Compare commits
2 Commits
dev
...
feature/co
Author | SHA1 | Date | |
---|---|---|---|
f834111e1f | |||
b33b131f96 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1 @@
|
||||
htdocs/tiles/**/
|
||||
scripts/geojson/*.json
|
||||
scripts/geojson/**/*.json
|
||||
|
9
.gitmodules
vendored
9
.gitmodules
vendored
@ -1,9 +0,0 @@
|
||||
[submodule "lifo-dijkstraserv"]
|
||||
path = lifo-dijkstraserv
|
||||
url = https://git.notsyncing.net/markus/lifo-dijkstraserv.git
|
||||
[submodule "htdocs/fa"]
|
||||
path = htdocs/fa
|
||||
url = https://github.com/FortAwesome/Font-Awesome
|
||||
[submodule "htdocs/awesomemarkers"]
|
||||
path = htdocs/awesomemarkers
|
||||
url = https://github.com/lvoogdt/Leaflet.awesome-markers
|
@ -1 +0,0 @@
|
||||
Subproject commit 4fcacdfc82ed58f0173062851a4cda713845df82
|
@ -1 +0,0 @@
|
||||
Subproject commit fcec2d1b01ff069ac10500ac42e4478d20d21f4c
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
$fn = "/tmp/lifo_update_ts";
|
||||
$ctime = time();
|
||||
$ltime = (int)(file_get_contents($fn));
|
||||
$ntime = $ltime + 60*1 * 30;
|
||||
if (isset($_GET['force']))
|
||||
$ntime = 0;
|
||||
if ($ctime > $ntime) {
|
||||
file_put_contents($fn, $ctime);
|
||||
echo "Downloading... ";
|
||||
flush();
|
||||
system("cd /srv/http/maps.linux-forks.de/geojson/; ./update_all.sh");
|
||||
} else {
|
||||
echo "Next update in " . intval(($ntime - $ctime) / 60) . " minutes.";
|
||||
}
|
||||
?>
|
@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
function fetch() {
|
||||
if [[ "$3" != "" ]]; then
|
||||
fn="$3"
|
||||
else
|
||||
fn="$1"
|
||||
fi
|
||||
"./fetch_$1.sh" "$2" | json_reformat -m > "$fn.json.tmp"
|
||||
rm -f "$fn.json"
|
||||
mv "$fn.json.tmp" "$fn.json"
|
||||
}
|
||||
|
||||
fetch streets
|
||||
fetch city_outlines
|
||||
fetch trainlines "Train Lines"
|
||||
fetch trainlines "Access Paths" trainlines_access
|
||||
fetch bodiesofwater "Rivers" rivers
|
||||
fetch bodiesofwater "Oceans, Seas, and Lakes" oceans
|
@ -1,54 +1,203 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>LinuxWorks Minetest Map [beta]</title>
|
||||
<meta charset="utf-8"/>
|
||||
<head>
|
||||
|
||||
<title>LinuxWorks Minetest Map (unofficial)</title>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="fa/css/all.css">
|
||||
<link rel="stylesheet" href="awesomemarkers/dist/leaflet.awesome-markers.css">
|
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>
|
||||
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>
|
||||
<script src="awesomemarkers/dist/leaflet.awesome-markers.js"></script>
|
||||
<!-- Streets -->
|
||||
<script src='leafletjs/ctxtextpath.js'></script>
|
||||
<script src='leafletjs/L.LabelTextCollision.js'></script>
|
||||
<script src='leafletjs/Leaflet.streetlabels.js'></script>
|
||||
<!-- Map Editor -->
|
||||
<script src='leafletjs/Leaflet.Editable.js'></script>
|
||||
</head>
|
||||
</head>
|
||||
<body style="position: absolute; padding: 0px; margin: 0px; width:100%; height:100%;">
|
||||
<table id="windowtable" style="border-spacing:0;border:0;height:100%;width:100%;"><tr id="windowtr">
|
||||
<td style="padding:0;margin:0;height:100%">
|
||||
<div id="mapid" style="padding:0;margin:0;width: 100%; height: 100%;"></div>
|
||||
</td>
|
||||
</tr></table>
|
||||
<div id="mapid" style="width: 100%; height: 100%;"></div>
|
||||
<style>
|
||||
.leaflet-tooltip.city-names {
|
||||
background-color: transparent;
|
||||
border: transparent;
|
||||
box-shadow: none;
|
||||
|
||||
font-weight: bold;
|
||||
font-size: 14pt;
|
||||
opacity: 1.0;
|
||||
opacity:1.0;
|
||||
color: white;
|
||||
text-shadow: 0px 0px 5px black;
|
||||
}
|
||||
|
||||
a.new {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.no-aa img[role=presentation] {
|
||||
image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
|
||||
image-rendering: -moz-crisp-edges; /* Firefox */
|
||||
image-rendering: -o-crisp-edges; /* Opera */
|
||||
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
|
||||
image-rendering: pixelated; /* Chrome */
|
||||
image-rendering: optimize-contrast; /* CSS3 Proposed */
|
||||
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
|
||||
}
|
||||
</style>
|
||||
<script src="mapscript.js?v3"></script>
|
||||
<script src="streeteditor.js"></script>
|
||||
<script>
|
||||
// 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;
|
||||
var originy = 7000;
|
||||
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
|
||||
var mymap = L.map('mapid', {
|
||||
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);
|
||||
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 satellite = L.tileLayer('tiles/?id={id}&z={z}&x={x}&y={y}', {
|
||||
maxZoom: 8,
|
||||
maxNativeZoom: 6,
|
||||
minNativeZoom: 0,
|
||||
minZoom: 0,
|
||||
noWrap: true,
|
||||
attribution: 'Map data © <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;
|
||||
}
|
||||
|
||||
function load_geojson(name, url, active=1, style = {}, onEachFeature = null, onClick=null) {
|
||||
var xhttp_ps = new XMLHttpRequest();
|
||||
xhttp_ps.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
if (this.status == 200) {
|
||||
var geojson = L.geoJSON(JSON.parse(xhttp_ps.responseText), {
|
||||
style: style,
|
||||
onEachFeature: onEachFeature
|
||||
});
|
||||
if (onClick)
|
||||
geojson.on('click', onClick)
|
||||
layers.addOverlay(geojson, name);
|
||||
if (active)
|
||||
geojson.addTo(mymap);
|
||||
return geojson;
|
||||
} else {
|
||||
alert("Error: Could not load geojson map layer (" + name + ").");
|
||||
}
|
||||
}
|
||||
};
|
||||
xhttp_ps.open("GET", url, true);
|
||||
xhttp_ps.send();
|
||||
}
|
||||
|
||||
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",
|
||||
1,
|
||||
{},
|
||||
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"}).openTooltip();
|
||||
},
|
||||
null);
|
||||
load_geojson(
|
||||
"All Places",
|
||||
"./geojson/all.json",
|
||||
1,
|
||||
{},
|
||||
null,
|
||||
onClick = function(e){
|
||||
console.log(e.sourceTarget.feature);
|
||||
popup
|
||||
.setLatLng(e.latlng)
|
||||
.setContent("Here is <a href=\"https://wiki.linux-forks.de/mediawiki/index.php/" + e.sourceTarget.feature.properties.name + "\">" + e.sourceTarget.feature.properties.name + "</a>")
|
||||
.openOn(mymap);
|
||||
});
|
||||
load_geojson(
|
||||
"Test",
|
||||
"./geojson/test.json",
|
||||
0,
|
||||
{
|
||||
radius: 8,
|
||||
fillColor: "#ff7800",
|
||||
color: "blue",
|
||||
opacity: 1,
|
||||
fillOpacity: 0.5
|
||||
},
|
||||
null,
|
||||
onClick = function(e){
|
||||
console.log(e.sourceTarget.feature);
|
||||
popup
|
||||
.setLatLng(e.latlng)
|
||||
.setContent("You clicked on <a href=\"https://wiki.linux-forks.de/mediawiki/index.php/" + e.sourceTarget.feature.properties.name + "\">" + e.sourceTarget.feature.properties.name + "</a>")
|
||||
.openOn(mymap);
|
||||
});
|
||||
|
||||
L.control.scale().addTo(mymap);
|
||||
|
||||
var popup = L.popup();
|
||||
|
||||
function onMapClick(e) {
|
||||
popup
|
||||
.setLatLng(e.latlng)
|
||||
.setContent("You clicked the map at " + e.latlng.toString())
|
||||
.openOn(mymap);
|
||||
}
|
||||
|
||||
//mymap.on('click', onMapClick);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,13 +0,0 @@
|
||||
L.LabelTextCollision=L.Canvas.extend({options:{collisionFlg:true},initialize:function(options){options=L.Util.setOptions(this,options);},_handleMouseHover:function(e,point){var id,layer;for(id in this._drawnLayers){layer=this._drawnLayers[id];if(layer.options.interactive&&layer._containsPoint(point)){L.DomUtil.addClass(this._containerText,'leaflet-interactive');this._fireEvent([layer],e,'mouseover');this._hoveredLayer=layer;}}
|
||||
if(this._hoveredLayer){this._fireEvent([this._hoveredLayer],e);}},_handleMouseOut:function(e,point){var layer=this._hoveredLayer;if(layer&&(e.type==='mouseout'||!layer._containsPoint(point))){L.DomUtil.removeClass(this._containerText,'leaflet-interactive');this._fireEvent([layer],e,'mouseout');this._hoveredLayer=null;}},_updateTransform:function(center,zoom){L.Canvas.prototype._updateTransform.call(this,center,zoom);var scale=this._map.getZoomScale(zoom,this._zoom),position=L.DomUtil.getPosition(this._container),viewHalf=this._map.getSize().multiplyBy(0.5+this.options.padding),currentCenterPoint=this._map.project(this._center,zoom),destCenterPoint=this._map.project(center,zoom),centerOffset=destCenterPoint.subtract(currentCenterPoint),topLeftOffset=viewHalf.multiplyBy(-scale).add(position).add(viewHalf).subtract(centerOffset);if(L.Browser.any3d){L.DomUtil.setTransform(this._containerText,topLeftOffset,scale);}else{L.DomUtil.setPosition(this._containerText,topLeftOffset);}},_initContainer:function(options){L.Canvas.prototype._initContainer.call(this);this._containerText=document.createElement('canvas');L.DomEvent.on(this._containerText,'mousemove',L.Util.throttle(this._onMouseMove,32,this),this).on(this._containerText,'click dblclick mousedown mouseup contextmenu',this._onClick,this).on(this._containerText,'mouseout',this._handleMouseOut,this);this._ctxLabel=this._containerText.getContext('2d');L.DomUtil.addClass(this._containerText,'leaflet-zoom-animated');this.getPane().appendChild(this._containerText);},_update:function(){this._textList=[];L.Renderer.prototype._update.call(this);var b=this._bounds,container=this._containerText,size=b.getSize(),m=L.Browser.retina?2:1;L.DomUtil.setPosition(container,b.min);container.width=m*size.x;container.height=m*size.y;container.style.width=size.x+'px';container.style.height=size.y+'px';container.style.zIndex='4';this._container.style.zIndex='3';if(L.Browser.retina){this._ctxLabel.scale(2,2);}
|
||||
this._ctxLabel.translate(-b.min.x,-b.min.y);L.Canvas.prototype._update.call(this);},_updatePoly:function(layer,closed){L.Canvas.prototype._updatePoly.call(this,layer,closed);this._text(this._ctxLabel,layer);},_updateCircle:function(layer){L.Canvas.prototype._updateCircle.call(this,layer);this._text(this._ctxLabel,layer);},_text:function(ctx,layer){if(layer.options.text!=undefined){ctx.globalAlpha=1;var p=layer._point;var textPoint;if(p==undefined){if(layer._parts.length==0||layer._parts[0].length==0){return;}
|
||||
p=this._getCenter(layer._parts[0]);}
|
||||
var offsetX=0;var offsetY=0;ctx.lineWidth=4.0;ctx.font="16px 'Meiryo'";var textWidth=(ctx.measureText(layer.options.text).width)
|
||||
+p.x;var textHeight=p.y+offsetY+20;var bounds=L.bounds(L.point(p.x+offsetX,p.y+offsetY),L.point(textWidth,textHeight));if(this.options.collisionFlg){for(var index in this._textList){var pointBounds=this._textList[index];if(pointBounds.intersects(bounds)){return;}}}
|
||||
this._textList.push(bounds);ctx.strokeStyle="white";ctx.strokeText(layer.options.text,p.x+offsetX,p.y
|
||||
+offsetY);if(layer.options.textColor==undefined){ctx.fillStyle="blue";}else{ctx.fillStyle=layer.options.textColor;}
|
||||
ctx.fillText(layer.options.text,p.x+offsetX,p.y
|
||||
+offsetY);}},_getCenter:function(points){var i,halfDist,segDist,dist,p1,p2,ratio,len=points.length;if(!len){return null;}
|
||||
for(i=0,halfDist=0;i<len-1;i++){halfDist+=points[i].distanceTo(points[i+1])/2;}
|
||||
if(halfDist===0){return points[0];}
|
||||
for(i=0,dist=0;i<len-1;i++){p1=points[i];p2=points[i+1];segDist=p1.distanceTo(p2);dist+=segDist;if(dist>halfDist){ratio=(dist-halfDist)/segDist;var resutl=[p2.x-ratio*(p2.x-p1.x),p2.y-ratio*(p2.y-p1.y)];return L.point(resutl[0],resutl[1]);}}},});
|
File diff suppressed because it is too large
Load Diff
@ -1,197 +0,0 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
*/
|
||||
L.StreetLabels = L.LabelTextCollision
|
||||
.extend({
|
||||
|
||||
options: {
|
||||
/**
|
||||
* Default property name to display the tooltip
|
||||
*/
|
||||
propertyName: 'name',
|
||||
showLabelIf: null,
|
||||
fontStyle: {
|
||||
dynamicFontSize: false,
|
||||
fontSize: 10,
|
||||
fontSizeUnit: "px",
|
||||
lineWidth: 4.0,
|
||||
fillStyle: "black",
|
||||
strokeStyle: "white",
|
||||
},
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
L.LabelTextCollision.prototype.initialize.call(this, options);
|
||||
L.Util.stamp(this);
|
||||
this._layers = this._layers || {};
|
||||
},
|
||||
|
||||
_initContainer: function (options) {
|
||||
L.LabelTextCollision.prototype._initContainer.call(this, options);
|
||||
|
||||
//Register the add/remove layers event to update the annotations accordingly
|
||||
if (this._map) {
|
||||
var handleLayerChanges = function () {
|
||||
this._reset();
|
||||
this._redraw();
|
||||
}.bind(this);
|
||||
this._map.on("layerremove", L.Util.throttle(handleLayerChanges, 32, this));
|
||||
}
|
||||
},
|
||||
|
||||
_text: function (ctx, layer) {
|
||||
|
||||
if (layer && layer.feature && layer.feature.properties && layer.feature.properties[this.options.propertyName] !== undefined) {
|
||||
if (this.options.showLabelIf) {
|
||||
if (this.options.showLabelIf.call(this, layer.feature) === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var layerText = layer.feature.properties[this.options.propertyName];
|
||||
ctx.globalAlpha = 1;
|
||||
var p;
|
||||
|
||||
// polygon or polyline
|
||||
if (layer._parts.length === 0 || layer._parts[0].length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer instanceof L.Polygon && this._map.hasLayer(layer)) {
|
||||
p = this._getCentroid(layer);
|
||||
}
|
||||
else {
|
||||
p = this._getCenter(layer._parts[0]);
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
// label bounds offset
|
||||
var offsetX = 0;
|
||||
var offsetY = 0;
|
||||
|
||||
/**
|
||||
* TODO setting for custom font
|
||||
*/
|
||||
ctx.lineWidth = this.options.fontStyle.lineWidth;
|
||||
|
||||
var fontSize = this.options.fontStyle.fontSize;
|
||||
if (this._map && this.options.fontStyle.dynamicFontSize === true) {
|
||||
fontSize = this._getDynamicFontSize(layer.feature);
|
||||
}
|
||||
|
||||
ctx.font = fontSize + this.options.fontStyle.fontSizeUnit + " 'Helvetica Neue',Helvetica,Arial,sans-serif";
|
||||
|
||||
// Collision detection
|
||||
var textWidth = (ctx.measureText(layerText).width) + p.x;// + offsetX;
|
||||
|
||||
var textHeight = p.y + offsetY + 20;
|
||||
|
||||
var bounds = L.bounds(
|
||||
L.point(p.x + offsetX, p.y + offsetY), L.point(
|
||||
textWidth, textHeight));
|
||||
|
||||
if (this._getCollisionFlag(layer)) {
|
||||
for (var index in this._textList) {
|
||||
var pointBounds = this._textList[index];
|
||||
if (pointBounds.intersects(bounds)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._textList.push(bounds);
|
||||
|
||||
ctx.fillStyle = this.options.fontStyle.fillStyle;
|
||||
ctx.strokeStyle = this.options.fontStyle.strokeStyle;
|
||||
|
||||
if (layer instanceof L.Polygon || layer instanceof L.CircleMarker) {
|
||||
var textLength = ctx.measureText(layerText).width;
|
||||
ctx.strokeText(layerText, p.x + offsetX - textLength / 2, p.y + offsetY);
|
||||
ctx.fillText(layerText, p.x + offsetX - textLength / 2, p.y + offsetY);
|
||||
} else if (layer instanceof L.Polyline) {
|
||||
/**
|
||||
* Render text alongside the polyline
|
||||
* **/
|
||||
var startCoords = layer.getLatLngs()[0];
|
||||
var stopCoords = layer.getLatLngs()[layer.getLatLngs().length - 1];
|
||||
|
||||
//Flip lineString if bearing is negative
|
||||
flip = (this._getBearing(startCoords, stopCoords) < 0);
|
||||
|
||||
if (layer._parts) {
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
//ctx.lineWidth = 3;
|
||||
layer._parts.forEach(function (part) {
|
||||
//Build the points list for the first part
|
||||
var pathPoints = [];
|
||||
for (var i = 0; i < part.length; i++) {
|
||||
var linePart = (flip ? part[part.length - 1 - i] : part[i]);
|
||||
pathPoints.push(linePart.x);
|
||||
pathPoints.push(linePart.y);
|
||||
}
|
||||
|
||||
ctx.textPath(layerText, pathPoints);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_getCollisionFlag: function (layer) {
|
||||
return this.options.collisionFlg;
|
||||
},
|
||||
|
||||
/***
|
||||
* Returns the bearing in degrees clockwise from north (0 degrees)
|
||||
from the first L.LatLng to the second, at the first LatLng
|
||||
@param {L.LatLng} latlng1: origin point of the bearing
|
||||
@param {L.LatLng} latlng2: destination point of the bearing
|
||||
@returns {float} degrees clockwise from north.
|
||||
Source: https://makinacorpus.github.io/Leaflet.GeometryUtil/leaflet.geometryutil.js.html
|
||||
*/
|
||||
_getBearing: function (startCoords, stopCoords) {
|
||||
if (startCoords.lat == stopCoords.lat) {
|
||||
if (startCoords.lng > stopCoords.lng)
|
||||
return -180;
|
||||
else
|
||||
return 180;
|
||||
}
|
||||
if (startCoords.lng == stopCoords.lng) {
|
||||
if (startCoords.lat > stopCoords.lat)
|
||||
return -90;
|
||||
else
|
||||
return 90;
|
||||
}
|
||||
var angle = Math.atan(stopCoords.lng - startCoords.lng, stopCoords.lat - startCoords.lat) * 180 / Math.Pi;
|
||||
return angle;
|
||||
},
|
||||
|
||||
/**
|
||||
Returns a clone with reversed coordinates.
|
||||
@param {L.PolyLine} polyline polyline to reverse
|
||||
@returns {L.PolyLine} polyline reversed
|
||||
Source: https://makinacorpus.github.io/Leaflet.GeometryUtil/leaflet.geometryutil.js.html
|
||||
*/
|
||||
_getLineStringReverse: function (polyline) {
|
||||
var latLngs = polyline.getLatLngs().slice(0).reverse();
|
||||
polyline.setLatLngs(latLngs);
|
||||
return polyline;
|
||||
},
|
||||
|
||||
_getDynamicFontSize: function (layer) {
|
||||
return parseInt(this._map.getZoom());
|
||||
},
|
||||
|
||||
_getCentroid: function (layer) {
|
||||
if (layer && layer.getCenter && this._map) {
|
||||
var latlngCenter = layer.getCenter();
|
||||
var containerPoint = this._map.latLngToContainerPoint(latlngCenter);
|
||||
return this._map.containerPointToLayerPoint(containerPoint);
|
||||
}
|
||||
},
|
||||
});
|
@ -1,35 +0,0 @@
|
||||
(function()
|
||||
{function dist2D(x1,y1,x2,y2)
|
||||
{var dx=x2-x1;var dy=y2-y1;return Math.sqrt(dx*dx+dy*dy);}
|
||||
CanvasRenderingContext2D.prototype.textOverflow="";CanvasRenderingContext2D.prototype.textJustify=false;CanvasRenderingContext2D.prototype.textStrokeMin=0;var state=[];var save=CanvasRenderingContext2D.prototype.save;CanvasRenderingContext2D.prototype.save=function()
|
||||
{state.push({textOverflow:this.textOverflow,textJustify:this.textJustify,textStrokeMin:this.textStrokeMin,});save.call(this);}
|
||||
var restore=CanvasRenderingContext2D.prototype.restore;CanvasRenderingContext2D.prototype.restore=function()
|
||||
{restore.call(this);var s=state.pop();this.textOverflow=s.textOverflow;this.textJustify=s.textJustify;this.textStrokeMin=s.textStrokeMin;}
|
||||
CanvasRenderingContext2D.prototype.textPath=function(text,path)
|
||||
{var di,dpos=0;var pos=2;function pointAt(dl)
|
||||
{if(!di||dpos+di<dl)
|
||||
{for(;pos<path.length;)
|
||||
{di=dist2D(path[pos-2],path[pos-1],path[pos],path[pos+1]);if(dpos+di>dl)break;pos+=2;if(pos>=path.length)break;dpos+=di;}}
|
||||
var x,y,dt=dl-dpos;if(pos>=path.length)
|
||||
{pos=path.length-2;}
|
||||
if(!dt)
|
||||
{x=path[pos-2];y=path[pos-1];}
|
||||
else
|
||||
{x=path[pos-2]+(path[pos]-path[pos-2])*dt/di;y=path[pos-1]+(path[pos+1]-path[pos-1])*dt/di;}
|
||||
return[x,y,Math.atan2(path[pos+1]-path[pos-1],path[pos]-path[pos-2])];}
|
||||
var letterPadding=this.measureText(" ").width*0.25;var d=0;for(var i=2;i<path.length;i+=2)
|
||||
{d+=dist2D(path[i-2],path[i-1],path[i],path[i+1])}
|
||||
if(d<this.minWidth)return;var nbspace=text.split(" ").length-1;if(this.textOverflow!="visible")
|
||||
{if(d<this.measureText(text).width+(text.length-1+nbspace)*letterPadding)
|
||||
{var overflow=(this.textOverflow=="ellipsis")?'\u2026':this.textOverflow||"";var dt=overflow.length-1;do
|
||||
{if(text[text.length-1]===" ")nbspace--;text=text.slice(0,-1);}while(text&&d<this.measureText(text+overflow).width+(text.length+dt+nbspace)*letterPadding)
|
||||
text+=overflow;}}
|
||||
var start=0;switch(this.textJustify||this.textAlign)
|
||||
{case true:case "center":case "end":case "right":{if(this.textJustify)
|
||||
{start=0;letterPadding=(d-this.measureText(text).width)/(text.length-1+nbspace);}
|
||||
else
|
||||
{start=d-this.measureText(text).width-(text.length+nbspace)*letterPadding;if(this.textAlign=="center")start/=2;}
|
||||
break;}
|
||||
default:break;}
|
||||
for(var t=0;t<text.length;t++)
|
||||
{var letter=text[t];var wl=this.measureText(letter).width;var p=pointAt(start+wl/2);this.save();this.textAlign="center";this.translate(p[0],p[1]);this.rotate(p[2]);if(this.lineWidth>0.1)this.strokeText(letter,0,0);this.fillText(letter,0,0);this.restore();start+=wl+letterPadding*(letter==" "?2:1);}};})();
|
@ -1,825 +0,0 @@
|
||||
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 © <a href="' + wikiurl_base + 'Maps">Linux-Forks</a>',
|
||||
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('<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>');
|
||||
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 (2020-12-13)", 'world-2020-12-13').addTo(mymap);
|
||||
load_tiles("Satellite (2020-11-20)", 'world-2020-11-20');
|
||||
load_tiles("Satellite (2020-08-30)", 'world-2020-08-30');
|
||||
load_tiles("Satellite (2020-06-04)", 'world-2020-06-04');
|
||||
load_tiles("Satellite (2020-04-26)", 'world-2020-04-26');
|
||||
load_tiles("Satellite (2020-04-09)", 'world-2020-04-09');
|
||||
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 = '<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%";
|
||||
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>';
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
td = document.getElementById('windowtr').insertCell(0);
|
||||
td.style.width = "400px";
|
||||
td.style.borderRight = "1px solid black";
|
||||
td.style.verticalAlign = "top";
|
||||
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;
|
||||
}
|
||||
|
||||
function htmlEntities(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
var highlighted_line;
|
||||
var default_street_color = "#3388ff";
|
||||
|
||||
function search(e) {
|
||||
var query = document.getElementById("search_query").value;
|
||||
var real_query = true;
|
||||
document.getElementById('search_results').innerHTML = "";
|
||||
if (true) {
|
||||
if (query.length == 0) {
|
||||
real_query = false;
|
||||
query = "!@#$%^&"; // Cheap workaround to (hopefully) match nothing
|
||||
}
|
||||
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];
|
||||
if (item.hasOwnProperty("no_search"))
|
||||
break;
|
||||
switch (item.feature.geometry.type) {
|
||||
case "Point":
|
||||
regex = new RegExp(query, 'i');
|
||||
if (item.feature.properties.name.match(regex)) {
|
||||
el = document.createElement("li");
|
||||
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>";
|
||||
results.appendChild(el);
|
||||
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
|
||||
}
|
||||
break;
|
||||
case "LineString":
|
||||
if (item.options.color != default_street_color) { // De-hilight last search
|
||||
item.options.color = default_street_color;
|
||||
item.redraw();
|
||||
}
|
||||
regex = new RegExp(query, 'i');
|
||||
|
||||
if (item.feature.properties.name.match(regex)) {
|
||||
item.options.color = "#FF0000";
|
||||
item.redraw();
|
||||
el = document.createElement("li");
|
||||
zpos = polyline_get_middle_coords(item.feature.geometry.coordinates);
|
||||
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>";
|
||||
results.appendChild(el);
|
||||
}
|
||||
break;
|
||||
case "Polygon":
|
||||
regex = new RegExp(query, 'i');
|
||||
|
||||
if (item.feature.properties.name.match(regex)) {
|
||||
el = document.createElement("li");
|
||||
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>";
|
||||
results.appendChild(el);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
document.getElementById('search_results').appendChild(results);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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) {
|
||||
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>";
|
||||
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();
|
||||
}
|
||||
|
||||
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, 'mousedown', L.DomEvent.stop);
|
||||
L.DomEvent.on(link, 'mouseup', L.DomEvent.stop);
|
||||
L.DomEvent.on(link, 'click', L.DomEvent.stop)
|
||||
.on(link, 'click', function () {
|
||||
window.LAYER = this.options.callback.call();
|
||||
}, this);
|
||||
return container;
|
||||
}
|
||||
});
|
||||
|
||||
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,
|
||||
title: 'Jump to coordinates',
|
||||
html: '⌖'
|
||||
}
|
||||
});
|
||||
mymap.addControl(new L.SearchControl());
|
||||
mymap.addControl(new L.GotoControl());
|
||||
|
||||
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());
|
||||
|
||||
var popup = L.popup();
|
||||
|
||||
L.AwesomeMarkers.Icon.prototype.options.prefix = 'fa';
|
||||
var baseballIcon = L.AwesomeMarkers.icon({
|
||||
icon: 'coffee',
|
||||
markerColor: 'red'
|
||||
});
|
||||
|
||||
function escapeHtml(text) {
|
||||
return text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function onMapClick(e) {
|
||||
var addinfo = "";
|
||||
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>';
|
||||
if (current_location != "")
|
||||
addinfo = " (part of <a target=\"_blank\" href=\"" + wikiurl_base + encodeURIComponent(current_location) + "\">" + escapeHtml(current_location) + "</a>)";
|
||||
if (current_feature) {
|
||||
popup.setLatLng(e.latlng).setContent("This is <a target=\"_blank\" href=\"" + wikiurl_base + current_layer.myName + ":" + encodeURIComponent(current_feature.properties.name) + "\">" + escapeHtml(current_feature.properties.name) + "</a>" + addinfo + route_links).openOn(mymap);
|
||||
} else {
|
||||
popup.setLatLng(e.latlng).setContent("You clicked the map at " + pos.lng + "," + pos.lat + addinfo + route_links).openOn(mymap);
|
||||
}
|
||||
current_feature = null;
|
||||
current_layer = null;
|
||||
current_location = "";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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};
|
||||
mymap.eachLayer( function(layer) {
|
||||
if ( layer.myTag && layer.myTag === "street") {
|
||||
layer.setStyle(myStyle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function update_outline_visibility() {
|
||||
zoom = mymap.getZoom();
|
||||
mymap.eachLayer( function(layer) {
|
||||
if ( layer.myTag && layer.myTag === "outline") {
|
||||
var fillOpacity;
|
||||
if (zoom <= polyconf_show_cities)
|
||||
fillOpacity = 0.5;
|
||||
//else if (zoom == polyconf_show_cities + 1)
|
||||
// opacity = 0.2;
|
||||
else
|
||||
fillOpacity = 0.0;
|
||||
|
||||
layer.setStyle({fillOpacity: fillOpacity});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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(); });
|
||||
mymap.on('mousemove', update_current_mouse_position);
|
||||
mymap.on('mouseout', update_current_mouse_position);
|
||||
|
||||
function onHashChange(e, hash=null) {
|
||||
if (!hash)
|
||||
hash = document.location.hash;
|
||||
if (hash == "")
|
||||
return;
|
||||
if (hash == "#" + get_current_location_str())
|
||||
return; // We're already there
|
||||
coordstr = decodeURIComponent(hash.slice(1)).split(",");
|
||||
if (coordstr.length < 2)
|
||||
coordstr.push(0); // Default y
|
||||
if (coordstr.length < 3)
|
||||
coordstr.push(mymap.getZoom()); // Default zoom
|
||||
var latlng = L.latLng(parseFloat(coordstr[1]), parseFloat(coordstr[0]));
|
||||
mymap.setView(latlng, parseInt(coordstr[2]));
|
||||
if (coordstr.length > 3) { /* Drop named marker */
|
||||
foo = L.marker(latlng).bindPopup(htmlEntities(coordstr[3])).addTo(mymap).openPopup();
|
||||
}
|
||||
}
|
||||
|
||||
build_sidebar();
|
||||
|
||||
window.addEventListener("hashchange", onHashChange, false);
|
||||
onHashChange(null);
|
@ -1,212 +0,0 @@
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
editor_mode = urlParams.has('editor');
|
||||
|
||||
if (editor_mode) {
|
||||
var editor_mode_polygon = urlParams.has('polygon');
|
||||
|
||||
var draw_layer;
|
||||
var polyline;
|
||||
|
||||
var edit_active = 0;
|
||||
|
||||
var editor_style = {
|
||||
radius: 8,
|
||||
fillColor: "#00ff00",
|
||||
color: "red",
|
||||
opacity: 1.0,
|
||||
fillOpacity: 0.5
|
||||
};
|
||||
|
||||
function start_editing(dir = 1) {
|
||||
// TODO: Check whether we already are in edit mode
|
||||
// TODO: Detect whether we are cloner to the tail or the head, and issue Fwd or Bwd accordingly
|
||||
if (polyline) {
|
||||
if (dir)
|
||||
polyline.editor.continueForward();
|
||||
else
|
||||
polyline.editor.continueBackward();
|
||||
} else {
|
||||
if (editor_mode_polygon)
|
||||
polyline = mymap.editTools.startPolygon();
|
||||
else
|
||||
polyline = mymap.editTools.startPolyline();
|
||||
}
|
||||
}
|
||||
|
||||
function start_reverse_editing() {
|
||||
start_editing(0);
|
||||
}
|
||||
|
||||
function strToPoints(str) {
|
||||
var temp = JSON.parse("[" + str + "]"); // TODO: add .5 everwhere
|
||||
return temp;
|
||||
}
|
||||
|
||||
function onDragEnd(e) {
|
||||
if (!polyline)
|
||||
return;
|
||||
var latlngs = polyline.getLatLngs();
|
||||
|
||||
for (var i = 0; i < latlngs.length; i++) {
|
||||
latlngs[i] = resolve_latlng(latlngs[i], 1);
|
||||
}
|
||||
polyline.editor.refresh();
|
||||
polyline.editor.refreshVertexMarkers();
|
||||
location.hash = get_location_string();
|
||||
}
|
||||
|
||||
function onLoad(interactive = 1) {
|
||||
if (interactive) {
|
||||
str = prompt("Instructions: \n" +
|
||||
"* Click the scribble-icon in the top left to start or continue drawing.\n" +
|
||||
"* Click last waypoint to stop drawing.\n" +
|
||||
"* Click a waypoint to delete it.\n" +
|
||||
"* Click save in the top right to get the new string.\n\n" +
|
||||
"Enter existing waypoints in the following format: [x,y],[x,y]:", window.location.hash.slice(1));
|
||||
if (str == undefined)
|
||||
return;
|
||||
} else {
|
||||
str = window.location.hash.slice(1);
|
||||
}
|
||||
|
||||
if (polyline) {
|
||||
polyline.remove(mymap);
|
||||
polyline = undefined;
|
||||
}
|
||||
|
||||
if (str) {
|
||||
coords = strToPoints(str);
|
||||
for (var i = 0; i < coords.length; i++) {
|
||||
coords[i] = [coords[i][1], coords[i][0]];
|
||||
}
|
||||
if (editor_mode_polygon)
|
||||
polyline = L.polygon([coords], editor_style).addTo(mymap);
|
||||
else
|
||||
polyline = L.polyline(coords, editor_style).addTo(mymap);
|
||||
// polyline.on('dragend', onDragEnd); // TODO: Doesn't work, see "workaround" below
|
||||
polyline.enableEdit();
|
||||
if (interactive) {
|
||||
latlng = L.latLng(polyline_get_middle_coords(coords));
|
||||
jump_to(latlng, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function editor_onHashChange() {
|
||||
if (("#" + get_location_string()) != window.location.hash) {
|
||||
onLoad(0);
|
||||
}
|
||||
}
|
||||
|
||||
window.removeEventListener("hashchange", onHashChange, false);
|
||||
window.addEventListener("hashchange", editor_onHashChange, false);
|
||||
window.addEventListener("mouseup", onDragEnd, false); // Workaround as polyline.on(dragend, ) doesn't seem to work
|
||||
|
||||
function onMapKeydown(e) {
|
||||
if (e.originalEvent.key == "Escape") {
|
||||
if (polyline)
|
||||
polyline.editor.cancelDrawing();
|
||||
}
|
||||
}
|
||||
|
||||
// Configure map for better editing
|
||||
mymap.setMaxZoom(14);
|
||||
mymap.off('click', onMapClick);
|
||||
mymap.on('keydown', onMapKeydown);
|
||||
|
||||
function get_location_string() {
|
||||
var latlngs;
|
||||
if (editor_mode_polygon)
|
||||
latlngs = polyline.getLatLngs()[0];
|
||||
else
|
||||
latlngs = polyline.getLatLngs();
|
||||
var str = "";
|
||||
|
||||
for (var i = 0; i < latlngs.length; i++) {
|
||||
latlng = resolve_latlng(latlngs[i], 1);
|
||||
if (i != 0)
|
||||
str += ",";
|
||||
str += "[" + (latlng.lng) + "," + (latlng.lat) + "]";
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function show_location_string(e) {
|
||||
if (polyline)
|
||||
polyline.editor.cancelDrawing();
|
||||
prompt("Copy this string back into the Wiki and wait for the server to refresh the maps:", get_location_string());
|
||||
}
|
||||
|
||||
function reset_path(e) {
|
||||
onLoad(1);
|
||||
}
|
||||
|
||||
L.EditControl = 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, 'mousedown', L.DomEvent.stop);
|
||||
L.DomEvent.on(link, 'mouseup', L.DomEvent.stop);
|
||||
L.DomEvent.on(link, 'click', L.DomEvent.stop)
|
||||
.on(link, 'click', function (e) {
|
||||
window.LAYER = this.options.callback.call(map.editTools);
|
||||
}, this);
|
||||
return container;
|
||||
}
|
||||
});
|
||||
|
||||
L.ResetPathControl = L.EditControl.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
callback: reset_path,
|
||||
title: 'Enter path coordinates',
|
||||
html: '📂'
|
||||
}
|
||||
});
|
||||
|
||||
L.StartEditControl = L.EditControl.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
callback: start_editing,
|
||||
title: 'Start editing (forward)',
|
||||
html: '\\/\\'
|
||||
}
|
||||
});
|
||||
|
||||
L.StartReverseEditControl = L.EditControl.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
callback: start_reverse_editing,
|
||||
title: 'Start editing (backward)',
|
||||
html: '↺'
|
||||
}
|
||||
});
|
||||
|
||||
L.NewLineControl = L.EditControl.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
callback: show_location_string,
|
||||
title: 'Get location string',
|
||||
html: '💾'
|
||||
}
|
||||
});
|
||||
|
||||
mymap.addControl(new L.NewLineControl());
|
||||
mymap.addControl(new L.ResetPathControl());
|
||||
mymap.addControl(new L.StartEditControl());
|
||||
mymap.addControl(new L.StartReverseEditControl());
|
||||
|
||||
onLoad();
|
||||
}
|
3
htdocs/tiles/index.php
Normal file
3
htdocs/tiles/index.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
?>
|
@ -1 +0,0 @@
|
||||
Subproject commit faa5d7ca4b9b16442de4bd3c3cc49567cfd56598
|
@ -1,62 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
OUTDIR=`pwd`/tiles
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
|
||||
mode="$1"
|
||||
|
||||
if [ "$mode" == "legacy" ]; then
|
||||
MAPSERVER='http://old-maps.li-fo.de/'
|
||||
FILES=`curl "$MAPSERVER" | sed -n 's/.*<a href="\([^\.]\+\.png\).*/\1/p'`
|
||||
else
|
||||
MAPSERVER='https://lifomaps.de'
|
||||
FILES=`curl "$MAPSERVER" | sed -n 's/.*>\(world-[0-9\-]\+\.png\).*/\1/p'`
|
||||
fi
|
||||
|
||||
if [[ "$FILES" == "" ]]; then
|
||||
echo "ERROR: Could not detect latest map file."
|
||||
exit
|
||||
fi
|
||||
|
||||
for FILE in $FILES; do
|
||||
REMOTE_URL="$MAPSERVER/$FILE"
|
||||
LOCAL_FILE="`echo $FILE | sed 's#.*/##'`"
|
||||
LOCAL_URL="$OUTDIR/$LOCAL_FILE"
|
||||
MAPNAME=`echo $LOCAL_URL | sed 's/.*\/\([^\.]\+\).*/\1/g'`
|
||||
|
||||
echo "# Downloading and converting $MAPNAME."
|
||||
|
||||
mkdir -p $OUTDIR
|
||||
cd $OUTDIR
|
||||
|
||||
if [ ! -d "$OUTDIR/$MAPNAME" ]; then
|
||||
echo "Downloading latest map file..."
|
||||
curl -C - "$REMOTE_URL" -o "$LOCAL_URL"
|
||||
|
||||
if [ "$mode" == "legacy" ]; then
|
||||
echo "Patching map (for map exports prior to 2019-07-09)..."
|
||||
OSIZE=`file $LOCAL_URL | sed -n 's/.*PNG image data, \([0-9]\+\).*/\1/p'`
|
||||
NSIZE=$(($OSIZE+1008))
|
||||
RESIZED_URL="$LOCAL_URL-temp.png"
|
||||
convert $LOCAL_URL -gravity SouthEast -extent ${NSIZE}x${NSIZE} $RESIZED_URL
|
||||
rm $LOCAL_URL
|
||||
mv $RESIZED_URL $LOCAL_URL
|
||||
fi
|
||||
|
||||
echo "Resizing map..."
|
||||
OSIZE=`file $LOCAL_URL | sed -n 's/.*PNG image data, \([0-9]\+\).*/\1/p'`
|
||||
NSIZE=$((2**6 * 256))
|
||||
RESIZED_URL="$LOCAL_URL-resized.png"
|
||||
convert $LOCAL_URL -extent ${NSIZE}x${NSIZE} -gravity NorthWest $RESIZED_URL
|
||||
|
||||
echo "Converting map..."
|
||||
$SCRIPT_DIR/convert_maps.sh $MAPNAME $RESIZED_URL
|
||||
|
||||
echo "Cleaning up..."
|
||||
rm $RESIZED_URL
|
||||
rm $LOCAL_URL
|
||||
else
|
||||
echo "Skipping $MAPNAME."
|
||||
fi
|
||||
done
|
@ -11,8 +11,8 @@
|
||||
# `convert $MAPFILE -extent ${crop}x${crop} -gravity NorthWest $MAPFILE.scaled.png`
|
||||
|
||||
TILESIZE=256
|
||||
MAPNAME="$1"
|
||||
MAPFILE="$2"
|
||||
MAPNAME="world-2020-04-09"
|
||||
MAPFILE="../$MAPNAME.png"
|
||||
|
||||
width=`file "$MAPFILE" | sed -n "s/.* \([0-9]\+\) x \([0-9]\+\).*/\1/p"`
|
||||
crop=$TILESIZE
|
||||
@ -41,7 +41,7 @@ while true; do
|
||||
fi
|
||||
|
||||
echo " Generating tiles..."
|
||||
convert $tempfile -crop ${TILESIZE}x${TILESIZE} +adjoin $out/%d.png
|
||||
convert $tempfile -crop ${TILESIZE}x${TILESIZE} +adjoin $out/%05d.png
|
||||
|
||||
rm $tempfile
|
||||
|
||||
@ -51,16 +51,3 @@ while true; do
|
||||
crop=$(($crop * 2))
|
||||
zoom=$(($zoom + 1))
|
||||
done;
|
||||
|
||||
echo "Renaming files..."
|
||||
for (( z=0; z<=$zoom; z++ )) {
|
||||
echo "Zoom level $z"
|
||||
fac=$((2**$z))
|
||||
for (( y=0; y<$fac; y++ )) {
|
||||
outdir="$MAPNAME/$z/$y"
|
||||
mkdir $outdir
|
||||
for (( x=0; x<$fac; x++ )) {
|
||||
mv $MAPNAME/$z/$(($fac * y + $x)).png $outdir/$x.png
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
json=`curl -s 'https://wiki.linux-forks.de/mediawiki/api.php?action=query&format=json&list=search&redirects=1&converttitles=1&srsearch=%7B%7BCo%7C&srlimit=max&srwhat=text&srprop=snippet'`
|
||||
data=`echo "$json" | json_reformat`;
|
||||
|
||||
echo "[";
|
||||
|
||||
IFS=$'\n';
|
||||
for line in $data; do
|
||||
temp=`echo "$line" | sed -n 's/^\s*{\s*$/END/p'`
|
||||
if [[ "$temp" == "END" ]]; then
|
||||
title="";
|
||||
coords="";
|
||||
fi
|
||||
temp=`echo "$line" | sed -n 's/\s*"title": "*\([^"]\+\).*/\1/p'`
|
||||
if [[ "$temp" != "" ]]; then
|
||||
title="$temp";
|
||||
fi
|
||||
temp=`echo "$line" | sed -n 's#.*<span class=.searchmatch.>Co<\/span>|\([0-9\-]\+\)|\([0-9\-]\+\)|\([0-9\-]\+\).*#\1,\3#p'`
|
||||
if [[ "$temp" != "" ]]; then
|
||||
coords="$temp";
|
||||
fi
|
||||
if [[ "$title" != "" && "$coords" != "" ]]; then
|
||||
echo "{\"type\": \"Feature\", \"properties\": {\"name\": \"$title\","
|
||||
urltitle=`echo "$title" | sed 's/ /_/g'`
|
||||
./get_rendered_meta.sh "https://wiki.linux-forks.de/mediawiki/index.php/$urltitle"
|
||||
echo "},";
|
||||
echo "\"geometry\": {\"type\": \"Point\", \"coordinates\": [$coords]}},";
|
||||
title="";
|
||||
coords="";
|
||||
fi
|
||||
done
|
||||
IFS=" ";
|
||||
|
||||
echo "{}]";
|
||||
json=`curl 'https://wiki.linux-forks.de/mediawiki/api.php?action=query&format=json&list=search&redirects=1&converttitles=1&srsearch=%7B%7BCo%7C&srlimit=max&srwhat=text&srprop=snippet'`
|
||||
echo "["
|
||||
echo $json | json_reformat | grep -B 2 'coordinates' | sed -n -e 's#.*o</span>|\([0-9\\-]\+\)|[0-9\\-]*|\([0-9\\-]\+\).*#"geometry": {"type": "Point", "coordinates": [\1,\2]}},#p' -e 's/.*title": "\([^"]*\).*/{ "type": "Feature", "properties": {"name": "\1"},/p'
|
||||
echo "{}]"
|
||||
|
10
scripts/geojson/fetch_cities.sh
Executable file
10
scripts/geojson/fetch_cities.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
json=`curl 'https://wiki.linux-forks.de/mediawiki/api.php?action=query&format=json&list=categorymembers&cmtitle=Category:City&cmlimit=100'`
|
||||
cities=`echo "$json" | json_reformat | sed -n 's/.*"title":\s*"\([^"]*\).*/\1/p' | tr ' ' '_' | tr '\n' ' '`
|
||||
|
||||
echo "["
|
||||
for city in $cities; do
|
||||
./fetch_single.sh "$city"
|
||||
done
|
||||
echo "{}]"
|
29
scripts/geojson/fetch_single.sh
Executable file
29
scripts/geojson/fetch_single.sh
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
json=`curl "https://wiki.linux-forks.de/mediawiki/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=$1&rvsection=0&rvslots=main" | sed -s "s/\\\\\\\\n//g"`
|
||||
|
||||
title=`echo $json | sed -n 's/.*"title":\s*"\([^"]\+\).*/\1/p'`
|
||||
image=`echo "$json" | sed -n "s/.*image = \([^|]*\).*/\1/p"`
|
||||
|
||||
coords=`echo "$json" | sed -n "s/.*coordinates = {{Co|\([^}]*\).*/\1/p"`
|
||||
coord_x=`echo "$coords" | sed -n "s/\([^|]\+\).*/\1/p"`
|
||||
coord_y=`echo "$coords" | sed -n "s/.*|\([^|]\+\).*/\1/p"`
|
||||
|
||||
description=`echo $json | sed -n "s/.*coordinates.*[^']*'''\([^']*\)'''\([^\.]*\).*/\1\2./p"
|
||||
`
|
||||
|
||||
if [[ "$coord_x" != "" && "$coord_y" != "" ]]; then
|
||||
echo "{\
|
||||
\"type\": \"Feature\",\
|
||||
\"properties\": {\
|
||||
\"name\": \"$title\",\
|
||||
\"amenity\": \"City\",\
|
||||
\"description\": \"$description\",\
|
||||
\"image\": \"https://wiki.linux-forks.de/mediawiki/images/thumb/0/0e/$image/250px-$image\"\
|
||||
},\
|
||||
\"geometry\": {\
|
||||
\"type\": \"Point\",\
|
||||
\"coordinates\": [$coord_x, $coord_y]\
|
||||
}\
|
||||
},"
|
||||
fi
|
@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
BASE="https://wiki.linux-forks.de"
|
||||
|
||||
mode="find_description"
|
||||
|
||||
thumbnail=""
|
||||
categories=""
|
||||
|
||||
data=`curl -s "$1"`
|
||||
|
||||
temp=`echo "$data" | sed -n 's/<p>\(.\+\).*/\1/p' | grep -v -e '^<br />$' | sed 's#^</p>##' | head -n1`
|
||||
if [ "$temp" != "" ]; then
|
||||
temp=`echo "$temp" | sed "s#href=\"#href=\"$BASE#g" | sed 's/"/\\\\"/g' | sed 's/\t//g'`
|
||||
description="$temp"
|
||||
mode="find_infobox";
|
||||
fi
|
||||
|
||||
IFS=$'>';
|
||||
for line in $data; do
|
||||
if [ "$mode" == "find_infobox" ]; then
|
||||
if [ "`echo \"$line\" | grep 'infobox'`" != "" ]; then
|
||||
mode="image";
|
||||
fi
|
||||
elif [ "$mode" == "image" ]; then
|
||||
temp=`echo "$line" | sed -n 's/.*img.*src="\([^"]\+\).*/\1/p'`;
|
||||
if [ "$temp" != "" ]; then
|
||||
thumbnail="$BASE$temp"
|
||||
mode="find_cat"
|
||||
fi
|
||||
elif [ "$mode" == "find_cat" ]; then
|
||||
if [ "`echo \"$line\" | grep 'mw-normal-catlinks'`" != "" ]; then
|
||||
mode="cat";
|
||||
fi
|
||||
elif [ "$mode" == "cat" ]; then
|
||||
temp=`echo "$line" | sed -n 's/.*title="Category:\([^"]\+\).*/\1/pg' | grep -v 'page does not exist'`
|
||||
if [ "$temp" != "" ]; then
|
||||
if [ "$categories" != "" ]; then
|
||||
categories="$categories,"
|
||||
fi
|
||||
categories="$categories\"$temp\""
|
||||
fi
|
||||
fi
|
||||
done
|
||||
IFS=" ";
|
||||
|
||||
echo "\"categories\": [$categories],"
|
||||
echo "\"image\": \"$thumbnail\","
|
||||
echo "\"description\": \"$description\""
|
@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
LIFO_SERVER="https://wiki.linux-forks.de"
|
||||
CURLOPTS=( '-b' "/etc/lifomapserver/cookies.txt" )
|
@ -1,64 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
source common.sh
|
||||
|
||||
json=`curl ${CURLOPTS[@]} $LIFO_SERVER'/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=Maps:BodiesOfWater'`
|
||||
data=`echo "$json" | json_reformat | sed -e 's/\\\\n//g' -n -e 's/begin:mapdata\([^}]\+\)/\1/gp' | sed -e "s/|-|/}/g"`
|
||||
|
||||
section=""
|
||||
echo "["
|
||||
export IFS="}"
|
||||
for entry in $data; do
|
||||
this_section=`echo $entry | sed -n 's/.*== \([^=]\+\) ==.*/\1/p'`
|
||||
if [[ "$this_section" != "" ]]; then
|
||||
section=$this_section
|
||||
fi
|
||||
|
||||
if [[ "$section" != "$1" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$section" in
|
||||
"Rivers")
|
||||
name=`echo "$entry" | sed -n 's/\s*\([^|]\+\).*/\1/p' | sed 's/ $//'`
|
||||
type=`echo "$entry" | sed -n 's/\s*\([^|]\+\)||\s*\([^|]\+\).*/\2/p' | sed 's/ $//'`
|
||||
coord=`echo "$entry" | sed -n 's/.*||\s*\([^|]\+\).*/\1/p'`
|
||||
if [[ "$name" != "" && "$coord" != "" ]]; then
|
||||
echo "{ \"type\": \"Feature\",
|
||||
\"geometry\": {
|
||||
\"type\": \"LineString\",
|
||||
\"coordinates\": [
|
||||
$coord
|
||||
]
|
||||
},
|
||||
\"properties\": {
|
||||
\"name\": \"$name\",
|
||||
\"type\": \"$type\"
|
||||
}
|
||||
},"
|
||||
fi
|
||||
;;
|
||||
"Oceans, Seas, and Lakes")
|
||||
name=`echo "$entry" | sed -n 's/\s*\([^|]\+\).*/\1/p' | sed 's/ $//'`
|
||||
type=`echo "$entry" | sed -n 's/\s*\([^|]\+\)||\s*\([^|]\+\).*/\2/p' | sed 's/ $//'`
|
||||
coord=`echo "$entry" | sed -n 's/.*||\s*\([^|]\+\).*/\1/p'`
|
||||
if [[ "$name" != "" && "$coord" != "" ]]; then
|
||||
echo "{ \"type\": \"Feature\",
|
||||
\"geometry\": {
|
||||
\"type\": \"Polygon\",
|
||||
\"coordinates\": [[
|
||||
$coord
|
||||
]]
|
||||
},
|
||||
\"properties\": {
|
||||
\"name\": \"$name\",
|
||||
\"type\": \"$type\"
|
||||
}
|
||||
},"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
export IFS=" "
|
||||
echo "{}"
|
||||
echo "]"
|
@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
source common.sh
|
||||
|
||||
json=`curl ${CURLOPTS[@]} $LIFO_SERVER'/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=Maps:Cities'`
|
||||
data=`echo "$json" | json_reformat | sed -e 's/\\\\n//g' -n -e 's/begin:mapdata\([^}]\+\)/\1/gp' | sed -e "s/|-|/}/g"`
|
||||
|
||||
echo "["
|
||||
export IFS="}"
|
||||
for entry in $data; do
|
||||
name=`echo "$entry" | sed -n 's/\s*\([^|]\+\).*/\1/p' | sed 's/ $//'`
|
||||
type=`echo "$entry" | sed -n 's/\s*\([^|]\+\)||\s*\([^|]\+\).*/\2/p' | sed 's/ $//'`
|
||||
coord=`echo "$entry" | sed -n 's/.*||\s*\([^|]\+\).*/\1/p'`
|
||||
if [[ "$type" == "district" ]]; then
|
||||
continue;
|
||||
fi
|
||||
if [[ "$name" != "" && "$coord" != "" ]]; then
|
||||
echo "{ \"type\": \"Feature\",
|
||||
\"geometry\": {
|
||||
\"type\": \"Polygon\",
|
||||
\"coordinates\": [[
|
||||
$coord
|
||||
]]
|
||||
},
|
||||
\"properties\": {
|
||||
\"name\": \"$name\",
|
||||
\"type\": \"$type\"
|
||||
}
|
||||
},"
|
||||
fi
|
||||
done
|
||||
export IFS=" "
|
||||
echo "{}"
|
||||
echo "]"
|
@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# WARNING: This script is not yet production ready. The slightest error in the wikipage can throw it off. Handle with care.
|
||||
|
||||
source common.sh
|
||||
|
||||
json=`curl ${CURLOPTS[@]} $LIFO_SERVER'/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=Maps:Streets'`
|
||||
data=`echo "$json" | json_reformat | sed -e 's/\\\\n//g' -n -e 's/begin:mapdata\([^}]\+\)/\1/gp' | sed -e "s/|-|/}/g"`
|
||||
|
||||
echo "["
|
||||
export IFS="}"
|
||||
for entry in $data; do
|
||||
name=`echo "$entry" | sed -n 's/\s*\([^|]\+\).*/\1/p' | sed 's/ $//'`
|
||||
coord=`echo "$entry" | sed -n 's/.*||\s*\([^|]\+\).*/\1/p'`
|
||||
if [[ "$name" != "" && "$coord" != "" ]]; then
|
||||
echo "{ \"type\": \"Feature\",
|
||||
\"geometry\": {
|
||||
\"type\": \"LineString\",
|
||||
\"coordinates\": [
|
||||
$coord
|
||||
]
|
||||
},
|
||||
\"properties\": {
|
||||
\"name\": \"$name\"
|
||||
}
|
||||
},"
|
||||
fi
|
||||
done
|
||||
export IFS=" "
|
||||
echo "{}"
|
||||
echo "]"
|
@ -1,68 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
source common.sh
|
||||
|
||||
json=`curl ${CURLOPTS[@]} $LIFO_SERVER'/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=Maps:Trainlines'`
|
||||
data=`echo "$json" | json_reformat | sed -e 's/\\\\n//g' -n -e 's/begin:mapdata\([^}]\+\)/\1/gp' | sed -e "s/|-|/}/g"`
|
||||
|
||||
section=""
|
||||
echo "["
|
||||
export IFS="}"
|
||||
for entry in $data; do
|
||||
this_section=`echo $entry | sed -n 's/.*== \([^=]\+\) ==.*/\1/p'`
|
||||
if [[ "$this_section" != "" ]]; then
|
||||
section=$this_section
|
||||
fi
|
||||
|
||||
if [[ "$section" != "$1" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$section" in
|
||||
"Train Lines")
|
||||
name=`echo "$entry" | sed -n 's/\s*\([^|]\+\).*/\1/p' | sed 's/ $//'`
|
||||
start=`echo "$entry" | sed -n 's/\s*\([^|]\+\)||\s*\([^|]\+\).*/\2/p' | sed 's/ $//'`
|
||||
end=`echo "$entry" | sed -n 's/\s*\([^|]\+\)||\([^|]\+\)||\s*\([^|]\+\).*/\3/p' | sed 's/ $//'`
|
||||
coord=`echo "$entry" | sed -n 's/.*||\s*\([^|]\+\).*/\1/p'`
|
||||
if [[ "$name" != "" && "$coord" != "" ]]; then
|
||||
echo "{ \"type\": \"Feature\",
|
||||
\"geometry\": {
|
||||
\"type\": \"LineString\",
|
||||
\"coordinates\": [
|
||||
$coord
|
||||
]
|
||||
},
|
||||
\"properties\": {
|
||||
\"name\": \"$name\",
|
||||
\"start\": \"$start\",
|
||||
\"end\": \"$end\"
|
||||
}
|
||||
},"
|
||||
fi
|
||||
;;
|
||||
"Access Paths")
|
||||
name=`echo "$entry" | sed -n 's/\s*\([^|]\+\).*/\1/p' | sed 's/ $//'`
|
||||
lines=`echo "$entry" | sed -n 's/\s*\([^|]\+\)||\s*\([^|]\+\).*/\2/p' | sed 's/ $//'`
|
||||
coord=`echo "$entry" | sed -n 's/.*||\s*\([^|]\+\).*/\1/p'`
|
||||
if [[ "$type" == "district" ]]; then
|
||||
continue;
|
||||
fi
|
||||
if [[ "$name" != "" && "$coord" != "" ]]; then
|
||||
echo "{ \"type\": \"Feature\",
|
||||
\"geometry\": {
|
||||
\"type\": \"LineString\",
|
||||
\"coordinates\": [
|
||||
$coord
|
||||
]
|
||||
},
|
||||
\"properties\": {
|
||||
\"name\": \"$lines:$name\"
|
||||
}
|
||||
},"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
export IFS=" "
|
||||
echo "{}"
|
||||
echo "]"
|
@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
source common.sh
|
||||
|
||||
function fetch() {
|
||||
if [[ "$3" != "" ]]; then
|
||||
fn="$3"
|
||||
else
|
||||
fn="$1"
|
||||
fi
|
||||
"./fetch_$1.sh" "$2" | json_reformat -m > "$fn.json.tmp"
|
||||
rm -f "$fn.json"
|
||||
mv "$fn.json.tmp" "$fn.json"
|
||||
}
|
||||
|
||||
fetch streets
|
||||
fetch city_outlines
|
||||
fetch trainlines "Train Lines"
|
||||
fetch trainlines "Access Paths" trainlines_access
|
||||
fetch bodiesofwater "Rivers" rivers
|
||||
fetch bodiesofwater "Oceans, Seas, and Lakes" oceans
|
Loading…
Reference in New Issue
Block a user