map: Add Polyhood support

This actually implements polyhood support for the MAP.

This is not connected to the earlier commit which provides
database support for polyhoods. This patch will work
independent of the earlier one.

Although the KeyXchange does not provide polyhood data so far,
the Monitoring's implementation can already be put in place and
will take up the data as soon as it's there.

Note that since we only provide an additional layer for the
map, the overall footprint of this change is relatively small.

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>

Tested-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
This commit is contained in:
Adrian Schmutzler 2018-11-24 14:14:34 +01:00
parent 61e2e4600b
commit c5291413f1
8 changed files with 90 additions and 6 deletions

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map>
<Map background-color="transparent" srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
<Style name="hoodpoint">
<Rule>
<TextSymbolizer face-name="DejaVu Sans Book" size="12" fill="#b200b2" halo-radius="2">[name]</TextSymbolizer>
</Rule>
</Style>
<Style name="hoodborder">
<Rule>
<LineSymbolizer stroke-width="3" stroke="#b200b2" stroke-linecap="butt" stroke-dasharray="6, 2" clip="false" />
</Rule>
</Style>
<Layer name="borders" srs="+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>hoodborder</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="file">csv/hoods_poly.csv</Parameter>
</Datasource>
</Layer>
<Layer name="points" srs="+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>hoodpoint</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="file">csv/hood-points-poly.csv</Parameter>
</Datasource>
</Layer>
</Map>

View File

@ -5,5 +5,6 @@ liteserv.py routers_v2.xml -p 8003 --processes=5 &
liteserv.py routers_local.xml -p 8004 --processes=5 & liteserv.py routers_local.xml -p 8004 --processes=5 &
liteserv.py hoods.xml -p 8001 --processes=5 & liteserv.py hoods.xml -p 8001 --processes=5 &
liteserv.py hoods_v2.xml -p 8002 --processes=5 liteserv.py hoods_v2.xml -p 8002 --processes=5
liteserv.py hoods_poly.xml -p 8005 --processes=5
killall liteserv.py killall liteserv.py

View File

@ -53,6 +53,16 @@
}, },
"metatile": {"buffer": 128}, "metatile": {"buffer": 128},
"cache lifespan": 300 "cache lifespan": 300
},
"tiles/hoods_poly": {
"provider": {
"class": "dynmapnik:DynMapnik",
"kwargs": {
"mapfile": "/usr/share/ffmap/hoods_poly.xml"
}
},
"metatile": {"buffer": 128},
"cache lifespan": 300
} }
}, },
"logging": "info" "logging": "info"

View File

@ -10,6 +10,7 @@ from ffmap.config import CONFIG
import math import math
import numpy as np import numpy as np
from scipy.spatial import Voronoi from scipy.spatial import Voronoi
import urllib.request, urllib.error, json
EARTH_RADIUS = 6378137.0 EARTH_RADIUS = 6378137.0
@ -259,9 +260,43 @@ def update_mapnik_csv(mysql):
hoods.append([x, y]) hoods.append([x, y])
draw_voronoi_lines(csv, hoods) draw_voronoi_lines(csv, hoods)
# Poly-Hoods
with urllib.request.urlopen("http://keyserver.freifunk-franken.de/v2/hoods.php") as url:
dbhoodspoly = json.loads(url.read().decode())
with open(os.path.join(CONFIG["csv_dir"], "hood-points-poly.csv"), "w", encoding="UTF-8") as csv:
csv.write("lng,lat,name\n")
for hood in dbhoodspoly:
for polygon in hood.get("polygons",()):
avlon = 0
avlat = 0
for p in polygon:
avlon += p["lon"]
avlat += p["lat"]
avlon /= len(polygon)
avlat /= len(polygon)
csv.write("%f,%f,\"%s\"\n" % (
avlon,
avlat,
hood["name"]
))
with open(os.path.join(CONFIG["csv_dir"], "hoods_poly.csv"), "w") as csv:
csv.write("WKT\n")
for hood in dbhoodspoly:
for polygon in hood.get("polygons",()):
oldlon = None
oldlat = None
for p in polygon:
if oldlon and oldlat:
csv.write("\"LINESTRING (%f %f,%f %f)\"\n" % (oldlon, oldlat, p["lon"], p["lat"]))
oldlon = p["lon"]
oldlat = p["lat"]
csv.write("\"LINESTRING (%f %f,%f %f)\"\n" % (oldlon, oldlat, polygon[0]["lon"], polygon[0]["lat"]))
# touch mapnik XML files to trigger tilelite watcher # touch mapnik XML files to trigger tilelite watcher
touch("/usr/share/ffmap/hoods.xml") touch("/usr/share/ffmap/hoods.xml")
touch("/usr/share/ffmap/hoods_v2.xml") touch("/usr/share/ffmap/hoods_v2.xml")
touch("/usr/share/ffmap/hoods_poly.xml")
touch("/usr/share/ffmap/routers.xml") touch("/usr/share/ffmap/routers.xml")
touch("/usr/share/ffmap/routers_v2.xml") touch("/usr/share/ffmap/routers_v2.xml")
touch("/usr/share/ffmap/routers_local.xml") touch("/usr/share/ffmap/routers_local.xml")

View File

@ -32,6 +32,7 @@ tileurls = {
"routers_local": "/tiles/routers_local", "routers_local": "/tiles/routers_local",
"hoods": "/tiles/hoods", "hoods": "/tiles/hoods",
"hoods_v2": "/tiles/hoods_v2", "hoods_v2": "/tiles/hoods_v2",
"hoods_poly": "/tiles/hoods_poly"
} }
@app.route('/') @app.route('/')

