Compare commits

...

66 Commits

Author SHA1 Message Date
Markus Koch fb7d445e54 scripts: Add authentication support for Wiki queries 2022-05-12 19:11:17 +02:00
Markus Koch 6519c019c9 htdocs: Make oceans less eye-searing 2022-01-30 10:51:19 +01:00
Markus Koch b2f543f49b htdocs: Editorials 2021-12-27 11:55:10 +01:00
Markus Koch 66e80778a9 htdocs: Link streets, cities, rivers, oceans, ... to the wiki 2021-12-27 11:54:29 +01:00
Markus Koch b5fd6aab1f htdocs: Add basic support for the wet stuff 2021-12-27 11:53:06 +01:00
Markus Koch 76570e5369 htdocs: Remove beta label from train geogson filenames 2021-11-02 17:12:24 +01:00
Markus Koch e4689aeb56 htdocs: geojson: Include train lines and water stuff 2021-11-02 16:58:19 +01:00
Markus Koch 4625d4e25b scripts: Modify map script to download and convert all available maps 2021-11-02 16:45:22 +01:00
Markus Koch 50d9ee43b0 lifo-dijkstraserv: Update repository URL 2021-05-23 11:42:05 +02:00
Markus Koch 215e607cb7 scripts: Fix geotype for bodies of water 2021-03-22 18:30:50 +01:00
Markus Koch 7a52d5bb59 scripts: Add train lines and bodies of water to update_all.sh 2021-03-22 18:01:32 +01:00
Markus Koch b888dbe3f4 scripts: Add fetch_bodiesofwater.sh 2021-03-22 18:01:05 +01:00
Markus Koch 6cc5cb8b4b scripts: Add fetch_trainlines.sh 2021-03-13 18:49:23 +01:00
Markus Koch 034bef5e2a scripts: Fix typo 2021-03-13 10:43:23 +01:00
Markus Koch 8c7825d121 scripts: Add script to easily convert the latest map 2021-03-13 10:27:07 +01:00
Markus Koch a91175fdd8 htdocs: Add script to auto-refresh streets etc. 2021-02-26 20:13:02 +01:00
Markus Koch 76c0056c87 htdocs: Update currently available tilemaps 2021-02-26 20:09:27 +01:00
Markus Koch db561b5d1d htdocs: Add trainlines to geojson list 2021-02-26 20:09:14 +01:00
Markus Koch 8a4a455e05 htdocs: Add trainline support 2021-02-26 20:08:42 +01:00
Markus Koch 1bd7cb1160 htdocs: Fix dependencies 2021-02-26 20:08:17 +01:00
Markus Koch 3b41beec7b htdocs: Update title to include [beta] 2021-02-26 20:05:30 +01:00
Markus Koch 447cd904c4 Merge branch 'dev' of git.notsyncing.net:markus/lifomapserver into dev 2021-02-26 19:56:05 +01:00
Markus Koch d67439efd6 Update to latest lifo-dijkstraserv
Trainlines update.
2021-02-26 19:55:41 +01:00
Markus Koch 314f0da3be Removing leading <br> paragraph
Technically, this is an error in the data (aka MediaWiki), but w/e...
2021-02-09 22:19:04 +01:00
Markus Koch f36d3cf0e7 Update to the latest version of lifo-dijkstraserv 2021-02-04 23:53:17 +01:00
Markus Koch fcc26a7fa5 Add mouse coordinate display to bottom left 2020-06-14 12:02:32 +02:00
Markus Koch 134d70dc9f Fix indentation 2020-06-11 10:54:14 +02:00
Markus Koch cf5dccbc3a Fix button behavior in editor
Stop event propagation of mouse up / down events.
2020-05-08 17:18:10 +02:00
Markus Koch e936b0c35b Add vector data only mode (map none) 2020-05-06 17:42:48 +02:00
Markus Koch 92ab599d75 Add directions support through lifo-dijkstraserv 2020-05-05 19:50:47 +02:00
Markus Koch f1105ccc45 Add waterway symbols 2020-05-05 19:48:27 +02:00
Markus Koch b0adb91c69 Make street label collision flag a function 2020-05-05 19:47:57 +02:00
Markus Koch 2054d66191 Fix property name check in streetlabels 2020-05-05 19:44:05 +02:00
Markus Koch 3610b8b610 Merge branch 'dev' of git.notsyncing.net:markus/lifomapserver into dev 2020-05-02 14:17:49 +02:00
Markus Koch 3d0afc953e Extract categories, description, and thumbnail from rendered HTML pages 2020-04-30 18:29:53 +02:00
Markus Koch 806348e676 Clean up links, open links in new tab 2020-04-27 17:49:16 +02:00
Markus Koch 9bdb4095a7 Merge branch 'dev' of git.notsyncing.net:markus/lifomapserver into dev 2020-04-27 17:38:25 +02:00
Markus Koch 05238dc5ae Add categories for markers
This commit obsoletes the many fetch scripts and combines them
into a single script, creating a single json, but with category
information.
2020-04-27 17:38:19 +02:00
Markus Koch 4d2fc5e739 Ignore districts for now
They are not yet implemented on the map and would only clutter
the map.
2020-04-26 23:07:43 +02:00
Markus Koch c7c4975a57 Optimize font sizes for city outlines 2020-04-26 18:48:18 +02:00
Markus Koch 2e67f22044 Add optional markers for direct location links 2020-04-26 17:55:32 +02:00
Markus Koch ff716d1036 Add script to update all Maps:-based jsons 2020-04-26 17:30:59 +02:00
Markus Koch 916914d4e9 Update gitignore to exclude .json files in scripts/ 2020-04-26 17:29:46 +02:00
Markus Koch a1c50a3cfb Move Maps:-based scripts to separate directory 2020-04-26 17:28:37 +02:00
Markus Koch 98cd0c8fe9 Properly quote in fetch scripts 2020-04-26 17:22:44 +02:00
Markus Koch 2f02ca1d2a Trigger update_street_width functionality only on streets 2020-04-26 17:02:14 +02:00
Markus Koch 1ddb724140 Give cities, towns, and villages different font sizes 2020-04-26 17:01:26 +02:00
Markus Koch 1292c1a573 Change title and footer 2020-04-25 18:19:39 +02:00
Markus Koch f7000d1c5c Correct instructions 2020-04-25 18:16:16 +02:00
Markus Koch 4aa26434f8 Fix restart through clearing the coordinate list 2020-04-25 18:14:28 +02:00
Markus Koch 777905e7f1 Press escape in the editor to stop drawing 2020-04-25 18:08:23 +02:00
Markus Koch 035eb5a992 Add editor styling
This function is only partially working atm. It only applies
the style when resuming an existing dataset. When starting
from scratch, the default style will be used.
2020-04-25 18:08:02 +02:00
Markus Koch 5b5ce97a1a Fix search behavior
Before, it was always searching for the current term without
the last entered (or with the last deleted) character. This
behavior is fixed now. Also, an empty query will now match
(hopefully) nothing instead of everything.
2020-04-25 17:34:33 +02:00
Markus Koch d229044ebf Fix coordinate order on popover, clean up resolve_latlng 2020-04-25 17:21:38 +02:00
Markus Koch 6a779db77b Add city outline fetcher script 2020-04-25 17:08:19 +02:00
Markus Koch f17bf1ebb0 Remove necessity for php tile resolution script
The conversion script now generates a proper directory
structure with z/y/x coords in the path.
2020-04-25 16:43:55 +02:00
Markus Koch 105dc4d3da Add tile ID conversion php file 2020-04-25 15:56:50 +02:00
Markus Koch a4c7833d87 Clean up 2020-04-25 13:33:34 +02:00
Markus Koch 6ceae7d7c2 Add polygons (city outlines) to search results 2020-04-25 13:33:13 +02:00
Markus Koch 771704bf15 Add basic support for city outlines
Use with load_geojson(
	"Cities (outline, demo)",
	"./geojson/cities_demo.json",
	"outline",
	"black",
	1,
	style_outlines);
