2020-04-19 09:12:17 +02:00
var editor _mode = 0 ;
2020-04-17 21:47:12 +02:00
var mymap ;
2020-04-25 13:08:14 +02:00
var polyconf _show _street _names = 5 ; // Zoom level for when to start showing street names
var polyconf _show _cities = 5 ; /* City outlines will be filled on this level and further away */
var polyconf _show _districts = 4 ; /* Shown from polyconf_show_cities until this*/
2022-01-30 10:51:19 +01:00
var polyconf _show _oceans = 5 ; // Show ocean labels from zoom level
2020-05-05 19:50:47 +02:00
var dijkstraserv _base = "https://notsyncing.net/dijkstra/" ;
2020-04-27 17:49:16 +02:00
var wikiurl _base = "https://wiki.linux-forks.de/mediawiki/index.php/"
2020-05-06 17:42:48 +02:00
var tiles _base = "https://notsyncing.net/maps.linux-forks.de/tiles/"
2020-04-27 17:49:16 +02:00
2020-04-17 16:43:34 +02:00
var streetLabelsRenderer = new L . StreetLabels ( {
collisionFlg : true ,
propertyName : 'name' ,
showLabelIf : function ( layer ) {
2021-12-27 11:53:06 +01:00
switch ( layer . feature . geometry . type ) {
2020-04-25 13:08:14 +02:00
case "LineString" :
if ( mymap . getZoom ( ) <= polyconf _show _street _names )
return false ;
break ;
case "Polygon" :
2022-01-30 10:51:19 +01:00
if ( layer . myName == "Oceans" )
return ( mymap . getZoom ( ) > polyconf _show _oceans ) ;
if ( mymap . getZoom ( ) > polyconf _show _street _names )
2020-04-25 13:08:14 +02:00
return false ;
break ;
default :
2020-04-20 18:39:48 +02:00
return false ;
2020-04-25 13:08:14 +02:00
}
2020-04-20 18:39:48 +02:00
return true ;
2020-04-17 16:43:34 +02:00
} ,
fontStyle : {
2020-04-20 17:57:49 +02:00
dynamicFontSize : true ,
2020-04-20 18:39:48 +02:00
fontSize : 10 ,
2020-04-17 16:43:34 +02:00
fontSizeUnit : "px" ,
2020-04-20 18:39:48 +02:00
lineWidth : 3.0 ,
2020-04-17 16:43:34 +02:00
fillStyle : "black" ,
2021-12-27 11:55:10 +01:00
strokeStyle : "white"
2020-04-17 16:43:34 +02:00
} ,
} ) ;
2020-04-19 12:56:02 +02:00
2020-05-05 19:44:54 +02:00
streetLabelsRenderer . _getCollisionFlag = function ( layer ) {
if ( ! ( layer instanceof L . Polygon ) ) // Always check collision for streets
return true ;
zoom = mymap . getZoom ( ) ;
return ( zoom < 5 ) ;
}
2020-04-25 13:08:14 +02:00
streetLabelsRenderer . _getDynamicFontSize = function ( layer ) {
2020-04-20 17:57:49 +02:00
zoom = mymap . getZoom ( ) ;
2020-04-25 13:08:14 +02:00
2021-12-27 11:53:06 +01:00
switch ( layer . myName ) {
case "Oceans" :
return size *= 2.0 / 3 ; ;
2020-04-25 13:08:14 +02:00
break ;
2021-12-27 11:53:06 +01:00
default :
switch ( layer . feature . geometry . type ) {
case "LineString" :
if ( zoom <= 8 )
return 11 ;
else
return 2 * * ( zoom - 9 ) * 11 ;
2020-04-26 17:01:26 +02:00
break ;
2021-12-27 11:53:06 +01:00
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 ;
2020-04-26 17:01:26 +02:00
default :
break ;
}
2020-04-25 13:08:14 +02:00
}
return 10 ;
2020-04-20 17:57:49 +02:00
}
2020-04-25 13:08:14 +02:00
var style _outlines = {
radius : 8 ,
fillColor : "#ff7800" ,
color : "black" ,
2020-04-25 13:33:34 +02:00
opacity : 1.0 ,
2020-04-25 13:08:14 +02:00
fillOpacity : 0.5
} ;
2020-04-25 18:08:02 +02:00
var style _streets = {
} ;
2021-02-26 20:08:42 +01:00
var style _trains = {
color : "yellow"
} ;
var style _tech = {
color : "red"
} ;
2021-12-27 11:53:06 +01:00
var style _rivers = {
2022-01-30 10:51:19 +01:00
color : "blue" ,
fillColor : "#00999955" ,
} ;
var style _oceans = {
color : "#00556655" ,
fillColor : "#00999955" ,
2021-12-27 11:53:06 +01:00
} ;
2020-05-05 19:50:47 +02:00
var style _route = {
radius : 8 ,
fillColor : "#00ff00" ,
color : "red" ,
opacity : 1.0 ,
fillOpacity : 0.5
} ;
2020-04-20 17:57:49 +02:00
2020-04-15 01:08:31 +02:00
// Projection fix from: https://gis.stackexchange.com/questions/200865/leaflet-crs-simple-custom-scale
2020-04-17 16:14:57 +02:00
var factorx = 1 / 256 * 4 ;
2020-04-15 01:08:31 +02:00
var factory = factorx ;
2020-04-19 07:38:41 +02:00
var originx = 7000 + 8 + 0.5 ;
var originy = 7000 + 8 - 0.5 ;
2020-04-15 01:08:31 +02:00
var zoom _level _real = 6 ;
L . CRS . pr = L . extend ( { } , L . CRS . Simple , {
2020-04-17 16:14:57 +02:00
projection : L . Projection . LonLat ,
transformation : new L . Transformation ( factorx , factorx * originx , - factory , factory * originy ) ,
scale : function ( zoom ) {
return Math . pow ( 2 , zoom ) ;
} ,
zoom : function ( scale ) {
return Math . log ( scale ) / Math . LN2 ;
} ,
distance : function ( latlng1 , latlng2 ) {
var dx = latlng2 . lng - latlng1 . lng
, dy = latlng2 . lat - latlng1 . lat ;
return Math . sqrt ( dx * dx + dy * dy ) ;
} ,
infinite : true
2020-04-15 01:08:31 +02:00
} ) ;
// Init map
2020-04-17 21:47:12 +02:00
mymap = L . map ( 'mapid' , {
2020-04-17 16:43:34 +02:00
renderer : streetLabelsRenderer ,
2020-04-17 21:47:12 +02:00
editable : true ,
2020-04-17 16:14:57 +02:00
crs : L . CRS . pr
2020-04-25 13:08:14 +02:00
} ) . setView ( [ 0 , 0 ] , 5 ) ;
2020-04-15 01:08:31 +02:00
var mapheight = 16384 ;
var mapwidth = mapheight ;
var sw = mymap . unproject ( [ 0 , 0 ] , zoom _level _real ) ;
var ne = mymap . unproject ( [ mapwidth , mapheight ] , zoom _level _real ) ;
2020-04-17 16:14:57 +02:00
var layerbounds = new L . LatLngBounds ( sw , ne ) ;
2020-04-15 01:08:31 +02:00
var layers = L . control . layers ( { } , { } ) . addTo ( mymap ) ;
function load _svg ( name , url , active = 1 ) {
2020-04-17 16:14:57 +02:00
var xhttp _ps = new XMLHttpRequest ( ) ;
xhttp _ps . onreadystatechange = function ( ) {
if ( this . readyState == 4 ) {
if ( this . status == 200 ) {
var svgElement = document . createElementNS ( "http://www.w3.org/2000/svg" , "svg" ) ;
svgElement . setAttribute ( 'xmlns' , "http://www.w3.org/2000/svg" ) ;
svgElement . setAttribute ( 'viewBox' , "0 0 16384 16384" ) ;
svgElement . innerHTML = xhttp _ps . responseText ;
var svgElementBounds = [ [ 0 , 0 ] , [ 1000 , 1000 ] ] ;
var overlay = L . svgOverlay ( svgElement , svgElementBounds ) ;
layers . addOverlay ( overlay , name ) ;
if ( active )
overlay . addTo ( mymap ) ;
return overlay ;
} else {
alert ( "Error: Could not load SVG map layer (" + name + ")" ) ;
}
}
2020-04-15 01:08:31 +02:00
}
2020-04-17 16:14:57 +02:00
;
xhttp _ps . open ( "GET" , url , true ) ;
xhttp _ps . send ( ) ;
2020-04-15 01:08:31 +02:00
}
function load _tiles ( name , id ) {
2020-05-06 17:42:48 +02:00
var url = "" ;
if ( name != "" ) {
url = tiles _base + '{id}/{z}/{y}/{x}.png' ;
}
2021-12-27 11:55:10 +01:00
var satellite = new L . TileLayer ( url , {
2020-04-17 21:47:12 +02:00
maxZoom : 14 /*8*/ ,
2020-04-17 16:14:57 +02:00
maxNativeZoom : 6 ,
minNativeZoom : 0 ,
minZoom : 0 ,
noWrap : true ,
2020-04-27 17:49:16 +02:00
attribution : 'Map data © <a href="' + wikiurl _base + 'Maps">Linux-Forks</a>' ,
2020-04-17 16:14:57 +02:00
id : id ,
tileSize : 256 ,
zoomOffset : 0 ,
opacity : 1.0 ,
bounds : layerbounds
} ) ;
layers . addBaseLayer ( satellite , name ) ;
return satellite ;
2020-04-15 01:08:31 +02:00
}
2020-04-25 13:08:14 +02:00
var current _location = "" ;
var current _feature = null ;
2021-12-27 11:54:29 +01:00
var current _layer = null ;
2020-04-27 17:37:12 +02:00
function load _geojson ( name , url , geotype , iconcolor , active = 1 , style = { } ) {
2020-04-17 16:14:57 +02:00
var xhttp _ps = new XMLHttpRequest ( ) ;
xhttp _ps . onreadystatechange = function ( ) {
if ( this . readyState == 4 ) {
if ( this . status == 200 ) {
2020-04-25 13:08:14 +02:00
onEachFeature = null ;
pointToLayer = null ;
filter = null ;
2020-04-27 17:37:12 +02:00
switch ( geotype ) {
2020-04-17 16:43:34 +02:00
case "street" :
2021-02-26 20:08:42 +01:00
case "train" :
2020-04-25 13:08:14 +02:00
onEachFeature = function ( feature , layer ) {
2020-04-27 17:37:12 +02:00
layer . myTag = geotype ;
2020-04-26 17:02:14 +02:00
layer . myName = name ;
2021-02-26 20:08:42 +01:00
if ( geotype == "train" )
layer . no _search = true
2020-04-25 13:08:14 +02:00
layer . on ( "click" , function ( e ) {
2021-12-27 11:54:29 +01:00
current _layer = layer ;
2020-04-25 13:08:14 +02:00
current _feature = feature ;
} ) ;
} ;
break ;
case "outline" :
onEachFeature = function ( feature , layer ) {
2020-04-27 17:37:12 +02:00
layer . myTag = geotype ;
2020-04-25 13:08:14 +02:00
layer . myName = name ;
layer . on ( "click" , function ( e ) {
current _location = feature . properties . name ;
} ) ;
}
2020-04-17 16:43:34 +02:00
break ;
default : /* else it is a marker with the specified icon */
onEachFeature = function ( feature , layer ) {
2021-12-27 11:53:06 +01:00
layer . myName = name ;
2020-04-17 16:43:34 +02:00
label = String ( feature . properties . name )
2020-04-27 17:49:16 +02:00
layer . bindPopup ( '<h1><a target="_blank" href="' + wikiurl _base + feature . properties . name + '">' + feature . properties . name + '</a> (' + feature . geometry . coordinates + ')</h1>' + '<p><img style="width:100%" src="' + feature . properties . image + '"></p>' + '<p>' + feature . properties . description + '</p>' ) ;
2020-04-17 16:43:34 +02:00
layer . bindTooltip ( label , {
permanent : true ,
direction : "center" ,
className : "city-names"
2020-04-19 09:12:37 +02:00
} ) . openTooltip ( ) . on ( 'click' , jump _to _marker ) ;
2020-04-17 16:43:34 +02:00
} ;
pointToLayer = function ( feature , latlng ) {
label = String ( feature . properties . name )
2020-04-27 17:37:12 +02:00
if ( geotype == "auto" ) {
iconname = "star" ; // default icon
iconcolor = "orange" ;
for ( var i = 0 ; i < feature . properties . categories . length ; i ++ ) {
category = feature . properties . categories [ i ] . toLowerCase ( ) ;
switch ( category ) {
case "stations" :
iconname = "train" ;
iconcolor = "blue" ;
break ;
case "shops" :
iconname = "shopping-cart" ;
iconcolor = "green" ;
break ;
case "city" :
case "village" :
case "town" :
case "settlements" :
iconname = "city" ;
iconcolor = "red" ;
break ;
case "parks" :
iconname = "tree" ;
iconcolor = "green" ;
break ;
case "courts" :
iconname = "balance-scale" ;
iconcolor = "black" ;
break ;
case "train depots" :
iconname = "wrench" ;
iconcolor = "violet" ;
break ;
case "hotels" :
iconname = "hotel" ;
iconcolor = "gray" ;
break ;
case "beaches" :
iconname = "umbrella-beach" ;
iconcolor = "orange" ;
break ;
2020-05-05 19:48:27 +02:00
case "waterway" :
iconname = "water" ;
iconcolor = "blue" ;
break ;
2020-04-27 17:37:12 +02:00
}
if ( iconname != "star" )
break ;
}
} else {
iconname = geotype ;
}
marker = new L . marker ( latlng , {
2020-04-17 16:43:34 +02:00
icon : L . AwesomeMarkers . icon ( {
icon : iconname ,
markerColor : iconcolor
} )
} ) . bindTooltip ( label , {
permanent : false ,
direction : "center" ,
opacity : 0.7
} ) . openTooltip ( ) ;
2020-04-27 17:37:12 +02:00
return marker ;
2020-04-17 16:43:34 +02:00
} ;
break ;
}
2020-04-19 07:38:41 +02:00
var json = JSON . parse ( xhttp _ps . responseText ) ;
2020-04-25 13:08:14 +02:00
geojson = L . geoJSON ( json , {
2020-04-17 16:43:34 +02:00
style : style ,
onEachFeature : onEachFeature ,
2020-04-25 13:08:14 +02:00
pointToLayer : pointToLayer ,
filter : filter
2020-04-17 16:14:57 +02:00
} ) ;
layers . addOverlay ( geojson , name ) ;
2020-04-25 13:08:14 +02:00
2020-04-17 16:14:57 +02:00
if ( active )
geojson . addTo ( mymap ) ;
return geojson ;
} else {
2020-04-17 22:00:36 +02:00
console . log ( "Error: Could not load geojson map layer (" + name + ")." ) ;
2020-04-17 16:14:57 +02:00
}
}
2020-04-15 01:08:31 +02:00
}
2020-04-17 16:14:57 +02:00
;
xhttp _ps . open ( "GET" , url , true ) ;
xhttp _ps . send ( ) ;
2020-04-15 01:08:31 +02:00
}
2021-02-26 20:09:27 +01:00
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' ) ;
2020-05-06 17:42:48 +02:00
load _tiles ( "None" , '' ) ;
2020-04-15 01:08:31 +02:00
2020-04-27 17:37:12 +02:00
load _geojson ( "All" , "./geojson/all.json" , "auto" , "auto" , 0 ) ;
load _geojson ( "Streets" , "./geojson/streets.json" , "street" , "auto" , 1 , style _streets ) ;
2021-11-02 17:12:24 +01:00
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 ) ;
2021-02-26 20:09:14 +01:00
load _geojson ( "Railroad Tracks" , "./geojson/trains.json" , "train" , "auto" , 0 , style _trains ) ;
2020-04-27 17:37:12 +02:00
load _geojson ( "Cities" , "./geojson/city_outlines.json" , "outline" , "auto" , 1 , style _outlines ) ;
2021-12-27 11:53:06 +01:00
load _geojson ( "Rivers" , "./geojson/rivers.json" , "street" , "auto" , 1 , style _rivers ) ;
2022-01-30 10:51:19 +01:00
load _geojson ( "Oceans" , "./geojson/oceans.json" , "outline" , "auto" , 1 , style _oceans ) ;
2020-04-15 01:08:31 +02:00
2021-02-26 20:13:02 +01:00
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 ( ) ;
2020-04-15 01:08:31 +02:00
L . control . scale ( ) . addTo ( mymap ) ;
2020-04-25 17:21:38 +02:00
function resolve _latlng ( latlng , recenter = 0 ) {
latlng . lng = Math . round ( latlng . lng ) ;
latlng . lat = Math . round ( latlng . lat ) ;
return latlng ;
}
2020-04-19 09:12:17 +02:00
function get _current _location _str ( ) {
2020-04-25 17:21:38 +02:00
var latlng = resolve _latlng ( mymap . getCenter ( ) ) ;
return latlng . lng + "," + latlng . lat + "," + mymap . getZoom ( ) ;
2020-04-19 09:12:17 +02:00
}
/* Important: Do not use mymap.setView, use this function instead */
function jump _to ( latlng , zoom = - 1 ) {
if ( zoom == - 1 )
zoom = mymap . getZoom ( ) ;
2020-04-25 17:21:38 +02:00
if ( ! editor _mode ) {
pos = resolve _latlng ( latlng ) ;
document . location . hash = "#" + pos . lng + "," + pos . lat + "," + zoom ;
} else {
2020-04-19 10:45:26 +02:00
mymap . setView ( latlng , zoom ) ;
2020-04-25 17:21:38 +02:00
}
2020-04-19 09:12:17 +02:00
}
function jump _to _marker ( e ) {
2020-04-19 10:45:26 +02:00
jump _to ( e . target . getLatLng ( ) ) ;
2020-04-19 09:12:17 +02:00
}
function prompt _location ( ) {
var str = prompt ( "Enter coordinates to jump to:\n\n" +
"Format: x, y [, zoom]" , get _current _location _str ( ) ) ;
2020-04-19 17:00:01 +02:00
if ( str ) {
if ( ! editor _mode )
document . location . hash = "#" + str ;
else
onHashChange ( null , "#" + str ) ;
}
2020-04-19 09:12:17 +02:00
}
2020-04-19 12:56:02 +02:00
var search _element ;
2020-05-05 19:50:47 +02:00
var route _element ;
function build _sidebar ( ) {
2020-04-19 12:56:02 +02:00
if ( ! search _element ) {
search _element = document . createElement ( "div" ) ;
search _element . style . overflow = "scroll" ;
search _element . style . padding = "6px" ;
search _element . style . height = "100%" ;
2020-05-05 19:50:47 +02:00
search _element . innerHTML = '<input style="width:100%;" id="search_query" name="lifo_map_search" type="search" placeholder="Start typing to search..." oninput="search(event)"><div id="search_results"></div>' ;
}
if ( ! route _element ) {
route _element = document . createElement ( "div" ) ;
route _element . style . overflow = "scroll" ;
route _element . style . padding = "6px" ;
route _element . style . height = "100%" ;
2021-02-26 20:08:42 +01:00
route _element . innerHTML = '<a href="#" onclick="toggle_search(\'search\' , 1 ) ; return false ; " > & 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 ) < / l a b e l > < b r > \
< input id = "route_submit" type = "button" style = "width:100%;" value = "Go!" onclick = "route(event)" > < div id = "route_results" > < / d i v > ' ;
2020-05-05 19:50:47 +02:00
}
}
var current _sidebar = "search" ;
function toggle _search ( type = current _sidebar , force _act = 0 ) {
if ( el = document . getElementById ( 'sidebar' ) ) {
el . parentNode . removeChild ( el ) ;
if ( force _act == 0 && type == current _sidebar )
return ;
2020-04-19 12:56:02 +02:00
}
td = document . getElementById ( 'windowtr' ) . insertCell ( 0 ) ;
td . style . width = "400px" ;
td . style . borderRight = "1px solid black" ;
td . style . verticalAlign = "top" ;
2020-05-05 19:50:47 +02:00
td . id = "sidebar" ;
switch ( type ) {
case "search" :
td . appendChild ( search _element ) ;
document . getElementById ( 'search_query' ) . select ( ) ;
break ;
case "route" :
td . appendChild ( route _element ) ;
break ;
default :
alert ( "JS error: sidebar" ) ;
break ;
}
current _sidebar = type ;
2020-04-19 12:56:02 +02:00
}
function htmlEntities ( str ) {
return String ( str ) . replace ( /&/g , '&' ) . replace ( /</g , '<' ) . replace ( />/g , '>' ) . replace ( /"/g , '"' ) ;
}
2020-04-19 23:09:26 +02:00
function polyline _get _middle _coords ( coords ) {
var ret = [ 2 ] ;
ret [ 0 ] = coords [ 0 ] [ 0 ] + ( coords [ coords . length - 1 ] [ 0 ] - coords [ 0 ] [ 0 ] ) / 2 ;
ret [ 1 ] = coords [ 0 ] [ 1 ] + ( coords [ coords . length - 1 ] [ 1 ] - coords [ 0 ] [ 1 ] ) / 2 ;
return ret ;
}
2020-04-19 23:28:54 +02:00
var highlighted _line ;
var default _street _color = "#3388ff" ;
2020-04-27 17:37:12 +02:00
2020-04-19 12:56:02 +02:00
function search ( e ) {
2020-04-20 18:40:22 +02:00
var query = document . getElementById ( "search_query" ) . value ;
2020-04-27 17:37:12 +02:00
var real _query = true ;
2020-04-19 20:21:13 +02:00
document . getElementById ( 'search_results' ) . innerHTML = "" ;
2020-04-25 17:34:33 +02:00
if ( true ) {
2020-04-27 17:37:12 +02:00
if ( query . length == 0 ) {
real _query = false ;
2020-04-25 17:34:33 +02:00
query = "!@#$%^&" ; // Cheap workaround to (hopefully) match nothing
2020-04-27 17:37:12 +02:00
}
2020-04-19 12:56:02 +02:00
results = document . createElement ( "ul" ) ;
for ( var i = 0 ; i < layers . _layers . length ; i ++ ) {
if ( ! layers . _layers [ i ] . layer . _layers )
continue ;
for ( key in layers . _layers [ i ] . layer . _layers ) {
item = layers . _layers [ i ] . layer . _layers [ key ] ;
2021-02-26 20:08:42 +01:00
if ( item . hasOwnProperty ( "no_search" ) )
break ;
2020-04-19 12:56:02 +02:00
switch ( item . feature . geometry . type ) {
case "Point" :
regex = new RegExp ( query , 'i' ) ;
if ( item . feature . properties . name . match ( regex ) ) {
el = document . createElement ( "li" ) ;
2020-04-20 18:40:22 +02:00
el . innerHTML = "[" + layers . _layers [ i ] . name + "] " + '<a href="#" onclick="layers._layers[' + i + '].layer._layers[' + item . _leaflet _id + '].fire(\'click\'); return false;">' + htmlEntities ( item . feature . properties . name ) + "</a>" ;
2020-04-19 12:56:02 +02:00
results . appendChild ( el ) ;
2020-04-27 17:37:12 +02:00
item . setOpacity ( 1.0 ) ; // TODO: setOpacity does not disable hover and click events
} else {
if ( real _query )
item . setOpacity ( 0.0 ) ; // TODO
else
item . setOpacity ( 1.0 ) ; // TODO
2020-04-19 12:56:02 +02:00
}
break ;
2020-04-19 23:09:26 +02:00
case "LineString" :
2020-04-19 23:28:54 +02:00
if ( item . options . color != default _street _color ) { // De-hilight last search
item . options . color = default _street _color ;
item . redraw ( ) ;
}
2020-04-19 23:09:26 +02:00
regex = new RegExp ( query , 'i' ) ;
2020-04-19 23:28:54 +02:00
2020-04-19 23:09:26 +02:00
if ( item . feature . properties . name . match ( regex ) ) {
2020-04-19 23:28:54 +02:00
item . options . color = "#FF0000" ;
item . redraw ( ) ;
2020-04-19 23:09:26 +02:00
el = document . createElement ( "li" ) ;
zpos = polyline _get _middle _coords ( item . feature . geometry . coordinates ) ;
2020-04-20 18:40:22 +02:00
el . innerHTML = "[" + layers . _layers [ i ] . name + "] " + '<a href="#" onclick="latLng2 = L.latLng(' + zpos [ 1 ] + ',' + zpos [ 0 ] + '); jump_to(latLng2); return false;">' + htmlEntities ( item . feature . properties . name ) + "</a>" ;
2020-04-19 23:09:26 +02:00
results . appendChild ( el ) ;
}
break ;
2020-04-25 13:33:13 +02:00
case "Polygon" :
regex = new RegExp ( query , 'i' ) ;
if ( item . feature . properties . name . match ( regex ) ) {
el = document . createElement ( "li" ) ;
2020-04-25 17:21:38 +02:00
zpos = resolve _latlng ( layers . _layers [ i ] . layer . _layers [ item . _leaflet _id ] . getCenter ( ) ) ;
el . innerHTML = "[" + layers . _layers [ i ] . name + "] " + '<a href="#" onclick="latLng2 = L.latLng(' + zpos . lat + ',' + zpos . lng + '); jump_to(latLng2, ' + polyconf _show _cities + '); return false;">' + htmlEntities ( item . feature . properties . name ) + "</a>" ;
2020-04-25 13:33:13 +02:00
results . appendChild ( el ) ;
}
break ;
2020-04-19 12:56:02 +02:00
default :
break ;
}
}
}
document . getElementById ( 'search_results' ) . appendChild ( results ) ;
}
2020-04-19 20:21:13 +02:00
return false ;
2020-04-19 12:56:02 +02:00
}
2020-05-05 19:50:47 +02:00
var route _layer ;
function route ( e ) // BOOKMARK
2021-12-27 11:55:10 +01:00
{
2020-05-05 19:50:47 +02:00
if ( route _layer ) {
mymap . removeLayer ( route _layer ) ;
}
start = document . getElementById ( 'route_start' ) . value ;
destination = document . getElementById ( 'route_destination' ) . value ;
if ( ( start == "" ) || ( destination == "" ) ) {
document . getElementById ( 'route_results' ) . innerHTML = "" ;
return ;
}
document . getElementById ( 'route_submit' ) . disabled = true ;
document . getElementById ( 'route_results' ) . innerHTML = "Loading..." ;
var xhttp _ps = new XMLHttpRequest ( ) ;
xhttp _ps . onreadystatechange = function ( ) {
if ( this . readyState == 4 ) {
if ( this . status == 200 ) {
var json = JSON . parse ( xhttp _ps . responseText ) ;
geojson = L . geoJSON ( json , {
style : style _route
} ) ;
route _layer = geojson . addTo ( mymap ) ;
str = "<ol>" ;
last _through = "" ;
geojson . eachLayer ( function ( layer ) {
if ( last _through != layer . feature . properties . through ) {
2021-02-26 20:08:42 +01:00
str += '<li><a href="#" onclick="latLng2 = L.latLng(' + layer . feature . geometry . coordinates [ 0 ] [ 1 ] + ',' + layer . feature . geometry . coordinates [ 0 ] [ 0 ] + '); jump_to(latLng2); return false;">' + htmlEntities ( layer . feature . properties . description ) . replace ( '[T]' , '🚆️' ) + "</a></li>" ;
2020-05-05 19:50:47 +02:00
last _through = layer . feature . properties . through ;
}
} ) ;
str += "</ol>" ;
document . getElementById ( 'route_results' ) . innerHTML = str ;
} else {
document . getElementById ( 'route_results' ) . innerHTML = "No results." ;
}
document . getElementById ( 'route_submit' ) . disabled = false ;
}
} ;
coordstr = start + ';' + destination ;
xhttp _ps . open ( "GET" , dijkstraserv _base + coordstr , true ) ;
xhttp _ps . send ( ) ;
}
function set _route _start ( latlng ) {
toggle _search ( "route" , 1 ) ;
document . getElementById ( 'route_start' ) . value = latlng . lat + ',' + latlng . lng ;
route ( ) ;
}
function set _route _destination ( latlng ) {
toggle _search ( "route" , 1 ) ;
document . getElementById ( 'route_destination' ) . value = latlng . lat + ',' + latlng . lng ;
route ( ) ;
}
2020-04-19 09:12:17 +02:00
L . MyControl = L . Control . extend ( {
options : {
position : 'topleft' ,
callback : null ,
kind : '' ,
html : ''
} ,
onAdd : function ( map ) {
var container = L . DomUtil . create ( 'div' , 'leaflet-control leaflet-bar' ) ,
link = L . DomUtil . create ( 'a' , '' , container ) ;
link . href = '#' ;
link . title = this . options . title ;
link . innerHTML = this . options . html ;
2020-05-08 17:18:10 +02:00
L . DomEvent . on ( link , 'mousedown' , L . DomEvent . stop ) ;
L . DomEvent . on ( link , 'mouseup' , L . DomEvent . stop ) ;
2020-04-19 09:12:17 +02:00
L . DomEvent . on ( link , 'click' , L . DomEvent . stop )
2020-06-11 10:54:14 +02:00
. on ( link , 'click' , function ( ) {
window . LAYER = this . options . callback . call ( ) ;
} , this ) ;
return container ;
2020-04-19 09:12:17 +02:00
}
} ) ;
2020-04-19 12:56:02 +02:00
L . SearchControl = L . MyControl . extend ( {
options : {
position : 'topleft' ,
callback : toggle _search ,
title : 'Search' ,
html : '🔍'
}
} ) ;
2020-04-19 09:12:17 +02:00
L . GotoControl = L . MyControl . extend ( {
options : {
position : 'topleft' ,
callback : prompt _location ,
2020-04-19 20:36:58 +02:00
title : 'Jump to coordinates' ,
2020-04-19 09:12:17 +02:00
html : '⌖'
}
} ) ;
2020-04-19 12:56:02 +02:00
mymap . addControl ( new L . SearchControl ( ) ) ;
2020-04-19 09:12:17 +02:00
mymap . addControl ( new L . GotoControl ( ) ) ;
2020-06-14 12:02:32 +02:00
L . CurrentPosControl = L . Control . extend ( {
options : {
position : 'bottomleft' ,
callback : null ,
kind : "" ,
html : ''
} ,
onAdd : function ( map ) {
container = L . DomUtil . create ( 'div' , 'leaflet-control-scale leaflet-bar' ) ;
container . style . visibility = "hidden" ;
div = L . DomUtil . create ( 'div' , '' , container ) ;
div . style . backgroundColor = "white" ;
div . style . paddingLeft = "4px" ;
div . style . paddingRight = "4px" ;
div . style . borderRadius = "2px" ;
div . style . margin = "2px" ;
div . style . opacity = "0.6" ;
div . style . fontWeight = "bold" ;
div . innerHTML = "" ;
div . id = "current_position_label" ;
return container ;
}
} ) ;
mymap . addControl ( new L . CurrentPosControl ( ) ) ;
2020-04-15 01:08:31 +02:00
var popup = L . popup ( ) ;
L . AwesomeMarkers . Icon . prototype . options . prefix = 'fa' ;
var baseballIcon = L . AwesomeMarkers . icon ( {
2020-04-17 16:14:57 +02:00
icon : 'coffee' ,
markerColor : 'red'
2020-04-15 01:08:31 +02:00
} ) ;
2021-12-27 11:54:29 +01:00
function escapeHtml ( text ) {
return text
. replace ( /&/g , "&" )
. replace ( /</g , "<" )
. replace ( />/g , ">" )
. replace ( /"/g , """ )
. replace ( /'/g , "'" ) ;
}
2020-04-15 01:08:31 +02:00
function onMapClick ( e ) {
2020-04-25 13:08:14 +02:00
var addinfo = "" ;
2020-05-05 19:50:47 +02:00
pos = resolve _latlng ( e . latlng ) ;
route _links = '<br><a href="#" onclick="latLng2 = L.latLng(' + pos . lng + ',' + pos . lat + '); set_route_start(latLng2); return false;">[route from here]</a>' ;
route _links += ' <a href="#" onclick="latLng2 = L.latLng(' + pos . lng + ',' + pos . lat + '); set_route_destination(latLng2); return false;">[route to here]</a>' ;
2020-04-25 13:08:14 +02:00
if ( current _location != "" )
2021-12-27 11:54:29 +01:00
addinfo = " (part of <a target=\"_blank\" href=\"" + wikiurl _base + encodeURIComponent ( current _location ) + "\">" + escapeHtml ( current _location ) + "</a>)" ;
2020-04-25 13:08:14 +02:00
if ( current _feature ) {
2021-12-27 11:54:29 +01:00
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 ) ;
2020-04-25 13:08:14 +02:00
} else {
2020-05-05 19:50:47 +02:00
popup . setLatLng ( e . latlng ) . setContent ( "You clicked the map at " + pos . lng + "," + pos . lat + addinfo + route _links ) . openOn ( mymap ) ;
2020-04-25 13:08:14 +02:00
}
current _feature = null ;
2021-12-27 11:54:29 +01:00
current _layer = null ;
2020-04-25 13:08:14 +02:00
current _location = "" ;
2020-04-15 01:08:31 +02:00
}
mymap . on ( 'click' , onMapClick ) ;
2020-04-19 09:12:17 +02:00
2020-04-19 10:45:26 +02:00
var is _user _drag = 0 ;
2020-04-19 09:12:17 +02:00
function update _hash _from _position ( e ) {
2020-04-19 10:45:26 +02:00
if ( is _user _drag )
is _user _drag = 0 ;
else
return ;
if ( ! editor _mode )
document . location . hash = "#" + get _current _location _str ( ) ;
2020-04-19 09:12:17 +02:00
}
2020-04-19 10:45:26 +02:00
function dragstart ( e ) {
is _user _drag = 1 ;
}
2020-04-20 00:02:28 +02:00
function update _aa _status ( ) {
if ( mymap . getZoom ( ) > zoom _level _real )
document . getElementById ( 'mapid' ) . classList . add ( "no-aa" ) ;
else
document . getElementById ( 'mapid' ) . classList . remove ( "no-aa" ) ;
}
2020-04-20 18:39:48 +02:00
function update _street _width ( ) {
zoom = mymap . getZoom ( ) ;
var w ;
if ( zoom <= 6 ) {
w = 2 ;
} else {
w = 2 * * zoom * 0.016 * 2 ;
}
var myStyle = { weight : w , opacity : 0.7 } ;
2020-04-26 17:02:14 +02:00
mymap . eachLayer ( function ( layer ) {
if ( layer . myTag && layer . myTag === "street" ) {
layer . setStyle ( myStyle ) ;
}
} ) ;
2020-04-20 18:39:48 +02:00
}
2020-04-25 13:08:14 +02:00
function update _outline _visibility ( ) {
zoom = mymap . getZoom ( ) ;
mymap . eachLayer ( function ( layer ) {
if ( layer . myTag && layer . myTag === "outline" ) {
2020-04-25 13:33:34 +02:00
var fillOpacity ;
2020-04-25 13:08:14 +02:00
if ( zoom <= polyconf _show _cities )
2020-04-25 13:33:34 +02:00
fillOpacity = 0.5 ;
2020-04-25 13:08:14 +02:00
//else if (zoom == polyconf_show_cities + 1)
// opacity = 0.2;
else
2020-04-25 13:33:34 +02:00
fillOpacity = 0.0 ;
2020-04-25 13:08:14 +02:00
2020-04-25 13:33:34 +02:00
layer . setStyle ( { fillOpacity : fillOpacity } ) ;
2020-04-25 13:08:14 +02:00
}
} ) ;
}
2020-06-14 12:02:32 +02:00
function update _current _mouse _position ( e ) {
var lbl = document . getElementById ( 'current_position_label' ) ;
if ( e . type == "mouseout" ) {
lbl . parentElement . style . visibility = "hidden" ;
return ;
}
lbl . parentElement . style . visibility = "visible" ;
pos = resolve _latlng ( e . latlng ) ;
lbl . innerHTML = pos . lng + "," + pos . lat ;
}
2020-04-19 10:45:26 +02:00
mymap . on ( 'zoomend' , function ( ) { is _user _drag = 1 ; update _hash _from _position ( ) ; } ) ;
2020-04-20 00:02:28 +02:00
mymap . on ( 'zoomend' , update _aa _status ) ;
2020-04-20 18:39:48 +02:00
mymap . on ( 'zoomend' , update _street _width ) ;
2020-04-25 13:08:14 +02:00
mymap . on ( 'zoomend' , update _outline _visibility ) ;
2020-04-19 10:45:26 +02:00
mymap . on ( 'moveend' , update _hash _from _position ) ;
mymap . on ( 'dragstart' , function ( ) { is _user _drag = 1 ; } ) ;
mymap . on ( 'keydown' , function ( e ) { if ( e . originalEvent . code . match ( /Arrow.*/ ) ) is _user _drag = 1 ; } ) ;
2020-04-25 13:08:14 +02:00
mymap . on ( 'overlayadd' , function ( e ) { update _street _width ( ) ; update _outline _visibility ( ) ; } ) ;
2020-06-14 12:02:32 +02:00
mymap . on ( 'mousemove' , update _current _mouse _position ) ;
mymap . on ( 'mouseout' , update _current _mouse _position ) ;
2020-04-26 17:55:32 +02:00
2020-04-19 17:00:01 +02:00
function onHashChange ( e , hash = null ) {
if ( ! hash )
hash = document . location . hash ;
2020-04-27 17:37:12 +02:00
if ( hash == "" )
return ;
2020-04-19 17:00:01 +02:00
if ( hash == "#" + get _current _location _str ( ) )
2020-04-19 09:12:17 +02:00
return ; // We're already there
2020-04-26 17:55:32 +02:00
coordstr = decodeURIComponent ( hash . slice ( 1 ) ) . split ( "," ) ;
2020-04-19 09:12:17 +02:00
if ( coordstr . length < 2 )
coordstr . push ( 0 ) ; // Default y
if ( coordstr . length < 3 )
coordstr . push ( mymap . getZoom ( ) ) ; // Default zoom
2020-04-19 17:07:07 +02:00
var latlng = L . latLng ( parseFloat ( coordstr [ 1 ] ) , parseFloat ( coordstr [ 0 ] ) ) ;
2020-04-19 09:12:17 +02:00
mymap . setView ( latlng , parseInt ( coordstr [ 2 ] ) ) ;
2020-04-26 17:55:32 +02:00
if ( coordstr . length > 3 ) { /* Drop named marker */
foo = L . marker ( latlng ) . bindPopup ( htmlEntities ( coordstr [ 3 ] ) ) . addTo ( mymap ) . openPopup ( ) ;
}
2020-04-19 09:12:17 +02:00
}
2020-04-19 12:56:02 +02:00
2020-05-05 19:50:47 +02:00
build _sidebar ( ) ;
2020-04-19 09:12:17 +02:00
window . addEventListener ( "hashchange" , onHashChange , false ) ;
onHashChange ( null ) ;