View File

@ -31,6 +31,7 @@ var routers_v2 = new L.TileLayer(tileurls.routers_v2 + '/{z}/{x}/{y}.png', overl
var routers_local = new L.TileLayer(tileurls.routers_local + '/{z}/{x}/{y}.png', overlay_config); var routers_local = new L.TileLayer(tileurls.routers_local + '/{z}/{x}/{y}.png', overlay_config);
var hoods = new L.TileLayer(tileurls.hoods + '/{z}/{x}/{y}.png', overlay_config); var hoods = new L.TileLayer(tileurls.hoods + '/{z}/{x}/{y}.png', overlay_config);
var hoods_v2 = new L.TileLayer(tileurls.hoods_v2 + '/{z}/{x}/{y}.png', overlay_config); var hoods_v2 = new L.TileLayer(tileurls.hoods_v2 + '/{z}/{x}/{y}.png', overlay_config);
var hoods_poly = new L.TileLayer(tileurls.hoods_poly + '/{z}/{x}/{y}.png', overlay_config);
var popuplayer = new L.TileLayer(''); var popuplayer = new L.TileLayer('');
layersControl = new L.Control.Layers({ layersControl = new L.Control.Layers({
"openstreetmap.org": tilesosmorg, "openstreetmap.org": tilesosmorg,
@ -42,6 +43,7 @@ layersControl = new L.Control.Layers({
"Local Routers": routers_local, "Local Routers": routers_local,
"Hoods V1": hoods, "Hoods V1": hoods,
"Hoods V2": hoods_v2, "Hoods V2": hoods_v2,
"Poly-Hoods": hoods_poly,
"Position-Popup": popuplayer "Position-Popup": popuplayer
}); });
map.addControl(layersControl); map.addControl(layersControl);
@ -62,8 +64,14 @@ function update_permalink() {
var zoom = map.getZoom(); var zoom = map.getZoom();
window.history.replaceState({}, document.title, window.history.replaceState({}, document.title,
mapurl + '?mapcenter=' + pos.lat.toFixed(5) + ',' + pos.lng.toFixed(5) + ',' + zoom mapurl + '?mapcenter=' + pos.lat.toFixed(5) + ',' + pos.lng.toFixed(5) + ',' + zoom
+ '&layers=' + (map.hasLayer(routers)|0) + ',' + (map.hasLayer(routers_v2)|0) + ',' + (map.hasLayer(routers_local)|0) + ',' + '&layers=' + (map.hasLayer(routers)|0) + ','
+ (map.hasLayer(hoods)|0) + ',' + (map.hasLayer(hoods_v2)|0) + ',' + (map.hasLayer(popuplayer)|0) ); + (map.hasLayer(routers_v2)|0) + ','
+ (map.hasLayer(routers_local)|0) + ','
+ (map.hasLayer(hoods)|0) + ','
+ (map.hasLayer(hoods_v2)|0) + ','
+ (map.hasLayer(hoods_poly)|0) + ','
+ (map.hasLayer(popuplayer)|0)
);
} }
} }

View File

@ -43,7 +43,8 @@
if(getlayers[2]==1) { routers_local.addTo(map); } if(getlayers[2]==1) { routers_local.addTo(map); }
if(getlayers[3]==1) { hoods.addTo(map); } if(getlayers[3]==1) { hoods.addTo(map); }
if(getlayers[4]==1) { hoods_v2.addTo(map); } if(getlayers[4]==1) { hoods_v2.addTo(map); }
if(getlayers[5]==1) { popuplayer.addTo(map); } if(getlayers[5]==1) { hoods_poly.addTo(map); }
if(getlayers[6]==1) { popuplayer.addTo(map); }
} else { } else {
initialLayers(); initialLayers();
} }

View File

@ -5,9 +5,9 @@ mkdir -vp /var/lib/ffmap/csv
chown -R www-data:www-data /var/lib/ffmap chown -R www-data:www-data /var/lib/ffmap
mkdir -vp /usr/share/ffmap mkdir -vp /usr/share/ffmap
cp -v ffmap/mapnik/{hoods,hoods_v2,routers,routers_v2,routers_local}.xml /usr/share/ffmap cp -v ffmap/mapnik/{hoods,hoods_v2,hoods_poly,routers,routers_v2,routers_local}.xml /usr/share/ffmap
sed -i -e 's#>csv/#>/var/lib/ffmap/csv/#' /usr/share/ffmap/{hoods,hoods_v2,routers,routers_v2,routers_local}.xml sed -i -e 's#>csv/#>/var/lib/ffmap/csv/#' /usr/share/ffmap/{hoods,hoods_v2,hoods_poly,routers,routers_v2,routers_local}.xml
chown www-data:www-data /usr/share/ffmap/{hoods,hoods_v2,routers,routers_v2,routers_local}.xml chown www-data:www-data /usr/share/ffmap/{hoods,hoods_v2,hoods_poly,routers,routers_v2,routers_local}.xml
cp -v ffmap/mapnik/tilestache.cfg /usr/share/ffmap cp -v ffmap/mapnik/tilestache.cfg /usr/share/ffmap
cp -rv ffmap/web/static /usr/share/ffmap cp -rv ffmap/web/static /usr/share/ffmap