From 771704bf15515ac524724c20399a0b44ccc44531 Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Sat, 25 Apr 2020 13:08:14 +0200 Subject: [PATCH] Add basic support for city outlines Use with load_geojson( "Cities (outline, demo)", "./geojson/cities_demo.json", "outline", "black", 1, style_outlines); --- htdocs/leafletjs/Leaflet.streetlabels.js | 7 +- htdocs/mapscript.js | 113 +++++++++++++++++++---- 2 files changed, 99 insertions(+), 21 deletions(-) diff --git a/htdocs/leafletjs/Leaflet.streetlabels.js b/htdocs/leafletjs/Leaflet.streetlabels.js index 91bd596..8aee67b 100644 --- a/htdocs/leafletjs/Leaflet.streetlabels.js +++ b/htdocs/leafletjs/Leaflet.streetlabels.js @@ -80,10 +80,8 @@ L.StreetLabels = L.LabelTextCollision ctx.lineWidth = this.options.fontStyle.lineWidth; var fontSize = this.options.fontStyle.fontSize; - if (this._map && this.options.fontStyle.dynamicFontSize === true) { - fontSize = this._getDynamicFontSize(); - + fontSize = this._getDynamicFontSize(layer.feature); } ctx.font = fontSize + this.options.fontStyle.fontSizeUnit + " 'Helvetica Neue',Helvetica,Arial,sans-serif"; @@ -98,7 +96,6 @@ L.StreetLabels = L.LabelTextCollision textWidth, textHeight)); if (this.options.collisionFlg) { - for (var index in this._textList) { var pointBounds = this._textList[index]; if (pointBounds.intersects(bounds)) { @@ -184,7 +181,7 @@ L.StreetLabels = L.LabelTextCollision return polyline; }, - _getDynamicFontSize: function () { + _getDynamicFontSize: function (layer) { return parseInt(this._map.getZoom()); }, diff --git a/htdocs/mapscript.js b/htdocs/mapscript.js index 8aab466..c70006f 100644 --- a/htdocs/mapscript.js +++ b/htdocs/mapscript.js @@ -1,13 +1,27 @@ var editor_mode = 0; var mymap; + +var polyconf_show_street_names = 5; // Zoom level for when to start showing street names +var polyconf_show_cities = 5; /* City outlines will be filled on this level and further away */ +var polyconf_show_districts = 4; /* Shown from polyconf_show_cities until this*/ + var streetLabelsRenderer = new L.StreetLabels({ collisionFlg: true, propertyName: 'name', showLabelIf: function (layer) { - if (!(layer.geometry.type == "LineString"|| layer.geometry.type == "Polygon")) - return false; - if (mymap.getZoom() <= 5) + switch (layer.geometry.type) { + case "LineString": + if (mymap.getZoom() <= polyconf_show_street_names) + return false; + break; + case "Polygon": + if (mymap.getZoom() > polyconf_show_street_names) + return false; + break; + default: return false; + } + return true; }, fontStyle: { @@ -20,14 +34,34 @@ var streetLabelsRenderer = new L.StreetLabels({ }, }); -streetLabelsRenderer._getDynamicFontSize = function () { +streetLabelsRenderer._getDynamicFontSize = function (layer) { zoom = mymap.getZoom(); - if (zoom <= 8) - return 11; - else - return 2**(zoom - 9) * 11; + + switch (layer.geometry.type) { + case "LineString": + if (zoom <= 8) + return 11; + else + return 2**(zoom - 9) * 11; + break; + case "Polygon": + if (zoom >= 4) + return 30; + return 20; + default: + break; + } + return 10; } +var style_outlines = { + radius: 8, + fillColor: "#ff7800", + color: "black", + opacity: 1, + fillOpacity: 0.5 + }; + // Projection fix from: https://gis.stackexchange.com/questions/200865/leaflet-crs-simple-custom-scale var factorx = 1 / 256 * 4; @@ -62,7 +96,7 @@ mymap = L.map('mapid', { renderer: streetLabelsRenderer, editable: true, crs: L.CRS.pr -}).setView([0, 0], 6); +}).setView([0, 0], 5); var mapheight = 16384; var mapwidth = mapheight; @@ -115,15 +149,34 @@ function load_tiles(name, id) { return satellite; } +var current_location = ""; +var current_feature = null; + function load_geojson(name, url, iconname, iconcolor, active=1, style={}) { var xhttp_ps = new XMLHttpRequest(); xhttp_ps.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200) { + onEachFeature = null; + pointToLayer = null; + filter = null; + switch (iconname) { case "street": - onEachFeature = null; - pointToLayer = null; + onEachFeature = function(feature, layer) { + layer.on("click", function (e) { + current_feature = feature; + }); + }; + break; + case "outline": + onEachFeature = function(feature, layer) { + layer.myTag = iconname; + layer.myName = name; + layer.on("click", function (e) { + current_location = feature.properties.name; + }); + } break; default: /* else it is a marker with the specified icon */ onEachFeature = function(feature, layer) { @@ -151,12 +204,14 @@ function load_geojson(name, url, iconname, iconcolor, active=1, style={}) { break; } var json = JSON.parse(xhttp_ps.responseText); - var geojson = L.geoJSON(json, { + geojson = L.geoJSON(json, { style: style, onEachFeature: onEachFeature, - pointToLayer: pointToLayer + pointToLayer: pointToLayer, + filter: filter }); layers.addOverlay(geojson, name); + if (active) geojson.addTo(mymap); return geojson; @@ -351,7 +406,16 @@ var baseballIcon = L.AwesomeMarkers.icon({ }); function onMapClick(e) { - popup.setLatLng(e.latlng).setContent("You clicked the map at " + e.latlng.toString()).openOn(mymap); + var addinfo = ""; + if (current_location != "") + addinfo = " (part of " + current_location + ")"; + if (current_feature) { + popup.setLatLng(e.latlng).setContent("This is " + current_feature.properties.name + addinfo).openOn(mymap); + } else { + popup.setLatLng(e.latlng).setContent("You clicked the map at " + e.latlng.toString() + addinfo).openOn(mymap); + } + current_feature = null; + current_location = ""; } mymap.on('click', onMapClick); @@ -394,13 +458,31 @@ function update_street_width() { } } +function update_outline_visibility() { + zoom = mymap.getZoom(); + mymap.eachLayer( function(layer) { + if ( layer.myTag && layer.myTag === "outline") { + var opacity; + if (zoom <= polyconf_show_cities) + opacity = 0.5; + //else if (zoom == polyconf_show_cities + 1) + // opacity = 0.2; + else + opacity = 0.0; + + layer.setStyle({fillOpacity: opacity}); + } + }); +} + mymap.on('zoomend', function () {is_user_drag = 1; update_hash_from_position();}); mymap.on('zoomend', update_aa_status); mymap.on('zoomend', update_street_width); +mymap.on('zoomend', update_outline_visibility); mymap.on('moveend', update_hash_from_position); mymap.on('dragstart', function () { is_user_drag = 1;}); mymap.on('keydown', function (e) { if (e.originalEvent.code.match(/Arrow.*/)) is_user_drag = 1;}); - +mymap.on('overlayadd', function (e) { update_street_width(); update_outline_visibility(); }); function onHashChange(e, hash=null) { if (!hash) hash = document.location.hash; @@ -417,4 +499,3 @@ function onHashChange(e, hash=null) { window.addEventListener("hashchange", onHashChange, false); onHashChange(null); -update_street_width();