2020-04-25 13:08:14 +02:00
Markus Koch 3cb3078820 Add editor mode for polygons 2020-04-20 18:51:10 +02:00
Markus Koch ae47583e2d Fix searh for terms and results including HTML chars 2020-04-20 18:40:22 +02:00
Markus Koch cfeafc11d9 Update street width depending on zoom level 2020-04-20 18:39:48 +02:00
Markus Koch 26972c366e Render labels for polygons 2020-04-20 18:01:32 +02:00
Markus Koch 4c5f7f9a85 Do not show label on path for polygons 2020-04-20 18:01:14 +02:00
Markus Koch b9986f0b42 Scale street labels depending on zoom level 2020-04-20 17:57:49 +02:00
27 changed files with 952 additions and 187 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
htdocs/tiles/**/
scripts/geojson/*.json
scripts/geojson/**/*.json

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[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
htdocs/awesomemarkers Submodule

@ -0,0 +1 @@
Subproject commit 4fcacdfc82ed58f0173062851a4cda713845df82

1
htdocs/fa Submodule

@ -0,0 +1 @@
Subproject commit fcec2d1b01ff069ac10500ac42e4478d20d21f4c

16
htdocs/geojson/update.php Normal file
View File

@ -0,0 +1,16 @@
<?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.";
}
?>

