Newer
Older
routemap / umappop.js
@HIROSE Yuuji HIROSE Yuuji on 3 Sep 2018 7 KB Add map web generated from geomapper.py
/*
 * Emulate uMap notation in your map
 */
var umappop =
    umappop||
    function(a)
{

var colors = ["red", "green", "blue", "purple", "yellow", "cyan", "magenta"]
function wikiRepl(s) {
    return s.replace(/{{(.*)\|([0-9][0-9]*)}}/g,
		     '<img class="popup" src="$1" width="$2">').
	replace(/{{(.*)}}/g, '<img class="popup" src="$1">').
	replace(/\[\[(.*)\|(.*)\]\]/g, '<a href="$1">$2</a>').
	replace(/\[\[(.*)\]\]/g, '<a href="$1">$1</a>').
	replace(/^### (.*)/, '<h4>$1</h4>').
	replace(/^## (.*)/, '<h3>$1</h4>').
	replace(/^# (.*)/, '<h2>$1</h4>');
}
// https://codepen.io/KryptoniteDove/post/load-json-file-locally-using-pure-javascript
function loadgeofile(arg, callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', arg['file'], true);
    xobj.onreadystatechange = function () {
	if (xobj.readyState == 4 && xobj.status == "200") {
	    callback(arg, xobj.responseText);
	}
    };
    xobj.send(null);
}
function escapeHtml(str) {
    return str.replace(/&/g, '&amp;').
	replace(/</g, '&lt;').
	replace(/>/g, '&gt;').
	replace(/\"/g, '&quot;').
	replace(/'/g, '&#39;');
}
function bindPopUp(feature, layer) {
    var altattrs = ["住所", "電話番号", "筆者", "撮影者"]
    var d = feature.properties.description||feature.properties.desc||'';
    var r = "", term;
    for (var i=0; i<altattrs.length; i++) {
	term = altattrs[i];
	if (feature.properties[term])
	    r += "<dt>"+ term + "</dt>\n" +
	    "<dd>"+feature.properties[term]+"</dd>\n";
    }
    layer.bindPopup(
	"<h2>"+feature.properties.name + "</h2>\n" +
	    "<p>"+wikiRepl(d)+"</p>\n<dl>"+
	    wikiRepl(r)+"</dl>\n"
    );
}

function init(logfiles) {
    if (!logfiles[0]) {
	logfiles = [logfiles];
    }
    var baseLayer = {};
    var map_osm = new L.tileLayer(			// OpenStretMap
	'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution : '&copy; <a href="//osm.org/copyright">OpenStreetMap</a> contributors | Generated with <a href="//www.gentei.org/~yuuji/software/geomapper/">geomapper</a>'
	});
    baseLayer["OpenStreetMap"] = map_osm;
    
    var map_gsi = new L.tileLayer( 			// 国土地理院
	'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
	    attribution: "<a href='//www.gsi.go.jp/kikakuchousei/kikakuchousei40182.html' target='_blank'>国土地理院</a>"
	});
    baseLayer["地理院地図"] = map_gsi;

    var map_ort = new					// 地理院オルソ
    L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg', {
	attribution: "<a href='http://www.gsi.go.jp/kikakuchousei/kikakuchousei40182.html' target='_blank'>国土地理院</a>"
    });
    baseLayer["地理院地図オルソ画像"] = map_ort;
    var map_gazo = new L.tileLayer(			// 地理院画像1974-1978
	'https://cyberjapandata.gsi.go.jp/xyz/gazo1/{z}/{x}/{y}.jpg', {
	attribution: "<a href='http://www.gsi.go.jp/kikakuchousei/kikakuchousei40182.html' target='_blank'>国土地理院</a>"
    });
    baseLayer["地理院画像(1974-1978)"] = map_gazo;

    if (L.BingLayer) {
	var bing_key =
	    "AjyiuTOpH-_ZQdW4bvsPnNsjKBQQ6n59nrXj92ccHqwvKgiDHJxmo1tEJHs3w70K";
	map_bing = new L.BingLayer(			// BingMap
	    bing_key, {type: "Road", culture: "ja"});
	baseLayer["Bing Map"] = new L.BingLayer(
	    bing_key, {type: "Road", culture: "ja"});
	baseLayer["Bing Map 衛星写真"] = new L.BingLayer(
	    bing_key, {type: "Aerial", culture: "ja"});
	baseLayer["Bing Map 衛星写真+ラベル"] = new L.BingLayer(
	    bing_key, {type: "AerialWithLabels", culture: "ja"});
    }
    if (L.Google) {
	baseLayer["Google Map"] = new L.Google("ROADMAP");
	baseLayer["Google Map 衛星写真"] = new L.Google('SATELLITE');
	baseLayer["Google Map 衛星写真+ラベル"] = new L.Google('HYBRID');
    }

    var map = L.map('map', {layers: [map_osm]});
    var mapControl = L.control.layers(baseLayer, null).addTo(map);
    var sakuraicon = L.icon({
	iconUrl: 'sakura-icon.jpg',
    });
    var markerLayers = L.featureGroup();
    var centermarker;
    var fileptn = /\.o?(gpx|csv|kml|geojson|topojson|polyline|umap)/i;
    for (var i=0; i<logfiles.length; i++) {
	var arg = logfiles[i];
	var file = arg['file'], color=(arg['color']||'blue');
	var fnmatch = fileptn.exec(file);
	if (fnmatch) {
	    loadgeofile(arg, function(arg, text) {
		var filename = arg['file'], color=arg['color']
		var ext = fileptn.exec(filename)[1].toLowerCase() //extension
		var geojson, umap=[], title, name, jsonLayer;
		var style = {color: color, opacity: 0.7}
		switch (ext) {
		case 'gpx':
		case 'kml':
		    var xml = (new DOMParser()).parseFromString(
			text, 'text/xml');
		    //alert((new XMLSerializer()).serializeToString(xml))
		    geojson = ((ext=="gpx")
			       ? toGeoJSON.gpx : toGeoJSON.kml)(xml);
		    var names = xml.getElementsByTagName("name");
		    for (var i=0; i<names.length; i++) {
			// Detecting GEO file's own "name": attribute
			name = names[i].parentNode.tagName;
			if (name && name.match(/gpx|Document|metadata|trk/i)) {
			    title = names[i].textContent;
			    break;
			}
		    }
		    geojson["name"] = title
		    umap = {"layers": [geojson]}; // Fake .umap
		    break;
		case 'csv': case 'topojson': case 'polyline':
		    // jsonLayer = omnivore.csv.parse(text);
		    alert("NOT Support "+ext+" yet..."); return;
		    break;
		case 'geojson':
		    geojson = JSON.parse(text);
		    umap = {"layers": [geojson]}; // Fake .umap
		    break;
		case 'umap':
		    umap = JSON.parse(text);
		}
		for (i=0; i < umap["layers"].length; i++) {
		    geojson = umap["layers"][i];
		    if (geojson["_storage"]) { // Maybe from .umap file
			title = geojson._storage["name"];
		    } else {
			title = geojson.name || filename;
		    }
		    jsonLayer = L.geoJson(geojson, {
			style: function(feature) {return style;},
			onEachFeature: function(feature, layer) {
			    // alert(feature.properties.name);
			    // Do not bind POPup if feature has no name
			    feature.properties &&
				feature.properties.name &&
				bindPopUp(feature, layer);
			}});
		    jsonLayer.addTo(map);
		    markerLayers.addLayer(jsonLayer)
		    // .gpx.parse() is NOT asynchronous.  So "ready" won't be fired
		    //if (markerLayers.getLatLng().length > 1)
		    map.fitBounds(markerLayers.getBounds());
		    //else
		    //    map.setView(markerLayers.getLatLngs()[0], 13);
		    mapControl.addOverlay(jsonLayer, title);
		}
	    });
	}
    }				// End of logfiles loop
    L.control.scale().addTo(map);

    function round(n, d) {
	return Math.round(n * Math.pow(10, d))/Math.pow(10, d);
    }
    var latlngform = document.getElementById("latlng");
    function displayLatLng(lat, lon) {
	lat = round(lat, 5); lon = round(lon, 5);
	latlngform.textContent = lat+", "+lon;
    }
    
    map.on('contextmenu', function(e) {
	if (e.originalEvent.shiftKey) {
	} else {
	    centermarker && map.removeLayer(centermarker);
	    displayLatLng(e.latlng.lat, e.latlng.lng);
	    centermarker = L.marker(e.latlng, {title: 'foo', draggable:true}).addTo(map)
	    centermarker.on('dragend', function(e) {
		var la = e.target._latlng.lat, lo = e.target._latlng.lng;
		displayLatLng(la, lo);
	    });
	    map.panTo(e.latlng)
	    return false;
	}
    });
    // Marker in the CENTER position
}  /* End of init() */

init(a);		/* Call from toplevel */
}