2020-04-19 09:12:17 +02:00
|
|
|
var editor_mode = 0;
|
2020-04-17 21:47:12 +02:00
|
|
|
var mymap;
|
2020-04-25 13:08:14 +02:00
|
|
|
|
|
|
|
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*/
|
|
|
|
|
2020-05-05 19:50:47 +02:00
|
|
|
var dijkstraserv_base = "https://notsyncing.net/dijkstra/";
|
2020-04-27 17:49:16 +02:00
|
|
|
var wikiurl_base = "https://wiki.linux-forks.de/mediawiki/index.php/"
|
2020-05-06 17:42:48 +02:00
|
|
|
var tiles_base = "https://notsyncing.net/maps.linux-forks.de/tiles/"
|
2020-04-27 17:49:16 +02:00
|
|
|
|
2020-04-17 16:43:34 +02:00
|
|
|
var streetLabelsRenderer = new L.StreetLabels({
|
|
|
|
collisionFlg: true,
|
|
|
|
propertyName: 'name',
|
|
|
|
showLabelIf: function (layer) {
|
2020-04-25 13:08:14 +02:00
|
|
|
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:
|
2020-04-20 18:39:48 +02:00
|
|
|
return false;
|
2020-04-25 13:08:14 +02:00
|
|
|
}
|
|
|
|
|
2020-04-20 18:39:48 +02:00
|
|
|
return true;
|
2020-04-17 16:43:34 +02:00
|
|
|
},
|
|
|
|
fontStyle: {
|
2020-04-20 17:57:49 +02:00
|
|
|
dynamicFontSize: true,
|
2020-04-20 18:39:48 +02:00
|
|
|
fontSize: 10,
|
2020-04-17 16:43:34 +02:00
|
|
|
fontSizeUnit: "px",
|
2020-04-20 18:39:48 +02:00
|
|
|
lineWidth: 3.0,
|
2020-04-17 16:43:34 +02:00
|
|
|
fillStyle: "black",
|
|
|
|
strokeStyle: "white",
|
|
|
|
},
|
|
|
|
});
|
2020-04-19 12:56:02 +02:00
|
|
|
|
2020-05-05 19:44:54 +02:00
|
|
|
streetLabelsRenderer._getCollisionFlag = function (layer) {
|
|
|
|
if (!(layer instanceof L.Polygon)) // Always check collision for streets
|
|
|
|
return true;
|
|
|
|
zoom = mymap.getZoom();
|
|
|
|
return (zoom < 5);
|
|
|
|
}
|
|
|
|
|
2020-04-25 13:08:14 +02:00
|
|
|
streetLabelsRenderer._getDynamicFontSize = function (layer) {
|
2020-04-20 17:57:49 +02:00
|
|
|
zoom = mymap.getZoom();
|
2020-04-25 13:08:14 +02:00
|
|
|
|
|
|
|
switch (layer.geometry.type) {
|
|
|
|
case "LineString":
|
|
|
|
if (zoom <= 8)
|
|
|
|
return 11;
|
|
|
|
else
|
|
|
|
return 2**(zoom - 9) * 11;
|
|
|
|
break;
|
|
|
|
case "Polygon":
|
2020-04-26 17:01:26 +02:00
|
|
|
var size;
|
2020-04-25 13:08:14 +02:00
|
|
|
if (zoom >= 4)
|
2020-04-26 17:01:26 +02:00
|
|
|
size = 30;
|
|
|
|
else
|
|
|
|
size = 20;
|
|
|
|
switch (layer.properties.type) {
|
|
|
|
case "city":
|
|
|
|
break;
|
|
|
|
case "town":
|
2020-04-26 18:48:18 +02:00
|
|
|
size *= 2.0/3.0;
|
2020-04-26 17:01:26 +02:00
|
|
|
break;
|
|
|
|
case "village":
|
2020-04-26 18:48:18 +02:00
|
|
|
size *= 1.5/3;
|
2020-04-26 17:01:26 +02:00
|
|
|
break;
|
|
|
|
case "district":
|
2020-04-26 18:48:18 +02:00
|
|
|
size *= 2.0/3;
|
2020-04-26 17:01:26 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
size *= 0.5/3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return size;
|
2020-04-25 13:08:14 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 10;
|
2020-04-20 17:57:49 +02:00
|
|
|
}
|
|
|
|
|
2020-04-25 13:08:14 +02:00
|
|
|
var style_outlines = {
|
|
|
|
radius: 8,
|
|
|
|
fillColor: "#ff7800",
|
|
|
|
color: "black",
|
2020-04-25 13:33:34 +02:00
|
|
|
opacity: 1.0,
|
2020-04-25 13:08:14 +02:00
|
|
|
fillOpacity: 0.5
|
|
|
|
};
|
|
|
|
|
2020-04-25 18:08:02 +02:00
|
|
|
var style_streets = {
|
|
|
|
};
|
|
|
|
|
2021-02-26 20:08:42 +01:00
|
|
|
var style_trains = {
|
|
|
|
color: "yellow"
|
|
|
|
};
|
|
|
|
|
|
|
|
var style_tech = {
|
|
|
|
color: "red"
|
|
|
|
};
|
|
|
|
|
2020-05-05 19:50:47 +02:00
|
|
|
var style_route = {
|
|
|
|
radius: 8,
|
|
|
|
fillColor: "#00ff00",
|
|
|
|
color: "red",
|
|
|
|
opacity: 1.0,
|
|
|
|
fillOpacity: 0.5
|
|
|
|
};
|
2020-04-20 17:57:49 +02:00
|
|
|
|
2020-04-15 01:08:31 +02:00
|
|
|
// Projection fix from: https://gis.stackexchange.com/questions/200865/leaflet-crs-simple-custom-scale
|
2020-04-17 16:14:57 +02:00
|
|
|
var factorx = 1 / 256 * 4;
|
2020-04-15 01:08:31 +02:00
|
|
|
var factory = factorx;
|
2020-04-19 07:38:41 +02:00
|
|
|
var originx = 7000 + 8 + 0.5;
|
|
|
|
var originy = 7000 + 8 - 0.5;
|
2020-04-15 01:08:31 +02:00
|
|
|
var zoom_level_real = 6;
|
|
|
|
|
|
|
|
L.CRS.pr = L.extend({}, L.CRS.Simple, {
|
2020-04-17 16:14:57 +02:00
|
|
|
projection: L.Projection.LonLat,
|
|
|
|
transformation: new L.Transformation(factorx,factorx * originx,-factory,factory * originy),
|
|
|
|
|
|
|
|
scale: function(zoom) {
|
|
|
|
return Math.pow(2, zoom);
|
|
|
|
},
|
|
|
|
|
|
|
|
zoom: function(scale) {
|
|
|
|
return Math.log(scale) / Math.LN2;
|
|
|
|
},
|
|
|
|
|
|
|
|
distance: function(latlng1, latlng2) {
|
|
|
|
var dx = latlng2.lng - latlng1.lng
|
|
|
|
, dy = latlng2.lat - latlng1.lat;
|
|
|
|
|
|
|
|
return Math.sqrt(dx * dx + dy * dy);
|
|
|
|
},
|
|
|
|
infinite: true
|
2020-04-15 01:08:31 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
// Init map
|
2020-04-17 21:47:12 +02:00
|
|
|
mymap = L.map('mapid', {
|
2020-04-17 16:43:34 +02:00
|
|
|
renderer: streetLabelsRenderer,
|
2020-04-17 21:47:12 +02:00
|
|
|
editable: true,
|
2020-04-17 16:14:57 +02:00
|
|
|
crs: L.CRS.pr
|
2020-04-25 13:08:14 +02:00
|
|
|
}).setView([0, 0], 5);
|
2020-04-15 01:08:31 +02:00
|
|
|
|
|
|
|
var mapheight = 16384;
|
|
|
|
var mapwidth = mapheight;
|
|
|
|
var sw = mymap.unproject([0, 0], zoom_level_real);
|
|
|
|
var ne = mymap.unproject([mapwidth, mapheight], zoom_level_real);
|
2020-04-17 16:14:57 +02:00
|
|
|
var layerbounds = new L.LatLngBounds(sw,ne);
|
2020-04-15 01:08:31 +02:00
|
|
|
|
|
|
|
var layers = L.control.layers({}, {}).addTo(mymap);
|
|
|
|
|
|
|
|
function load_svg(name, url, active=1) {
|
2020-04-17 16:14:57 +02:00
|
|
|
var xhttp_ps = new XMLHttpRequest();
|
|
|
|
xhttp_ps.onreadystatechange = function() {
|
|
|
|
if (this.readyState == 4) {
|
|
|
|
if (this.status == 200) {
|
|
|
|
var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
|
|
svgElement.setAttribute('xmlns', "http://www.w3.org/2000/svg");
|
|
|
|
svgElement.setAttribute('viewBox', "0 0 16384 16384");
|
|
|
|
svgElement.innerHTML = xhttp_ps.responseText;
|
|
|
|
var svgElementBounds = [[0, 0], [1000, 1000]];
|
|
|
|
var overlay = L.svgOverlay(svgElement, svgElementBounds);
|
|
|
|
layers.addOverlay(overlay, name);
|
|
|
|
if (active)
|
|
|
|
overlay.addTo(mymap);
|
|
|
|
return overlay;
|
|
|
|
} else {
|
|
|
|
alert("Error: Could not load SVG map layer (" + name + ")");
|
|
|
|
}
|
|
|
|
}
|
2020-04-15 01:08:31 +02:00
|
|
|
}
|
2020-04-17 16:14:57 +02:00
|
|
|
;
|
|
|
|
xhttp_ps.open("GET", url, true);
|
|
|
|
xhttp_ps.send();
|
2020-04-15 01:08:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function load_tiles(name, id) {
|
2020-05-06 17:42:48 +02:00
|
|
|
var url = "";
|
|
|
|
if (name != "") {
|
|
|
|
url = tiles_base + '{id}/{z}/{y}/{x}.png';
|
|
|
|
}
|
|
|
|
var satellite = L.tileLayer(url, {
|
2020-04-17 21:47:12 +02:00
|
|
|
maxZoom: 14 /*8*/,
|
2020-04-17 16:14:57 +02:00
|
|
|
maxNativeZoom: 6,
|
|
|
|
minNativeZoom: 0,
|
|
|
|
minZoom: 0,
|
|
|
|
noWrap: true,
|
2020-04-27 17:49:16 +02:00
|
|
|
attribution: 'Map data © <a href="' + wikiurl_base + 'Maps">Linux-Forks</a>',
|
2020-04-17 16:14:57 +02:00
|
|
|
id: id,
|
|
|
|
tileSize: 256,
|
|
|
|
zoomOffset: 0,
|
|
|
|
opacity: 1.0,
|
|
|
|
bounds: layerbounds
|
|
|
|
});
|
|
|
|
layers.addBaseLayer(satellite, name);
|
|
|
|
return satellite;
|
2020-04-15 01:08:31 +02:00
|
|
|
}
|
|
|
|
|
2020-04-25 13:08:14 +02:00
|
|
|
var current_location = "";
|
|
|
|
var current_feature = null;
|
2020-04-27 17:37:12 +02:00
|
|
|
function load_geojson(name, url, geotype, iconcolor, active=1, style={}) {
|
2020-04-17 16:14:57 +02:00
|
|
|
var xhttp_ps = new XMLHttpRequest();
|
|
|
|
xhttp_ps.onreadystatechange = function() {
|
|
|
|
if (this.readyState == 4) {
|
|
|
|
if (this.status == 200) {
|
2020-04-25 13:08:14 +02:00
|
|
|
onEachFeature = null;
|
|
|
|
pointToLayer = null;
|
|
|
|
filter = null;
|
|
|
|
|
2020-04-27 17:37:12 +02:00
|
|
|
switch (geotype) {
|
2020-04-17 16:43:34 +02:00
|
|
|
case "street":
|
2021-02-26 20:08:42 +01:00
|
|
|
case "train":
|
2020-04-25 13:08:14 +02:00
|
|
|
onEachFeature = function(feature, layer) {
|
2020-04-27 17:37:12 +02:00
|
|
|
layer.myTag = geotype;
|
2020-04-26 17:02:14 +02:00
|
|
|
layer.myName = name;
|
2021-02-26 20:08:42 +01:00
|
|
|
if (geotype == "train")
|
|
|
|
layer.no_search = true
|
2020-04-25 13:08:14 +02:00
|
|
|
layer.on("click", function (e) {
|
|
|
|
current_feature = feature;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case "outline":
|
|
|
|
onEachFeature = function(feature, layer) {
|
2020-04-27 17:37:12 +02:00
|
|
|
layer.myTag = geotype;
|
2020-04-25 13:08:14 +02:00
|
|
|
layer.myName = name;
|
|
|
|
layer.on("click", function (e) {
|
|
|
|
current_location = feature.properties.name;
|
|
|
|
});
|
|
|
|
}
|
2020-04-17 16:43:34 +02:00
|
|
|
break;
|
|
|
|
default: /* else it is a marker with the specified icon */
|
|
|
|
onEachFeature = function(feature, layer) {
|
|
|
|
label = String(feature.properties.name)
|
2020-04-27 17:49:16 +02:00
|
|
|
layer.bindPopup('<h1><a target="_blank" href="' + wikiurl_base + feature.properties.name + '">' + feature.properties.name + '</a> (' + feature.geometry.coordinates + ')</h1>' + '<p><img style="width:100%" src="' + feature.properties.image + '"></p>' + '<p>' + feature.properties.description + '</p>');
|
2020-04-17 16:43:34 +02:00
|
|
|
layer.bindTooltip(label, {
|
|
|
|
permanent: true,
|
|
|
|
direction: "center",
|
|
|
|
className: "city-names"
|
2020-04-19 09:12:37 +02:00
|
|
|
}).openTooltip().on('click', jump_to_marker);
|
2020-04-17 16:43:34 +02:00
|
|
|
};
|
|
|
|
pointToLayer = function(feature, latlng) {
|
|
|
|
label = String(feature.properties.name)
|
2020-04-27 17:37:12 +02:00
|
|
|
if (geotype == "auto") {
|
|
|
|
iconname = "star"; // default icon
|
|
|
|
iconcolor = "orange";
|
|
|
|
for (var i = 0; i < feature.properties.categories.length; i++) {
|
|
|
|
category = feature.properties.categories[i].toLowerCase();
|
|
|
|
switch (category) {
|
|
|
|
case "stations":
|
|
|
|
iconname = "train";
|
|
|
|
iconcolor = "blue";
|
|
|
|
break;
|
|
|
|
case "shops":
|
|
|
|
iconname = "shopping-cart";
|
|
|
|
iconcolor = "green";
|
|
|
|
break;
|
|
|
|
case "city":
|
|
|
|
case "village":
|
|
|
|
case "town":
|
|
|
|
case "settlements":
|
|
|
|
iconname = "city";
|
|
|
|
iconcolor = "red";
|
|
|
|
break;
|
|
|
|
case "parks":
|
|
|
|
iconname = "tree";
|
|
|
|
iconcolor = "green";
|
|
|
|
break;
|
|
|
|
case "courts":
|
|
|
|
iconname = "balance-scale";
|
|
|
|
iconcolor = "black";
|
|
|
|
break;
|
|
|
|
case "train depots":
|
|
|
|
iconname = "wrench";
|
|
|
|
iconcolor = "violet";
|
|
|
|
break;
|
|
|
|
case "hotels":
|
|
|
|
iconname = "hotel";
|
|
|
|
iconcolor = "gray";
|
|
|
|
break;
|
|
|
|
case "beaches":
|
|
|
|
iconname = "umbrella-beach";
|
|
|
|
iconcolor = "orange";
|
|
|
|
break;
|
2020-05-05 19:48:27 +02:00
|
|
|
case "waterway":
|
|
|
|
iconname = "water";
|
|
|
|
iconcolor = "blue";
|
|
|
|
break;
|
2020-04-27 17:37:12 +02:00
|
|
|
}
|
|
|
|
if (iconname != "star")
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
iconname = geotype;
|
|
|
|
}
|
|
|
|
marker = new L.marker(latlng,{
|
2020-04-17 16:43:34 +02:00
|
|
|
icon: L.AwesomeMarkers.icon({
|
|
|
|
icon: iconname,
|
|
|
|
markerColor: iconcolor
|
|
|
|
})
|
|
|
|
}).bindTooltip(label, {
|
|
|
|
permanent: false,
|
|
|
|
direction: "center",
|
|
|
|
opacity: 0.7
|
|
|
|
}).openTooltip();
|
2020-04-27 17:37:12 +02:00
|
|
|
return marker;
|
2020-04-17 16:43:34 +02:00
|
|
|
};
|
|
|
|
break;
|
|
|
|
}
|
2020-04-19 07:38:41 +02:00
|
|
|
var json = JSON.parse(xhttp_ps.responseText);
|
2020-04-25 13:08:14 +02:00
|
|
|
geojson = L.geoJSON(json, {
|
2020-04-17 16:43:34 +02:00
|
|
|
style: style,
|
|
|
|
onEachFeature: onEachFeature,
|
2020-04-25 13:08:14 +02:00
|
|
|
pointToLayer: pointToLayer,
|
|
|
|
filter: filter
|
2020-04-17 16:14:57 +02:00
|
|
|
});
|
|
|
|
layers.addOverlay(geojson, name);
|
2020-04-25 13:08:14 +02:00
|
|
|
|
2020-04-17 16:14:57 +02:00
|
|
|
if (active)
|
|
|
|
geojson.addTo(mymap);
|
|
|
|
return geojson;
|
|
|
|
} else {
|
2020-04-17 22:00:36 +02:00
|
|
|
console.log("Error: Could not load geojson map layer (" + name + ").");
|
2020-04-17 16:14:57 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-15 01:08:31 +02:00
|
|
|
}
|
2020-04-17 16:14:57 +02:00
|
|
|
;
|
|
|
|
xhttp_ps.open("GET", url, true);
|
|
|
|
xhttp_ps.send();
|
2020-04-15 01:08:31 +02:00
|
|
|
}
|
|
|
|
|
2020-04-17 16:14:57 +02:00
|
|
|
load_tiles("Satellite (2020-04-09)", 'world-2020-04-09').addTo(mymap);
|
2020-04-15 01:08:31 +02:00
|
|
|
load_tiles("Satellite (2019-05-04, wrong coords)", 'world-2019-05-04');
|
2020-05-06 17:42:48 +02:00
|
|
|
load_tiles("None", '');
|
2020-04-15 01:08:31 +02:00
|
|
|
|
2020-04-27 17:37:12 +02:00
|
|
|
load_geojson("All", "./geojson/all.json", "auto", "auto", 0);
|
|
|
|
load_geojson("Streets", "./geojson/streets.json", "street", "auto", 1, style_streets);
|
2021-02-26 20:09:14 +01:00
|
|
|
load_geojson("Trainlines (beta)", "./geojson/trainlines_beta.json", "train", "auto", 1, style_trains);
|
|
|
|
load_geojson("TL Access (tech layer)", "./geojson/trainlines_access_beta.json", "train", "auto", 0, style_tech);
|
|
|
|
load_geojson("Railroad Tracks", "./geojson/trains.json", "train", "auto", 0, style_trains);
|
2020-04-27 17:37:12 +02:00
|
|
|
load_geojson("Cities", "./geojson/city_outlines.json", "outline", "auto", 1, style_outlines);
|
2020-04-15 01:08:31 +02:00
|
|
|
|
|
|
|
L.control.scale().addTo(mymap);
|
|
|
|
|
2020-04-25 17:21:38 +02:00
|
|
|
function resolve_latlng(latlng, recenter = 0) {
|
|
|
|
latlng.lng = Math.round(latlng.lng);
|
|
|
|
latlng.lat = Math.round(latlng.lat);
|
|
|
|
return latlng;
|
|
|
|
}
|
|
|
|
|
2020-04-19 09:12:17 +02:00
|
|
|
function get_current_location_str() {
|
2020-04-25 17:21:38 +02:00
|
|
|
var latlng = resolve_latlng(mymap.getCenter());
|
|
|
|
return latlng.lng + "," + latlng.lat + "," + mymap.getZoom();
|
2020-04-19 09:12:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Important: Do not use mymap.setView, use this function instead */
|
|
|
|
function jump_to(latlng, zoom = -1) {
|
|
|
|
if (zoom == -1)
|
|
|
|
zoom = mymap.getZoom();
|
2020-04-25 17:21:38 +02:00
|
|
|
if (!editor_mode) {
|
|
|
|
pos = resolve_latlng(latlng);
|
|
|
|
document.location.hash = "#" + pos.lng + "," + pos.lat + "," + zoom;
|
|
|
|
} else {
|
2020-04-19 10:45:26 +02:00
|
|
|
mymap.setView(latlng, zoom);
|
2020-04-25 17:21:38 +02:00
|
|
|
}
|
2020-04-19 09:12:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function jump_to_marker(e) {
|
2020-04-19 10:45:26 +02:00
|
|
|
jump_to(e.target.getLatLng());
|
2020-04-19 09:12:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function prompt_location() {
|
|
|
|
var str = prompt("Enter coordinates to jump to:\n\n" +
|
|
|
|
"Format: x, y [, zoom]", get_current_location_str());
|
2020-04-19 17:00:01 +02:00
|
|
|
if (str) {
|
|
|
|
if (!editor_mode)
|
|
|
|
document.location.hash = "#" + str;
|
|
|
|
else
|
|
|
|
onHashChange(null, "#" + str);
|
|
|
|
}
|
2020-04-19 09:12:17 +02:00
|
|
|
}
|
|
|
|
|
2020-04-19 12:56:02 +02:00
|
|
|
var search_element;
|
2020-05-05 19:50:47 +02:00
|
|
|
var route_element;
|
|
|
|
function build_sidebar() {
|
2020-04-19 12:56:02 +02:00
|
|
|
if (!search_element) {
|
|
|
|
search_element = document.createElement("div");
|
|
|
|
search_element.style.overflow = "scroll";
|
|
|
|
search_element.style.padding = "6px";
|
|
|
|
search_element.style.height = "100%";
|
2020-05-05 19:50:47 +02:00
|
|
|
search_element.innerHTML = '<input style="width:100%;" id="search_query" name="lifo_map_search" type="search" placeholder="Start typing to search..." oninput="search(event)"><div id="search_results"></div>';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!route_element) {
|
|
|
|
route_element = document.createElement("div");
|
|
|
|
route_element.style.overflow = "scroll";
|
|
|
|
route_element.style.padding = "6px";
|
|
|
|
route_element.style.height = "100%";
|
2021-02-26 20:08:42 +01:00
|
|
|
route_element.innerHTML = '<a href="#" onclick="toggle_search(\'search\',1);return false;"><-- Return to search<br><br></a>\
|
|
|
|
<input style="width:100%;" id="route_start" name="lifo_route_loc" type="search" placeholder="Start at x,y"><br>\
|
|
|
|
<input style="width:100%;" id="route_destination" name="lifo_route_loc" type="search" placeholder="Go to x,y"><br>\
|
|
|
|
<input type="checkbox" name="use_trains" id="use_trains" value="trains" checked disabled=true><label for="use_trains"> Use trains (only S12)</label><br>\
|
|
|
|
<input id="route_submit" type="button" style="width:100%;" value="Go!" onclick="route(event)"><div id="route_results"></div>';
|
2020-05-05 19:50:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var current_sidebar = "search";
|
|
|
|
function toggle_search(type = current_sidebar, force_act = 0) {
|
|
|
|
if (el = document.getElementById('sidebar')) {
|
|
|
|
el.parentNode.removeChild(el);
|
|
|
|
if (force_act == 0 && type == current_sidebar)
|
|
|
|
return;
|
2020-04-19 12:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
td = document.getElementById('windowtr').insertCell(0);
|
|
|
|
td.style.width = "400px";
|
|
|
|
td.style.borderRight = "1px solid black";
|
|
|
|
td.style.verticalAlign = "top";
|
2020-05-05 19:50:47 +02:00
|
|
|
td.id = "sidebar";
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case "search":
|
|
|
|
td.appendChild(search_element);
|
|
|
|
document.getElementById('search_query').select();
|
|
|
|
break;
|
|
|
|
case "route":
|
|
|
|
td.appendChild(route_element);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
alert("JS error: sidebar");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
current_sidebar = type;
|
2020-04-19 12:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function htmlEntities(str) {
|
|
|
|
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
|
|
}
|
2020-04-19 23:09:26 +02:00
|
|
|
|
|
|
|
function polyline_get_middle_coords(coords) {
|
|
|
|
var ret = [2];
|
|
|
|
ret[0] = coords[0][0] + (coords[coords.length - 1][0] - coords[0][0]) / 2;
|
|
|
|
ret[1] = coords[0][1] + (coords[coords.length - 1][1] - coords[0][1]) / 2;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-04-19 23:28:54 +02:00
|
|
|
var highlighted_line;
|
|
|
|
var default_street_color = "#3388ff";
|
2020-04-27 17:37:12 +02:00
|
|
|
|
2020-04-19 12:56:02 +02:00
|
|
|
function search(e) {
|
2020-04-20 18:40:22 +02:00
|
|
|
var query = document.getElementById("search_query").value;
|
2020-04-27 17:37:12 +02:00
|
|
|
var real_query = true;
|
2020-04-19 20:21:13 +02:00
|
|
|
document.getElementById('search_results').innerHTML = "";
|
2020-04-25 17:34:33 +02:00
|
|
|
if (true) {
|
2020-04-27 17:37:12 +02:00
|
|
|
if (query.length == 0) {
|
|
|
|
real_query = false;
|
2020-04-25 17:34:33 +02:00
|
|
|
query = "!@#$%^&"; // Cheap workaround to (hopefully) match nothing
|
2020-04-27 17:37:12 +02:00
|
|
|
}
|
2020-04-19 12:56:02 +02:00
|
|
|
results = document.createElement("ul");
|
|
|
|
for (var i = 0; i < layers._layers.length; i++) {
|
|
|
|
if (!layers._layers[i].layer._layers)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (key in layers._layers[i].layer._layers) {
|
|
|
|
item = layers._layers[i].layer._layers[key];
|
2021-02-26 20:08:42 +01:00
|
|
|
if (item.hasOwnProperty("no_search"))
|
|
|
|
break;
|
2020-04-19 12:56:02 +02:00
|
|
|
switch (item.feature.geometry.type) {
|
|
|
|
case "Point":
|
|
|
|
regex = new RegExp(query, 'i');
|
|
|
|
if (item.feature.properties.name.match(regex)) {
|
|
|
|
el = document.createElement("li");
|
2020-04-20 18:40:22 +02:00
|
|
|
el.innerHTML = "[" + layers._layers[i].name + "] " + '<a href="#" onclick="layers._layers[' + i + '].layer._layers[' + item._leaflet_id + '].fire(\'click\'); return false;">' + htmlEntities(item.feature.properties.name) + "</a>";
|
2020-04-19 12:56:02 +02:00
|
|
|
results.appendChild(el);
|
2020-04-27 17:37:12 +02:00
|
|
|
item.setOpacity(1.0); // TODO: setOpacity does not disable hover and click events
|
|
|
|
} else {
|
|
|
|
if (real_query)
|
|
|
|
item.setOpacity(0.0); // TODO
|
|
|
|
else
|
|
|
|
item.setOpacity(1.0); // TODO
|
2020-04-19 12:56:02 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-19 23:09:26 +02:00
|
|
|
case "LineString":
|
2020-04-19 23:28:54 +02:00
|
|
|
if (item.options.color != default_street_color) { // De-hilight last search
|
|
|
|
item.options.color = default_street_color;
|
|
|
|
item.redraw();
|
|
|
|
}
|
2020-04-19 23:09:26 +02:00
|
|
|
regex = new RegExp(query, 'i');
|
2020-04-19 23:28:54 +02:00
|
|
|
|
2020-04-19 23:09:26 +02:00
|
|
|
if (item.feature.properties.name.match(regex)) {
|
2020-04-19 23:28:54 +02:00
|
|
|
item.options.color = "#FF0000";
|
|
|
|
item.redraw();
|
2020-04-19 23:09:26 +02:00
|
|
|
el = document.createElement("li");
|
|
|
|
zpos = polyline_get_middle_coords(item.feature.geometry.coordinates);
|
2020-04-20 18:40:22 +02:00
|
|
|
el.innerHTML = "[" + layers._layers[i].name + "] " + '<a href="#" onclick="latLng2 = L.latLng(' + zpos[1] + ',' + zpos[0] + '); jump_to(latLng2); return false;">' + htmlEntities(item.feature.properties.name) + "</a>";
|
2020-04-19 23:09:26 +02:00
|
|
|
results.appendChild(el);
|
|
|
|
}
|
|
|
|
break;
|
2020-04-25 13:33:13 +02:00
|
|
|
case "Polygon":
|
|
|
|
regex = new RegExp(query, 'i');
|
|
|
|
|
|
|
|
if (item.feature.properties.name.match(regex)) {
|
|
|
|
el = document.createElement("li");
|
2020-04-25 17:21:38 +02:00
|
|
|
zpos = resolve_latlng(layers._layers[i].layer._layers[item._leaflet_id].getCenter());
|
|
|
|
el.innerHTML = "[" + layers._layers[i].name + "] " + '<a href="#" onclick="latLng2 = L.latLng(' + zpos.lat + ',' + zpos.lng + '); jump_to(latLng2, ' + polyconf_show_cities + '); return false;">' + htmlEntities(item.feature.properties.name) + "</a>";
|
2020-04-25 13:33:13 +02:00
|
|
|
results.appendChild(el);
|
|
|
|
}
|
|
|
|
break;
|
2020-04-19 12:56:02 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
document.getElementById('search_results').appendChild(results);
|
|
|
|
}
|
2020-04-19 20:21:13 +02:00
|
|
|
return false;
|
2020-04-19 12:56:02 +02:00
|
|
|
}
|
|
|
|
|
2020-05-05 19:50:47 +02:00
|
|
|
var route_layer;
|
|
|
|
function route(e) // BOOKMARK
|
|
|
|
{
|
|
|
|
if (route_layer) {
|
|
|
|
mymap.removeLayer(route_layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
start = document.getElementById('route_start').value;
|
|
|
|
destination = document.getElementById('route_destination').value;
|
|
|
|
if ((start == "") || (destination == "")) {
|
|
|
|
document.getElementById('route_results').innerHTML = "";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
document.getElementById('route_submit').disabled = true;
|
|
|
|
document.getElementById('route_results').innerHTML = "Loading...";
|
|
|
|
|
|
|
|
var xhttp_ps = new XMLHttpRequest();
|
|
|
|
xhttp_ps.onreadystatechange = function() {
|
|
|
|
if (this.readyState == 4) {
|
|
|
|
if (this.status == 200) {
|
|
|
|
var json = JSON.parse(xhttp_ps.responseText);
|
|
|
|
geojson = L.geoJSON(json, {
|
|
|
|
style: style_route
|
|
|
|
});
|
|
|
|
route_layer = geojson.addTo(mymap);
|
|
|
|
|
|
|
|
str = "<ol>";
|
|
|
|
last_through = "";
|
|
|
|
geojson.eachLayer( function(layer) {
|
|
|
|
if (last_through != layer.feature.properties.through) {
|
2021-02-26 20:08:42 +01:00
|
|
|
str += '<li><a href="#" onclick="latLng2 = L.latLng(' + layer.feature.geometry.coordinates[0][1] + ',' + layer.feature.geometry.coordinates[0][0] + '); jump_to(latLng2); return false;">' + htmlEntities(layer.feature.properties.description).replace('[T]', '🚆️') + "</a></li>";
|
2020-05-05 19:50:47 +02:00
|
|
|
last_through = layer.feature.properties.through;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
str += "</ol>";
|
|
|
|
document.getElementById('route_results').innerHTML = str;
|
|
|
|
} else {
|
|
|
|
document.getElementById('route_results').innerHTML = "No results.";
|
|
|
|
}
|
|
|
|
document.getElementById('route_submit').disabled = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
coordstr = start + ';' + destination;
|
|
|
|
xhttp_ps.open("GET", dijkstraserv_base + coordstr, true);
|
|
|
|
xhttp_ps.send();
|
|
|
|
}
|
|
|
|
|
|
|
|
function set_route_start(latlng) {
|
|
|
|
toggle_search("route", 1);
|
|
|
|
document.getElementById('route_start').value = latlng.lat + ',' + latlng.lng;
|
|
|
|
route();
|
|
|
|
}
|
|
|
|
|
|
|
|
function set_route_destination(latlng) {
|
|
|
|
toggle_search("route", 1);
|
|
|
|
document.getElementById('route_destination').value = latlng.lat + ',' + latlng.lng;
|
|
|
|
route();
|
|
|
|
}
|
|
|
|
|
2020-04-19 09:12:17 +02:00
|
|
|
L.MyControl = L.Control.extend({
|
|
|
|
options: {
|
|
|
|
position: 'topleft',
|
|
|
|
callback: null,
|
|
|
|
kind: '',
|
|
|
|
html: ''
|
|
|
|
},
|
|
|
|
onAdd: function (map) {
|
|
|
|
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'),
|
|
|
|
link = L.DomUtil.create('a', '', container);
|
|
|
|
|
|
|
|
link.href = '#';
|
|
|
|
link.title = this.options.title;
|
|
|
|
link.innerHTML = this.options.html;
|
2020-05-08 17:18:10 +02:00
|
|
|
L.DomEvent.on(link, 'mousedown', L.DomEvent.stop);
|
|
|
|
L.DomEvent.on(link, 'mouseup', L.DomEvent.stop);
|
2020-04-19 09:12:17 +02:00
|
|
|
L.DomEvent.on(link, 'click', L.DomEvent.stop)
|
2020-06-11 10:54:14 +02:00
|
|
|
.on(link, 'click', function () {
|
|
|
|
window.LAYER = this.options.callback.call();
|
|
|
|
}, this);
|
|
|
|
return container;
|
2020-04-19 09:12:17 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-19 12:56:02 +02:00
|
|
|
L.SearchControl = L.MyControl.extend({
|
|
|
|
options: {
|
|
|
|
position: 'topleft',
|
|
|
|
callback: toggle_search,
|
|
|
|
title: 'Search',
|
|
|
|
html: '🔍'
|
|
|
|
}
|
|
|
|
});
|
2020-04-19 09:12:17 +02:00
|
|
|
L.GotoControl = L.MyControl.extend({
|
|
|
|
options: {
|
|
|
|
position: 'topleft',
|
|
|
|
callback: prompt_location,
|
2020-04-19 20:36:58 +02:00
|
|
|
title: 'Jump to coordinates',
|
2020-04-19 09:12:17 +02:00
|
|
|
html: '⌖'
|
|
|
|
}
|
|
|
|
});
|
2020-04-19 12:56:02 +02:00
|
|
|
mymap.addControl(new L.SearchControl());
|
2020-04-19 09:12:17 +02:00
|
|
|
mymap.addControl(new L.GotoControl());
|
|
|
|
|
2020-06-14 12:02:32 +02:00
|
|
|
L.CurrentPosControl = L.Control.extend({
|
|
|
|
options: {
|
|
|
|
position : 'bottomleft',
|
|
|
|
callback: null,
|
|
|
|
kind: "",
|
|
|
|
html: ''
|
|
|
|
},
|
|
|
|
onAdd: function (map) {
|
|
|
|
container = L.DomUtil.create('div', 'leaflet-control-scale leaflet-bar');
|
|
|
|
container.style.visibility = "hidden";
|
|
|
|
div = L.DomUtil.create('div', '', container);
|
|
|
|
div.style.backgroundColor = "white";
|
|
|
|
div.style.paddingLeft = "4px";
|
|
|
|
div.style.paddingRight = "4px";
|
|
|
|
div.style.borderRadius = "2px";
|
|
|
|
div.style.margin = "2px";
|
|
|
|
div.style.opacity = "0.6";
|
|
|
|
div.style.fontWeight = "bold";
|
|
|
|
div.innerHTML = "";
|
|
|
|
div.id = "current_position_label";
|
|
|
|
return container;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
mymap.addControl(new L.CurrentPosControl());
|
|
|
|
|
2020-04-15 01:08:31 +02:00
|
|
|
var popup = L.popup();
|
|
|
|
|
|
|
|
L.AwesomeMarkers.Icon.prototype.options.prefix = 'fa';
|
|
|
|
var baseballIcon = L.AwesomeMarkers.icon({
|
2020-04-17 16:14:57 +02:00
|
|
|
icon: 'coffee',
|
|
|
|
markerColor: 'red'
|
2020-04-15 01:08:31 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
function onMapClick(e) {
|
2020-04-25 13:08:14 +02:00
|
|
|
var addinfo = "";
|
2020-05-05 19:50:47 +02:00
|
|
|
pos = resolve_latlng(e.latlng);
|
|
|
|
route_links = '<br><a href="#" onclick="latLng2 = L.latLng(' + pos.lng + ',' + pos.lat + '); set_route_start(latLng2); return false;">[route from here]</a>';
|
|
|
|
route_links += ' <a href="#" onclick="latLng2 = L.latLng(' + pos.lng + ',' + pos.lat + '); set_route_destination(latLng2); return false;">[route to here]</a>';
|
2020-04-25 13:08:14 +02:00
|
|
|
if (current_location != "")
|
2020-04-27 17:49:16 +02:00
|
|
|
addinfo = " (part of <a target=\"_blank\" href='" + wikiurl_base + current_location + "'>" + current_location + "</a>)";
|
2020-04-25 13:08:14 +02:00
|
|
|
if (current_feature) {
|
2020-05-05 19:50:47 +02:00
|
|
|
popup.setLatLng(e.latlng).setContent("This is " + current_feature.properties.name + addinfo + route_links).openOn(mymap);
|
2020-04-25 13:08:14 +02:00
|
|
|
} else {
|
2020-05-05 19:50:47 +02:00
|
|
|
popup.setLatLng(e.latlng).setContent("You clicked the map at " + pos.lng + "," + pos.lat + addinfo + route_links).openOn(mymap);
|
2020-04-25 13:08:14 +02:00
|
|
|
}
|
|
|
|
current_feature = null;
|
|
|
|
current_location = "";
|
2020-04-15 01:08:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mymap.on('click', onMapClick);
|
2020-04-19 09:12:17 +02:00
|
|
|
|
2020-04-19 10:45:26 +02:00
|
|
|
var is_user_drag = 0;
|
|
|
|
|
2020-04-19 09:12:17 +02:00
|
|
|
function update_hash_from_position(e) {
|
2020-04-19 10:45:26 +02:00
|
|
|
if (is_user_drag)
|
|
|
|
is_user_drag = 0;
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
if (!editor_mode)
|
|
|
|
document.location.hash = "#" + get_current_location_str();
|
2020-04-19 09:12:17 +02:00
|
|
|
}
|
2020-04-19 10:45:26 +02:00
|
|
|
|
|
|
|
function dragstart(e) {
|
|
|
|
is_user_drag = 1;
|
|
|
|
}
|
|
|
|
|
2020-04-20 00:02:28 +02:00
|
|
|
function update_aa_status() {
|
|
|
|
if (mymap.getZoom() > zoom_level_real)
|
|
|
|
document.getElementById('mapid').classList.add("no-aa");
|
|
|
|
else
|
|
|
|
document.getElementById('mapid').classList.remove("no-aa");
|
|
|
|
}
|
|
|
|
|
2020-04-20 18:39:48 +02:00
|
|
|
function update_street_width() {
|
|
|
|
zoom = mymap.getZoom();
|
|
|
|
var w;
|
|
|
|
if (zoom <= 6) {
|
|
|
|
w = 2;
|
|
|
|
} else {
|
|
|
|
w = 2**zoom * 0.016 * 2;
|
|
|
|
}
|
|
|
|
var myStyle = {weight: w, opacity: 0.7};
|
2020-04-26 17:02:14 +02:00
|
|
|
mymap.eachLayer( function(layer) {
|
|
|
|
if ( layer.myTag && layer.myTag === "street") {
|
|
|
|
layer.setStyle(myStyle);
|
|
|
|
}
|
|
|
|
});
|
2020-04-20 18:39:48 +02:00
|
|
|
}
|
|
|
|
|
2020-04-25 13:08:14 +02:00
|
|
|
function update_outline_visibility() {
|
|
|
|
zoom = mymap.getZoom();
|
|
|
|
mymap.eachLayer( function(layer) {
|
|
|
|
if ( layer.myTag && layer.myTag === "outline") {
|
2020-04-25 13:33:34 +02:00
|
|
|
var fillOpacity;
|
2020-04-25 13:08:14 +02:00
|
|
|
if (zoom <= polyconf_show_cities)
|
2020-04-25 13:33:34 +02:00
|
|
|
fillOpacity = 0.5;
|
2020-04-25 13:08:14 +02:00
|
|
|
//else if (zoom == polyconf_show_cities + 1)
|
|
|
|
// opacity = 0.2;
|
|
|
|
else
|
2020-04-25 13:33:34 +02:00
|
|
|
fillOpacity = 0.0;
|
2020-04-25 13:08:14 +02:00
|
|
|
|
2020-04-25 13:33:34 +02:00
|
|
|
layer.setStyle({fillOpacity: fillOpacity});
|
2020-04-25 13:08:14 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-14 12:02:32 +02:00
|
|
|
function update_current_mouse_position(e) {
|
|
|
|
var lbl = document.getElementById('current_position_label');
|
|
|
|
if (e.type == "mouseout") {
|
|
|
|
lbl.parentElement.style.visibility = "hidden";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
lbl.parentElement.style.visibility = "visible";
|
|
|
|
pos = resolve_latlng(e.latlng);
|
|
|
|
lbl.innerHTML = pos.lng + "," + pos.lat;
|
|
|
|
}
|
|
|
|
|
2020-04-19 10:45:26 +02:00
|
|
|
mymap.on('zoomend', function () {is_user_drag = 1; update_hash_from_position();});
|
2020-04-20 00:02:28 +02:00
|
|
|
mymap.on('zoomend', update_aa_status);
|
2020-04-20 18:39:48 +02:00
|
|
|
mymap.on('zoomend', update_street_width);
|
2020-04-25 13:08:14 +02:00
|
|
|
mymap.on('zoomend', update_outline_visibility);
|
2020-04-19 10:45:26 +02:00
|
|
|
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;});
|
2020-04-25 13:08:14 +02:00
|
|
|
mymap.on('overlayadd', function (e) { update_street_width(); update_outline_visibility(); });
|
2020-06-14 12:02:32 +02:00
|
|
|
mymap.on('mousemove', update_current_mouse_position);
|
|
|
|
mymap.on('mouseout', update_current_mouse_position);
|
2020-04-26 17:55:32 +02:00
|
|
|
|
2020-04-19 17:00:01 +02:00
|
|
|
function onHashChange(e, hash=null) {
|
|
|
|
if (!hash)
|
|
|
|
hash = document.location.hash;
|
2020-04-27 17:37:12 +02:00
|
|
|
if (hash == "")
|
|
|
|
return;
|
2020-04-19 17:00:01 +02:00
|
|
|
if (hash == "#" + get_current_location_str())
|
2020-04-19 09:12:17 +02:00
|
|
|
return; // We're already there
|
2020-04-26 17:55:32 +02:00
|
|
|
coordstr = decodeURIComponent(hash.slice(1)).split(",");
|
2020-04-19 09:12:17 +02:00
|
|
|
if (coordstr.length < 2)
|
|
|
|
coordstr.push(0); // Default y
|
|
|
|
if (coordstr.length < 3)
|
|
|
|
coordstr.push(mymap.getZoom()); // Default zoom
|
2020-04-19 17:07:07 +02:00
|
|
|
var latlng = L.latLng(parseFloat(coordstr[1]), parseFloat(coordstr[0]));
|
2020-04-19 09:12:17 +02:00
|
|
|
mymap.setView(latlng, parseInt(coordstr[2]));
|
2020-04-26 17:55:32 +02:00
|
|
|
if (coordstr.length > 3) { /* Drop named marker */
|
|
|
|
foo = L.marker(latlng).bindPopup(htmlEntities(coordstr[3])).addTo(mymap).openPopup();
|
|
|
|
}
|
2020-04-19 09:12:17 +02:00
|
|
|
}
|
2020-04-19 12:56:02 +02:00
|
|
|
|
2020-05-05 19:50:47 +02:00
|
|
|
build_sidebar();
|
|
|
|
|
2020-04-19 09:12:17 +02:00
|
|
|
window.addEventListener("hashchange", onHashChange, false);
|
|
|
|
onHashChange(null);
|