19
htdocs/geojson/update_all.sh Executable file
View File

@ -0,0 +1,19 @@
#!/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

View File

@ -1,14 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>LinuxWorks Minetest Map (unofficial)</title>
<title>LinuxWorks Minetest Map [beta]</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/leaflet.awesome-markers.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/leaflet.awesome-markers.js"></script>
<script src="awesomemarkers/dist/leaflet.awesome-markers.js"></script>
<!-- Streets -->
<script src='leafletjs/ctxtextpath.js'></script>
<script src='leafletjs/L.LabelTextCollision.js'></script>
@ -48,7 +48,7 @@
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
}
</style>
<script src="mapscript.js"></script>
<script src="mapscript.js?v3"></script>
<script src="streeteditor.js"></script>
</body>
</html>

View File

@ -42,8 +42,7 @@ L.StreetLabels = L.LabelTextCollision
_text: function (ctx, layer) {
if (layer && layer.feature && layer.feature.properties && layer.feature.properties[this.options.propertyName] !== 'undefined') {
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;
@ -80,10 +79,8 @@ L.StreetLabels = L.LabelTextCollision
ctx.lineWidth = this.options.fontStyle.lineWidth;
var fontSize = this.options.fontStyle.fontSize;
if (this._map && this.options.fontStyle.dynamicFontSize === true) {
fontSize = this._getDynamicFontSize();
fontSize = this._getDynamicFontSize(layer.feature);
}
ctx.font = fontSize + this.options.fontStyle.fontSizeUnit + " 'Helvetica Neue',Helvetica,Arial,sans-serif";
@ -97,8 +94,7 @@ L.StreetLabels = L.LabelTextCollision
L.point(p.x + offsetX, p.y + offsetY), L.point(
textWidth, textHeight));
if (this.options.collisionFlg) {
if (this._getCollisionFlag(layer)) {
for (var index in this._textList) {
var pointBounds = this._textList[index];
if (pointBounds.intersects(bounds)) {
@ -109,7 +105,6 @@ L.StreetLabels = L.LabelTextCollision
this._textList.push(bounds);
ctx.fillStyle = this.options.fontStyle.fillStyle;
ctx.strokeStyle = this.options.fontStyle.strokeStyle;
@ -117,8 +112,7 @@ L.StreetLabels = L.LabelTextCollision
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);
}
if (layer instanceof L.Polyline) {
} else if (layer instanceof L.Polyline) {
/**
* Render text alongside the polyline
* **/
@ -131,7 +125,7 @@ L.StreetLabels = L.LabelTextCollision
if (layer._parts) {
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.lineWidth = 3;
//ctx.lineWidth = 3;
layer._parts.forEach(function (part) {
//Build the points list for the first part
var pathPoints = [];
@ -148,6 +142,10 @@ L.StreetLabels = L.LabelTextCollision
}
},
_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
@ -185,7 +183,7 @@ L.StreetLabels = L.LabelTextCollision
return polyline;
},
_getDynamicFontSize: function () {
_getDynamicFontSize: function (layer) {
return parseInt(this._map.getZoom());
},

View File

@ -1,21 +1,136 @@
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) {
return layer.geometry.type == "LineString";
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: false,
dynamicFontSize: true,
fontSize: 10,
fontSizeUnit: "px",
lineWidth: 4.0,
lineWidth: 3.0,
fillStyle: "black",
strokeStyle: "white",
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;
@ -49,7 +164,7 @@ mymap = L.map('mapid', {
renderer: streetLabelsRenderer,
editable: true,
crs: L.CRS.pr
}).setView([0, 0], 6);
}).setView([0, 0], 5);
var mapheight = 16384;
var mapwidth = mapheight;
@ -85,13 +200,17 @@ function load_svg(name, url, active=1) {
}
function load_tiles(name, id) {
var satellite = L.tileLayer('https://notsyncing.net/maps.linux-forks.de/tiles/?id={id}&z={z}&x={x}&y={y}', {
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 &copy; <a href="https://wiki.linux-forks.de/mediawiki/index.php/Maps">Linux-Forks</a>, ' + 'All rights reserved, ',
attribution: 'Map data &copy; <a href="' + wikiurl_base + 'Maps">Linux-Forks</a>',
id: id,
tileSize: 256,
zoomOffset: 0,
@ -102,20 +221,46 @@ function load_tiles(name, id) {
return satellite;
}
function load_geojson(name, url, iconname, iconcolor, active=1, style={}) {
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) {
switch (iconname) {
onEachFeature = null;
pointToLayer = null;
filter = null;
switch (geotype) {
case "street":
onEachFeature = null;
pointToLayer = null;
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 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.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",
@ -124,7 +269,59 @@ function load_geojson(name, url, iconname, iconcolor, active=1, style={}) {
};
pointToLayer = function(feature, latlng) {
label = String(feature.properties.name)
return new L.marker(latlng,{
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
@ -134,16 +331,19 @@ function load_geojson(name, url, iconname, iconcolor, active=1, style={}) {
direction: "center",
opacity: 0.7
}).openTooltip();
return marker;
};
break;
}
var json = JSON.parse(xhttp_ps.responseText);
var geojson = L.geoJSON(json, {
geojson = L.geoJSON(json, {
style: style,
onEachFeature: onEachFeature,
pointToLayer: pointToLayer
pointToLayer: pointToLayer,
filter: filter
});
layers.addOverlay(geojson, name);
if (active)
geojson.addTo(mymap);
return geojson;
@ -157,36 +357,53 @@ function load_geojson(name, url, iconname, iconcolor, active=1, style={}) {
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_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_svg("Test", "./overlay.svg", 0);
load_geojson("Cities", "./geojson/cities.json", "city", "red");
load_geojson("Stations", "./geojson/stations.json", "train", "blue");
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");
load_geojson("Streets", "./geojson/streets.json", "street", "blue", 0);
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 = mymap.getCenter();
return Math.round(latlng.lng) + "," + Math.round(latlng.lat) + "," + mymap.getZoom();
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)
document.location.hash = "#" + Math.round(latlng.lng) + "," + Math.round(latlng.lat) + "," + zoom;
else
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) {
@ -205,28 +422,57 @@ function prompt_location() {
}
var search_element;
function toggle_search() {
if (el = document.getElementById('searchbar')) {
el.parentNode.removeChild(el);
return;
}
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..." onkeypress="search(event)"><div id="search_results"></div>' ;
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;">&lt;-- 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 = "searchbar";
td.appendChild(search_element);
document.getElementById('search_query').focus();
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) {
@ -242,10 +488,16 @@ function polyline_get_middle_coords(coords) {
var highlighted_line;
var default_street_color = "#3388ff";
function search(e) {
var query = htmlEntities(document.getElementById("search_query").value);
var query = document.getElementById("search_query").value;
var real_query = true;
document.getElementById('search_results').innerHTML = "";
if (query.length > 0 || e.key == "Enter") {
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)
@ -253,13 +505,21 @@ function search(e) {
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;">' + item.feature.properties.name + "</a>";
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":
@ -270,12 +530,21 @@ function search(e) {
regex = new RegExp(query, 'i');
if (item.feature.properties.name.match(regex)) {
console.log(item.options.color);
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;">' + item.feature.properties.name + "</a>";
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;
@ -289,6 +558,67 @@ function search(e) {
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',
@ -303,11 +633,13 @@ L.MyControl = L.Control.extend({
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;
.on(link, 'click', function () {
window.LAYER = this.options.callback.call();
}, this);
return container;
}
});
@ -330,6 +662,31 @@ L.GotoControl = L.MyControl.extend({
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';
@ -338,8 +695,30 @@ var baseballIcon = L.AwesomeMarkers.icon({
markerColor: 'red'
});
function escapeHtml(text) {
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
function onMapClick(e) {
popup.setLatLng(e.latlng).setContent("You clicked the map at " + e.latlng.toString()).openOn(mymap);
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);
@ -366,25 +745,81 @@ function update_aa_status() {
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 = hash.slice(1).replace(/%20/g, "").split(",");
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);

View File

@ -3,16 +3,20 @@ 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;
function resolve_latlng(latlng, recenter = 0) {
latlng.lng = Math.round(latlng.lng);
latlng.lat = Math.round(latlng.lat);
return latlng;
}
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
@ -23,7 +27,10 @@ if (editor_mode) {
else
polyline.editor.continueBackward();
} else {
polyline = mymap.editTools.startPolyline();
if (editor_mode_polygon)
polyline = mymap.editTools.startPolygon();
else
polyline = mymap.editTools.startPolyline();
}
}
@ -53,11 +60,11 @@ if (editor_mode) {
if (interactive) {
str = prompt("Instructions: \n" +
"* Click the scribble-icon in the top left to start or continue drawing.\n" +
"* Double click last waypoint to stop.\n" +
"* Double click a waypoint to delete it.\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)
if (str == undefined)
return;
} else {
str = window.location.hash.slice(1);
@ -73,7 +80,10 @@ if (editor_mode) {
for (var i = 0; i < coords.length; i++) {
coords[i] = [coords[i][1], coords[i][0]];
}
polyline = L.polyline(coords).addTo(mymap);
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) {
@ -93,12 +103,24 @@ if (editor_mode) {
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 = polyline.getLatLngs();
var latlngs;
if (editor_mode_polygon)
latlngs = polyline.getLatLngs()[0];
else
latlngs = polyline.getLatLngs();
var str = "";
for (var i = 0; i < latlngs.length; i++) {
@ -112,6 +134,8 @@ if (editor_mode) {
}
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());
}
@ -133,10 +157,12 @@ if (editor_mode) {
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(map.editTools);
}, this);
.on(link, 'click', function (e) {
window.LAYER = this.options.callback.call(map.editTools);
}, this);
return container;
}
});

View File

@ -1,3 +0,0 @@
<?php
?>

1
lifo-dijkstraserv Submodule

@ -0,0 +1 @@
Subproject commit faa5d7ca4b9b16442de4bd3c3cc49567cfd56598

62
scripts/convert_all.sh Executable file
View File

@ -0,0 +1,62 @@
#!/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

View File

@ -11,8 +11,8 @@
# `convert $MAPFILE -extent ${crop}x${crop} -gravity NorthWest $MAPFILE.scaled.png`
TILESIZE=256
MAPNAME="world-2020-04-09"
MAPFILE="../$MAPNAME.png"
MAPNAME="$1"
MAPFILE="$2"
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/%05d.png
convert $tempfile -crop ${TILESIZE}x${TILESIZE} +adjoin $out/%d.png
rm $tempfile
@ -51,3 +51,16 @@ 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
}
}
}

View File

@ -1,30 +0,0 @@
fetch_category () {
echo "Fetching $1" > /dev/stderr
json=`curl "https://wiki.linux-forks.de/mediawiki/api.php?action=query&format=json&list=categorymembers&cmtitle=Category:$1&cmlimit=max" 2>/dev/null`
cities=`echo "$json" | json_reformat | sed -n 's/.*"title":\s*"\([^"]*\).*/\1/p' | tr ' ' '_' | tr '\n' ' '`
num=`echo $cities | tr ' ' '\n' | wc -l`
i=0
echo "["
for city in $cities; do
let i++
echo -n -e "\rFetched $i/$num" > /dev/stderr
./fetch_single.sh "$city"
done
echo > /dev/stderr
echo "{}]"
}
JSONDIR=../../htdocs/geojson
mkdir -p $JSONDIR
fetch_category Shops > $JSONDIR/shops.json
fetch_category City > $JSONDIR/cities.json
fetch_category Stations > $JSONDIR/stations.json
fetch_category Parks > $JSONDIR/parks.json
fetch_category Libraries > $JSONDIR/libraries.json
fetch_category "CW_Complexes" > $JSONDIR/cw_complexes.json
fetch_category Courts > $JSONDIR/courts.json
fetch_category Waterway > $JSONDIR/waterway.json
fetch_category Train_Depots > $JSONDIR/depots.json

View File

@ -0,0 +1,35 @@
#!/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 "{}]";

View File

@ -1,10 +0,0 @@
#!/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 "{}]"

View File

@ -1,10 +0,0 @@
#!/bin/bash
json=`curl 'https://wiki.linux-forks.de/mediawiki/api.php?action=query&format=json&list=categorymembers&cmtitle=Category:Shops&cmlimit=1000' 2>/dev/null`
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 "{}]"

View File

@ -1,31 +0,0 @@
#!/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" 2>/dev/null | sed -s "s/\\\\\\\\n//g"`
title=`echo $json | sed -n 's/.*"title":\s*"\([^"]\+\).*/\1/p'`
img=$(curl "https://wiki.linux-forks.de/mediawiki/index.php/$1" 2>/dev/null | sed s/\"/\\n/g | grep /thumb/ | head -n 1)
image="https://wiki.linux-forks.de$img"
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=`curl "https://wiki.linux-forks.de/mediawiki/api.php?action=parse&page=$1&section=0&prop=text&format=json" 2>/dev/null | sed -z -n "s/<\/p><p>//g;s/.*<p>\(.*\)<\/p>.*/\1/p" | sed s,\"/mediawiki/index.php,\"https://wiki.linux-forks.de/mediawiki/index.php,g`
if [[ "$coord_x" != "" && "$coord_y" != "" ]]; then
echo "{\
\"type\": \"Feature\",\
\"properties\": {\
\"name\": \"$title\",\
\"amenity\": \"City\",\
\"description\": \"$description\",\
\"image\": \"$image\"\
},\
\"geometry\": {\
\"type\": \"Point\",\
\"coordinates\": [$coord_x, $coord_y]\
}\
},"
fi

View File

@ -1,10 +0,0 @@
#!/bin/bash
json=`curl 'https://wiki.linux-forks.de/mediawiki/api.php?action=query&format=json&list=categorymembers&cmtitle=Category:Stations&cmlimit=1000' 2>/dev/null`
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 "{}]"

View File

@ -0,0 +1,49 @@
#!/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\""

3
scripts/geojson/maps/common.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
CURLOPTS=( '-b' "/etc/lifomapserver/cookies.txt" )

View File

@ -0,0 +1,64 @@
#!/bin/bash
source common.sh
json=`curl ${CURLOPTS[@]} 'https://wiki.linux-forks.de/mediawiki/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 "]"

View File

@ -0,0 +1,34 @@
#!/bin/bash
source common.sh
json=`curl ${CURLOPTS[@]} 'https://wiki.linux-forks.de/mediawiki/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 "]"

View File

@ -2,14 +2,16 @@
# WARNING: This script is not yet production ready. The slightest error in the wikipage can throw it off. Handle with care.
json=`curl 'https://wiki.linux-forks.de/mediawiki/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"`
source common.sh
json=`curl ${CURLOPTS[@]} 'https://wiki.linux-forks.de/mediawiki/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'`
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\": {

View File

@ -0,0 +1,68 @@
#!/bin/bash
source common.sh
json=`curl ${CURLOPTS[@]} 'https://wiki.linux-forks.de/mediawiki/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 "]"

View File

@ -0,0 +1,21 @@
#!/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