Newer
Older
flymap / omnivore / yuza.js
@HIROSE Yuuji HIROSE Yuuji on 16 Sep 2018 10 KB Renamed to "yuza".*
// 例: GeoJSONファイルを leaflet-ajax でロードする

var tmap =
    tmap||
    function()
{
    var colors = ["red", "green", "blue", "purple", "yellow", "cyan", "magenta"]
    var gjl;				// GeoJSON Layer : Globally used
    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 bindPop(feature, layer) {
	var altattrs = ["住所", "電話番号", "筆者", "撮影者"]
	var d = feature.properties.description||feature.properties.desc||'';
	var n = feature.properties.name||'';
	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"
	);
    }

    // HTML要素
    var info	= document.getElementById("info"),
	update	= document.getElementById("update"),
	undobtn	= document.getElementById("undo"),
	loadbtn	= document.getElementById("reload"),
	namefld	= document.getElementById("name"),
	descfld	= document.getElementById("desc"),
	rmbtn	= document.getElementById("remove"),
	gpsbtn	= document.getElementById("gps");
    function dispInfo(msg) {
	info.textContent = msg;
    }
    function modifyFlag(flag) {
	if (flag) {
	    update.style.backgroundColor = 'pink';
	    update.disabled = false;
	} else {
	    update.style.backgroundColor = 'white';
	    undopoint = false;
	    update.disabled = true;
	}
    }
    function updateGJ(json) {
	function respond(str) {
	    if (this.readyState == 4) {
		dispInfo("OK");
	    }
	    modifyFlag(false);
	}
	var newjson = {name: 'yuzasprings', val: json.toGeoJSON()};
	var val = JSON.stringify(newjson);
	if (val) {
	    var conn = new XMLHttpRequest();
	    conn.open('POST', './getgj.cgi');
	    conn.setRequestHeader(
		'Content-Type', 'application/x-www-form-urlencoded');
	    conn.send(val);
	    conn.onreadystatechange = respond;// イベントリスナ登録
	}
    }
    var undopoint = false;
    function undoMarker(e) {
	if (undopoint) {
	    let marker = undopoint.marker,
		latlng = undopoint.latlng;
	    marker.setLatLng(latlng);
	    modifyFlag(false);
	}
    }
    
    // 初期化関数
    function init(logfile) {
	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>',
		maxZoom: 20, maxNativeZoom: 18
	    });
	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>",
		maxZoom: 20, maxNativeZoom: 18
	    });
	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>",
	    maxZoom: 20, maxNativeZoom: 18
	});
	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",
			   maxZoom: 20, maxNativeZoom: 18});
	    baseLayer["Bing Map"] = new L.BingLayer(
		bing_key, {type: "Road", culture: "ja",
			   maxZoom: 20, maxNativeZoom: 18});
	    baseLayer["Bing Map 衛星写真"] = new L.BingLayer(
		bing_key, {type: "Aerial", culture: "ja",
			   maxZoom: 20, maxNativeZoom: 18});
	    var bing_dbl = baseLayer["Bing Map 衛星写真+ラベル"] = new L.BingLayer(
		bing_key, {type: "AerialWithLabels", culture: "ja",
			   maxZoom: 20, maxNativeZoom: 18});
	}
	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 jsonmap = L.map('load-json', {layers: [map_ort]}).setView([38.273295,140.761600], 14);
	var mapControl = L.control.layers(baseLayer, null).addTo(jsonmap);
	var markerLayers = L.featureGroup();

	// GPS related
	var gpsIcon = L.icon({
	    iconUrl: 'img/gpsmark.png',
	    iconAnchor: [12,12]
	});
	var gpsmarker = null;
	function gps_error() {
	    dispInfo("GPS信号取得失敗")
	}
	function gps_success(pos) {
	    dispInfo("GPSお")
	    var latlng = L.latLng([pos.coords.latitude, pos.coords.longitude]);
	    jsonmap.panTo(latlng);		// 地図の中心を取得した位置に
	    if (!gpsmarker)
		gpsmarker = L.marker(latlng, {icon: gpsIcon}).addTo(jsonmap);
	    else
		gpsmarker.setLatLng(latlng);
	    dispInfo(latlng);
	    gpsbtn.disabled = false;
	}
	gpsbtn.addEventListener('click', function() {
	    gpsbtn.disabled = true;
	    dispInfo("位置取得中...");
	    navigator.geolocation.getCurrentPosition(gps_success, gps_error, {
		// enableHighAccuracy: true,
		timeout:	8000,
		maximumAge:	0000,
	    });
	});

	var popupopenmarker = false;
	function updatePopup(e) {
	    var elem = e.target;
	    if (popupopenmarker) {
		let mk = popupopenmarker.marker,
		    pr = popupopenmarker.props;
		pr.name = elem.value;
		let newmk = mk.toGeoJSON();
		newmk.properties.name = elem.value;
		alert(newmk.properties.name);
		gjl.addData(newmk);
		mk.remove();	// 古いマーカを消して入れ直す
		modifyFlag(true);
	    }
	}
	function rmMarker(e) {
	    var elem = e.target;
	    if (popupopenmarker) {
		var mk = popupopenmarker.marker;
		//alert(mk);
		mk.removeFrom(gjl);
		mk.closePopup();
		mk.remove();
		modifyFlag(true);
	    }
	}
	
	var fileptn = /\.o?(gpx|csv|kml|geojson|topojson|polyline|umap)/i;
	// var fnmatch = fileptn.exec(logfile);
	var customLayer = L.geoJson(null, {	// omnivoreに引き渡すGeoJSONレイヤ
	    onEachFeature: function(f, layer) {	// レイヤ上に配置する feature(地点)
		let p = f.properties;		// ごとに、プロパティを取り出し
		if (p) {			// description(概要)を
		    let name = p.name, desc = p.description;
		    let popup = "<h3>" + name + "</h3>" + "<p>" + (desc||"") + "</p>";
		    layer.bindPopup(popup);	// ポップアップに設定する
		    layer.bindTooltip(name);
		    layer.options.draggable = true;
		    layer.on('popupopen', function(e) {	//ポップアップ開く時
			// If this marker is popupped
			//dispInfo(e.target.getPopup().getContent());
			// → <h3>にぎわいの水</h3><p></p>
			namefld.value = p.name;
			descfld.value = p.description||"";
			rmbtn.style.visibility = 'visible';
			popupopenmarker = {marker: layer, props: p};
		    });
		    layer.on('popupclose', function(e) {
			var newname = namefld.value,
			    newdesc = descfld.value,
			    marker  = popupopenmarker.marker;
			var newmarker = marker.toGeoJSON();
			if (newmarker.properties.name != newname
			    || newmarker.properties.description != newdesc) {
			    newmarker.properties.name = newname;
			    newmarker.properties.description = newdesc;
			    marker.remove();
			    gjl.addData(newmarker);
			    modifyFlag(true);
			}
			namefld.value = '';
			descfld.value = '';
			rmbtn.style.visibility = 'hidden';
			popupopenmarker = null;
		    });
		    layer.on('dragstart', function(e) {
			undopoint = undopoint ||
			    {marker: layer, latlng: layer.getLatLng()};
		    });
		    layer.on('dragend', function(e) {
			modifyFlag(true);
		    });
		}
	    }
	});
	
	// geojson外部ファイルの読み込みは次の行
	gjl = omnivore.geojson("./gj/yuzasprings.geojson", null, customLayer);
	// ↑引数は順に: ファイル, 解析オプション, カスタムレイヤ
	update.addEventListener('click', function() {updateGJ(gjl)});
	undobtn.addEventListener('click', function(e) {undoMarker(e)});
	rmbtn.addEventListener('click', rmMarker);
	modifyFlag(false);
	function dispGJ() {
	    var gj = gjl.toGeoJSON();
	    var len = gj.features.length;
	    info.textContent = len + ':' + JSON.stringify(gj);
	}
	gjl.on("ready", function() {	// 'ready' イベントに読み終わったときの処理
	    jsonmap.fitBounds(gjl.getBounds());	// 読み取り失敗時は 'error' イベント
	    dispGJ();
	});
	gjl.addTo(jsonmap);		// マップに足す
	// L.control.layers(baseLayer, {"Triangle": gjl}).addTo(jsonmap);


	
	jsonmap.on('contextmenu', function(e) {
	    if (e.originalEvent.shiftKey) {
	    } else {
		var newmk = L.marker(e.latlng, {
		    title: 'foo',
		    draggable: true}),
		    newgj = newmk.toGeoJSON();
		newmk.remove();
		newgj.properties.name = 'foo';
		newgj.properties.description = 'Point of foo';
		gjl.addData(newgj);
		dispInfo(JSON.stringify(newgj));
		modifyFlag(true);
	    }
	});
	function reloadGJ() {
	    function respond(str) {
		if (this.readyState == 4) {
		    dispInfo("Reload OK");
		    // https://github.com/Leaflet/Leaflet/issues/1416
		    gjl.clearLayers();
		    gjl.addData(JSON.parse(this.responseText));
		}
		modifyFlag(false);
	    }
	    var conn = new XMLHttpRequest();
	    conn.open('GET', './catgj.cgi');
	    conn.send(null);
	    conn.onreadystatechange = respond;// イベントリスナ登録
	}
	loadbtn.addEventListener('click', reloadGJ);
    }
    init("foo");
}();