lifomapserver/htdocs/mapscript.js

357 lines
10 KiB
JavaScript
Raw Normal View History

var editor_mode = 0;
var mymap;
2020-04-17 16:43:34 +02:00
var streetLabelsRenderer = new L.StreetLabels({
collisionFlg: true,
propertyName: 'name',
showLabelIf: function (layer) {
return layer.geometry.type == "LineString";
},
fontStyle: {
dynamicFontSize: false,
fontSize: 10,
fontSizeUnit: "px",
lineWidth: 4.0,
fillStyle: "black",
strokeStyle: "white",
},
});
2020-04-19 12:56:02 +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;
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, {
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
});
// Init map
mymap = L.map('mapid', {
2020-04-17 16:43:34 +02:00
renderer: streetLabelsRenderer,
editable: true,
2020-04-17 16:14:57 +02:00
crs: L.CRS.pr
}).setView([0, 0], 6);
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);
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-17 16:14:57 +02:00
;
xhttp_ps.open("GET", url, true);
xhttp_ps.send();
}
function load_tiles(name, id) {
2020-04-17 16:14:57 +02:00
var satellite = L.tileLayer('https://notsyncing.net/maps.linux-forks.de/tiles/?id={id}&z={z}&x={x}&y={y}', {
maxZoom: 14 /*8*/,
2020-04-17 16:14:57 +02:00
maxNativeZoom: 6,
minNativeZoom: 0,
minZoom: 0,
noWrap: true,
attribution: 'Map data &copy; <a href="https://wiki.linux-forks.de/mediawiki/index.php/Maps">Linux-Forks</a>, ' + 'All rights reserved, ',
id: id,
tileSize: 256,
zoomOffset: 0,
opacity: 1.0,
bounds: layerbounds
});
layers.addBaseLayer(satellite, name);
return satellite;
}
2020-04-17 16:43:34 +02:00
function load_geojson(name, url, iconname, 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-17 16:43:34 +02:00
switch (iconname) {
case "street":
onEachFeature = null;
pointToLayer = null;
break;
default: /* else it is a marker with the specified icon */
onEachFeature = function(feature, layer) {
label = String(feature.properties.name)
layer.bindPopup('<h1><a href="https://wiki.linux-forks.de/mediawiki/index.php/' + 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>');
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)
return new L.marker(latlng,{
icon: L.AwesomeMarkers.icon({
icon: iconname,
markerColor: iconcolor
})
}).bindTooltip(label, {
permanent: false,
direction: "center",
opacity: 0.7
}).openTooltip();
};
break;
}
var json = JSON.parse(xhttp_ps.responseText);
var geojson = L.geoJSON(json, {
2020-04-17 16:43:34 +02:00
style: style,
onEachFeature: onEachFeature,
pointToLayer: pointToLayer
2020-04-17 16:14:57 +02:00
});
layers.addOverlay(geojson, name);
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-17 16:14:57 +02:00
;
xhttp_ps.open("GET", url, true);
xhttp_ps.send();
}
2020-04-17 16:14:57 +02:00
load_tiles("Satellite (2020-04-09)", 'world-2020-04-09').addTo(mymap);
load_tiles("Satellite (2019-05-04, wrong coords)", 'world-2019-05-04');
//load_svg("Test", "./overlay.svg", 0);
load_geojson("Cities", "./geojson/cities.json", "city", "red");
load_geojson("Stations", "./geojson/stations.json", "train", "blue");
2020-04-15 13:20:28 +02:00
load_geojson("Shops", "./geojson/shops.json", "shopping-cart", "green");
load_geojson("Parks", "./geojson/parks.json", "tree", "darkgreen");
load_geojson("Libraries", "./geojson/libraries.json", "book-open", "darkblue");
load_geojson("CW Complexes", "./geojson/cw_complexes.json", "border-all", "black");
load_geojson("Courts", "./geojson/courts.json", "balance-scale", "black");
load_geojson("Waterway", "./geojson/waterway.json", "water", "darkblue");
load_geojson("Train Depots", "./geojson/depots.json", "wrench", "violet");
2020-04-17 22:00:50 +02:00
load_geojson("Streets", "./geojson/streets.json", "street", "blue", 0);
L.control.scale().addTo(mymap);
function get_current_location_str() {
var latlng = mymap.getCenter();
return Math.round(latlng.lng) + "," + Math.round(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)
2020-04-19 20:12:39 +02:00
document.location.hash = "#" + Math.round(latlng.lng) + "," + Math.round(latlng.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());
2020-04-19 17:00:01 +02:00
if (str) {
if (!editor_mode)
document.location.hash = "#" + str;
else
onHashChange(null, "#" + str);
}
}
2020-04-19 12:56:02 +02:00
var search_element;
function toggle_search() {
if (el = document.getElementById('searchbar')) {
el.parentNode.removeChild(el);
return;
}
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 = '<input style="width:100%;" id="search_query" name="lifo_map_search" type="search" placeholder="Start typing to search..." onkeypress="search(event)"><div id="search_results"></div>' ;
}
td = document.getElementById('windowtr').insertCell(0);
td.style.width = "400px";
td.style.borderRight = "1px solid black";
td.style.verticalAlign = "top";
td.id = "searchbar";
td.appendChild(search_element);
document.getElementById('search_query').focus();
}
function htmlEntities(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
var regex;
function search(e) {
var query = htmlEntities(document.getElementById("search_query").value);
2020-04-19 20:21:13 +02:00
document.getElementById('search_results').innerHTML = "";
2020-04-19 12:56:02 +02:00
if (query.length > 0 || e.key == "Enter") {
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];
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-19 20:12:57 +02:00
el.innerHTML = "[" + layers._layers[i].name + "] " + '<a href="#" onclick="layers._layers[' + i + '].layer._layers[' + item._leaflet_id + '].fire(\'click\'); return false;">' + item.feature.properties.name + "</a>";
2020-04-19 12:56:02 +02:00
results.appendChild(el);
}
break;
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
}
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;
L.DomEvent.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', function () {
window.LAYER = this.options.callback.call();
}, this);
return container;
}
});
2020-04-19 12:56:02 +02:00
L.SearchControl = L.MyControl.extend({
options: {
position: 'topleft',
callback: toggle_search,
title: 'Search',
html: '🔍'
}
});
L.GotoControl = L.MyControl.extend({
options: {
position: 'topleft',
callback: prompt_location,
2020-04-19 20:36:58 +02:00
title: 'Jump to coordinates',
html: '⌖'
}
});
2020-04-19 12:56:02 +02:00
mymap.addControl(new L.SearchControl());
mymap.addControl(new L.GotoControl());
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'
});
function onMapClick(e) {
2020-04-17 16:14:57 +02:00
popup.setLatLng(e.latlng).setContent("You clicked the map at " + e.latlng.toString()).openOn(mymap);
}
mymap.on('click', onMapClick);
var is_user_drag = 0;
function update_hash_from_position(e) {
if (is_user_drag)
is_user_drag = 0;
else
return;
if (!editor_mode)
document.location.hash = "#" + get_current_location_str();
}
function dragstart(e) {
is_user_drag = 1;
}
mymap.on('zoomend', function () {is_user_drag = 1; update_hash_from_position();});
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-19 17:00:01 +02:00
function onHashChange(e, hash=null) {
if (!hash)
hash = document.location.hash;
if (hash == "#" + get_current_location_str())
return; // We're already there
2020-04-19 17:00:01 +02:00
coordstr = hash.slice(1).replace(/%20/g, "").split(",");
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]));
mymap.setView(latlng, parseInt(coordstr[2]));
}
2020-04-19 12:56:02 +02:00
window.addEventListener("hashchange", onHashChange, false);
onHashChange(null);