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 polyconf_show_oceans = 5; // Show ocean labels from zoom level var dijkstraserv_base = "https://notsyncing.net/dijkstra/"; var wikiurl_base = "https://wiki.linux-forks.de/mediawiki/index.php/" var tiles_base = "https://notsyncing.net/maps.linux-forks.de/tiles/" var streetLabelsRenderer = new L.StreetLabels({ collisionFlg: true, propertyName: 'name', showLabelIf: function (layer) { switch (layer.feature.geometry.type) { case "LineString": if (mymap.getZoom() <= polyconf_show_street_names) return false; break; case "Polygon": if (layer.myName == "Oceans") return (mymap.getZoom() > polyconf_show_oceans); if (mymap.getZoom() > polyconf_show_street_names) return false; break; default: return false; } return true; }, fontStyle: { dynamicFontSize: true, fontSize: 10, fontSizeUnit: "px", lineWidth: 3.0, fillStyle: "black", strokeStyle: "white" }, }); streetLabelsRenderer._getCollisionFlag = function (layer) { if (!(layer instanceof L.Polygon)) // Always check collision for streets return true; zoom = mymap.getZoom(); return (zoom < 5); } streetLabelsRenderer._getDynamicFontSize = function (layer) { zoom = mymap.getZoom(); switch (layer.myName) { case "Oceans": return size *= 2.0/3;; break; default: switch (layer.feature.geometry.type) { case "LineString": if (zoom <= 8) return 11; else return 2**(zoom - 9) * 11; break; case "Polygon": var size; if (zoom >= 4) size = 30; else size = 20; switch (layer.feature.properties.type) { case "city": break; case "town": size *= 2.0/3.0; break; case "village": size *= 1.5/3; break; case "district": size *= 2.0/3; break; default: size *= 0.5/3; break; } return size; default: break; } } return 10; } var style_outlines = { radius: 8, fillColor: "#ff7800", color: "black", opacity: 1.0, fillOpacity: 0.5 }; var style_streets = { }; var style_trains = { color: "yellow" }; var style_tech = { color: "red" }; var style_rivers = { color: "blue", fillColor: "#00999955", }; var style_oceans = { color: "#00556655", fillColor: "#00999955", }; var style_route = { radius: 8, fillColor: "#00ff00", color: "red", opacity: 1.0, fillOpacity: 0.5 }; // Projection fix from: https://gis.stackexchange.com/questions/200865/leaflet-crs-simple-custom-scale var factorx = 1 / 256 * 4; var factory = factorx; var originx = 7000 + 8 + 0.5; var originy = 7000 + 8 - 0.5; var zoom_level_real = 6; L.CRS.pr = L.extend({}, L.CRS.Simple, { 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 }); // Init map mymap = L.map('mapid', { renderer: streetLabelsRenderer, editable: true, crs: L.CRS.pr }).setView([0, 0], 5); var mapheight = 16384; var mapwidth = mapheight; var sw = mymap.unproject([0, 0], zoom_level_real); var ne = mymap.unproject([mapwidth, mapheight], zoom_level_real); var layerbounds = new L.LatLngBounds(sw,ne); var layers = L.control.layers({}, {}).addTo(mymap); function load_svg(name, url, active=1) { 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 + ")"); } } } ; xhttp_ps.open("GET", url, true); xhttp_ps.send(); } function load_tiles(name, id) { var url = ""; if (name != "") { url = tiles_base + '{id}/{z}/{y}/{x}.png'; } var satellite = new L.TileLayer(url, { maxZoom: 14 /*8*/, maxNativeZoom: 6, minNativeZoom: 0, minZoom: 0, noWrap: true, attribution: 'Map data © Linux-Forks', id: id, tileSize: 256, zoomOffset: 0, opacity: 1.0, bounds: layerbounds }); layers.addBaseLayer(satellite, name); return satellite; } var current_location = ""; var current_feature = null; var current_layer = null; function load_geojson(name, url, geotype, 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 (geotype) { case "street": case "train": onEachFeature = function(feature, layer) { layer.myTag = geotype; layer.myName = name; if (geotype == "train") layer.no_search = true layer.on("click", function (e) { current_layer = layer; current_feature = feature; }); }; break; case "outline": onEachFeature = function(feature, layer) { layer.myTag = geotype; 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) { layer.myName = name; label = String(feature.properties.name) layer.bindPopup('
' + feature.properties.description + '
'); layer.bindTooltip(label, { permanent: true, direction: "center", className: "city-names" }).openTooltip().on('click', jump_to_marker); }; pointToLayer = function(feature, latlng) { label = String(feature.properties.name) 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; case "waterway": iconname = "water"; iconcolor = "blue"; break; } if (iconname != "star") break; } } else { iconname = geotype; } marker = new L.marker(latlng,{ icon: L.AwesomeMarkers.icon({ icon: iconname, markerColor: iconcolor }) }).bindTooltip(label, { permanent: false, direction: "center", opacity: 0.7 }).openTooltip(); return marker; }; break; } var json = JSON.parse(xhttp_ps.responseText); geojson = L.geoJSON(json, { style: style, onEachFeature: onEachFeature, pointToLayer: pointToLayer, filter: filter }); layers.addOverlay(geojson, name); if (active) geojson.addTo(mymap); return geojson; } else { console.log("Error: Could not load geojson map layer (" + name + ")."); } } } ; xhttp_ps.open("GET", url, true); xhttp_ps.send(); } load_tiles("Satellite (2025-02-01)", "world-2025-02-01").addTo(mymap); load_tiles("Satellite (2025-01-01)", "world-2025-01-01"); load_tiles("Satellite (2024-12-01)", "world-2024-12-01"); load_tiles("Satellite (2024-11-01)", "world-2024-11-01"); load_tiles("Satellite (2024-10-01)", "world-2024-10-01"); load_tiles("Satellite (2024-09-01)", "world-2024-09-01"); load_tiles("Satellite (2024-08-01)", "world-2024-08-01"); load_tiles("Satellite (2023-09-15)", "world-2023-09-15"); load_tiles("Satellite (2023-04-12)", "world-2023-04-12"); load_tiles("Satellite (2023-03-16)", "world-2023-03-16"); load_tiles("Satellite (2022-05-15)", "world-2022-05-15"); load_tiles("Satellite (2022-02-05)", "world-2022-02-05"); load_tiles("Satellite (2021-12-09)", "world-2021-12-09"); load_tiles("Satellite (2021-10-01)", "world-2021-10-01"); load_tiles("Satellite (2021-08-03)", "world-2021-08-03"); load_tiles("Satellite (2021-07-20)", "world-2021-07-20"); load_tiles("Satellite (2021-07-01)", "world-2021-07-01"); load_tiles("Satellite (2021-06-13)", "world-2021-06-13"); load_tiles("Satellite (2021-05-02)", "world-2021-05-02"); load_tiles("Satellite (2021-04-18)", "world-2021-04-18"); load_tiles("Satellite (2021-04-07)", "world-2021-04-07"); load_tiles("Satellite (2021-03-06)", "world-2021-03-06"); load_tiles("Satellite (2021-02-20)", "world-2021-02-20"); load_tiles("Satellite (2021-01-20)", "world-2021-01-20"); load_tiles("Satellite (2020-12-13)", "world-2020-12-13"); load_tiles("Satellite (2020-11-20)", "world-2020-11-20"); load_tiles("Satellite (2020-11-06)", "world-2020-11-06"); load_tiles("Satellite (2020-10-16)", "world-2020-10-16"); load_tiles("Satellite (2020-10-03)", "world-2020-10-03"); load_tiles("Satellite (2020-09-24)", "world-2020-09-24"); load_tiles("Satellite (2020-09-11)", "world-2020-09-11"); load_tiles("Satellite (2020-08-30)", "world-2020-08-30"); load_tiles("Satellite (2020-08-19)", "world-2020-08-19"); load_tiles("Satellite (2020-08-09)", "world-2020-08-09"); load_tiles("Satellite (2020-07-22)", "world-2020-07-22"); load_tiles("Satellite (2020-06-24)", "world-2020-06-24"); load_tiles("Satellite (2020-06-04)", "world-2020-06-04"); load_tiles("Satellite (2020-05-07)", "world-2020-05-07"); load_tiles("Satellite (2020-04-26)", "world-2020-04-26"); load_tiles("Satellite (2020-04-09)", "world-2020-04-09"); load_tiles("Satellite (2020-04-03)", "world-2020-04-03"); load_tiles("Satellite (2020-03-19)", "world-2020-03-19"); load_tiles("Satellite (2020-03-14)", "world-2020-03-14"); load_tiles("Satellite (2020-03-06)", "world-2020-03-06"); load_tiles("Satellite (2020-02-27)", "world-2020-02-27"); load_tiles("Satellite (2020-02-15)", "world-2020-02-15"); load_tiles("Satellite (2020-02-07)", "world-2020-02-07"); load_tiles("Satellite (2020-01-30)", "world-2020-01-30"); load_tiles("Satellite (2020-01-18)", "world-2020-01-18"); load_tiles("Satellite (2019-12-22)", "world-2019-12-22"); load_tiles("Satellite (2019-12-16)", "world-2019-12-16"); load_tiles("Satellite (2019-12-02)", "world-2019-12-02"); load_tiles("Satellite (2019-11-12)", "world-2019-11-12"); load_tiles("Satellite (2019-11-02)", "world-2019-11-02"); load_tiles("Satellite (2019-10-21)", "world-2019-10-21"); load_tiles("Satellite (2019-09-20)", "world-2019-09-20"); load_tiles("Satellite (2019-09-02)", "world-2019-09-02"); load_tiles("Satellite (2019-08-17)", "world-2019-08-17"); load_tiles("Satellite (2019-07-31)", "world-2019-07-31"); load_tiles("Satellite (2019-07-09)", "world-2019-07-09"); load_tiles("Satellite (2019-07-01)", "world-2019-07-01"); load_tiles("Satellite (2019-06-22)", "world-2019-06-22"); load_tiles("Satellite (2019-06-20)", "world-2019-06-20"); load_tiles("Satellite (2019-06-19)", "world-2019-06-19"); load_tiles("Satellite (2019-06-08)", "world-2019-06-08"); load_tiles("Satellite (2019-05-30)", "world-2019-05-30"); load_tiles("Satellite (2019-05-26)", "world-2019-05-26"); load_tiles("Satellite (2019-05-20)", "world-2019-05-20"); load_tiles("Satellite (2019-05-14)", "world-2019-05-14"); load_tiles("Satellite (2019-05-12)", "world-2019-05-12"); load_tiles("Satellite (2019-05-04)", "world-2019-05-04"); load_tiles("Satellite (2019-01-28)", "world-2019-01-28"); load_tiles("Satellite (2019-01-21)", "world-2019-01-21"); load_tiles("Satellite (2019-01-14)", "world-2019-01-14"); load_tiles("Satellite (2019-01-07)", "world-2019-01-07"); load_tiles("Satellite (2018-12-31)", "world-2018-12-31"); load_tiles("Satellite (2018-12-10)", "world-2018-12-10"); load_tiles("Satellite (2018-10-04)", "world-2018-10-04"); load_tiles("Satellite (2018-08-22)", "world-2018-08-22"); load_tiles("Satellite (2018-07-25)", "world-2018-07-25"); load_tiles("Satellite (2018-07-06)", "world-2018-07-06"); load_tiles("Satellite (2018-06-20)", "world-2018-06-20"); load_tiles("Satellite (2018-05-14)", "world-2018-05-14"); load_tiles("Satellite (2018-04-28)", "world-2018-04-28"); load_tiles("Satellite (2018-03-30)", "world-2018-03-30"); load_tiles("Satellite (2018-02-24)", "world-2018-02-24"); load_tiles("Satellite (2018-01-25)", "world-2018-01-25"); load_tiles("Satellite (2018-01-11)", "world-2018-01-11"); load_tiles("Satellite (2017-12-27)", "world-2017-12-27"); load_tiles("Satellite (2017-12-24)", "world-2017-12-24"); load_tiles("Satellite (2017-12-14)", "world-2017-12-14"); load_tiles("Satellite (2017-11-26)", "world-2017-11-26"); load_tiles("Satellite (2017-11-15)", "world-2017-11-15"); load_tiles("Satellite (2017-11-09)", "world-2017-11-09"); load_tiles("Satellite (2017-10-31)", "world-2017-10-31"); load_tiles("Satellite (2017-10-22)", "world-2017-10-22"); load_tiles("Satellite (2017-09-06)", "world-2017-09-06"); load_tiles("Satellite (2017-08-24)", "world-2017-08-24"); load_tiles("None", ''); load_geojson("All", "./geojson/all.json", "auto", "auto", 0); load_geojson("Streets", "./geojson/streets.json", "street", "auto", 1, style_streets); load_geojson("Trainlines (beta)", "./geojson/trainlines.json", "train", "auto", 1, style_trains); load_geojson("TL Access (tech layer)", "./geojson/trainlines_access.json", "train", "auto", 0, style_tech); load_geojson("Railroad Tracks", "./geojson/trains.json", "train", "auto", 0, style_trains); load_geojson("Cities", "./geojson/city_outlines.json", "outline", "auto", 1, style_outlines); load_geojson("Rivers", "./geojson/rivers.json", "street", "auto", 1, style_rivers); load_geojson("Oceans", "./geojson/oceans.json", "outline", "auto", 1, style_oceans); function update_geojson() { var xhttp_ps = new XMLHttpRequest(); xhttp_ps.open("GET", "https://notsyncing.net/maps.linux-forks.de/geojson/update.php", true); xhttp_ps.send(); } update_geojson(); L.control.scale().addTo(mymap); function resolve_latlng(latlng, recenter = 0) { latlng.lng = Math.round(latlng.lng); latlng.lat = Math.round(latlng.lat); return latlng; } function get_current_location_str() { var latlng = resolve_latlng(mymap.getCenter()); return latlng.lng + "," + latlng.lat + "," + mymap.getZoom(); } /* Important: Do not use mymap.setView, use this function instead */ function jump_to(latlng, zoom = -1) { if (zoom == -1) zoom = mymap.getZoom(); if (!editor_mode) { pos = resolve_latlng(latlng); document.location.hash = "#" + pos.lng + "," + pos.lat + "," + zoom; } else { mymap.setView(latlng, zoom); } } function jump_to_marker(e) { jump_to(e.target.getLatLng()); } function prompt_location() { var str = prompt("Enter coordinates to jump to:\n\n" + "Format: x, y [, zoom]", get_current_location_str()); if (str) { if (!editor_mode) document.location.hash = "#" + str; else onHashChange(null, "#" + str); } } var search_element; var route_element; function build_sidebar() { if (!search_element) { search_element = document.createElement("div"); search_element.style.overflow = "scroll"; search_element.style.padding = "6px"; search_element.style.height = "100%"; search_element.innerHTML = ''; } if (!route_element) { route_element = document.createElement("div"); route_element.style.overflow = "scroll"; route_element.style.padding = "6px"; route_element.style.height = "100%"; route_element.innerHTML = '<-- Return to search