チュートリアル14
提供: svg2wiki
				
								
				(版間での差分)
				
																
				
				
								
				|  (→コード) |  (→コード) | ||
| (1人の利用者による、間の22版が非表示) | |||
| 3行: | 3行: | ||
| * 実際の動作は、[https://svgmap.org/devinfo/devkddi/tutorials/geojson2/geojson2.html こちら]をクリック。 | * 実際の動作は、[https://svgmap.org/devinfo/devkddi/tutorials/geojson2/geojson2.html こちら]をクリック。 | ||
| − | * [https://svgmap.org/devinfo/devkddi/tutorials/geojson2 | + | * 使用ファイルの[https://www.svgmap.org/devinfo/devkddi/tutorials/geojson2.zip ZIPアーカイブファイル] | 
| + | |||
| == geojson1.html == | == geojson1.html == | ||
| 33行: | 34行: | ||
| </pre> | </pre> | ||
| − | ==geoJsonExample2.html== | + | ==geoJsonExample2.html, geoJsonExample2.js== | 
| ===[https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php USGS Earthquake GeoJSON Real-time Feeds]サービスについて=== | ===[https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php USGS Earthquake GeoJSON Real-time Feeds]サービスについて=== | ||
| このサービスは全世界の地震発生状況を更新間隔1分リアルタイム配信しています。出力形式はGeoJson、出力データは時間間隔および地震規模でいくつか選択できるようになっています。リクエストにはクエリパートはなく、更新されたデータが常に同じURLで配信されます。 | このサービスは全世界の地震発生状況を更新間隔1分リアルタイム配信しています。出力形式はGeoJson、出力データは時間間隔および地震規模でいくつか選択できるようになっています。リクエストにはクエリパートはなく、更新されたデータが常に同じURLで配信されます。 | ||
| 55行: | 56行: | ||
| ** <code>setInterval(function(){..}..)</code>  指定した間隔で定期的に更新する関数(地震データはリアルタイムに更新されるため) | ** <code>setInterval(function(){..}..)</code>  指定した間隔で定期的に更新する関数(地震データはリアルタイムに更新されるため) | ||
| + | |||
| + | geoJsonExample2.html | ||
| <pre> | <pre> | ||
| <!doctype html> | <!doctype html> | ||
| 62行: | 65行: | ||
| 	<title>SVGMapのwebAppレイヤーで、geoJsonを描画するサンプル</title> | 	<title>SVGMapのwebAppレイヤーで、geoJsonを描画するサンプル</title> | ||
| </head> | </head> | ||
| + | <script src="https://cdn.jsdelivr.net/gh/svgmap/svgmapjs@latest/svgMapLayerLib.js"></script> | ||
| + | <script src="geoJsonExample2.js"></script> | ||
| + | <body> | ||
| + | <h3>area layer</h3> | ||
| + | <p><a href="https://earthquake.usgs.gov/earthquakes/feed/">USGS Earthquake Hazards Program Feed</a>の可視化</p> | ||
| + | 期間<select id="dataSelect1" onchange="changeData()"></select><br> | ||
| + | 規模<select id="dataSelect2" onchange="changeData()"></select> | ||
| + | <div id="messageDiv"></div> | ||
| + | </body> | ||
| + | </html> | ||
| + | </pre> | ||
| − | < | + | geoJsonExample2.js | 
| + | <pre> | ||
| var usgsEarthquakeService="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/"; | var usgsEarthquakeService="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/"; | ||
| var timeSpanKeys=["hour","day","week","month"]; // 配信データの期間設定の選択枝 | var timeSpanKeys=["hour","day","week","month"]; // 配信データの期間設定の選択枝 | ||
| 172行: | 187行: | ||
| 	console.log(features); | 	console.log(features); | ||
| } | } | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| </pre> | </pre> | ||
| − | + | ==appendix:クロスオリジンアクセス== | |
| − | + | [[クロスオリジンアクセス]] については([[クロスオリジンアクセス|独立したページ]]に移行しました) | |
2024年7月24日 (水) 10:32時点における最新版
| 目次 | 
[編集] チュートリアル14 WebApp Layer ベクトル地理情報サービスの結合
動的にベクトルデータが生成・配信されているサービスをSVGMap.jsに結合します。ここではUSGS Hazards Programが配信している、リアルタイム世界の地震発生状況データ(GeoJSON Real-time Feeds)(GeoJSON版)を結合してみます。基本的にはチュートリアル6との違いはありません。
- 実際の動作は、こちらをクリック。
- 使用ファイルのZIPアーカイブファイル
[編集] geojson1.html
- チュートリアル6と特に違いはありません。
[編集] Container.svg
- チュートリアル6と特に違いはありません。
[編集] geoJsonExample2.svg
-  ドキュメントルート要素(svg要素)の、data-controller属性で、このレイヤーを操作するwebAppを指定しています。
- data-controller="geoJsonExample2.html#exec=appearOnLayerLoad
- exec=appearOnLayerLoadは、レイヤが表示状態になるとwebAppのウィンドが出現する設定です。(詳しくはこちら)
 
- defs要素でマーカー(POIのアイコン)を定義しています
- マーカーの色はマグニチュードに応じて変化させるためここでは未定義にしてあります
 
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="12375.0 -4500.0 2250.0 2250.0" go:dataArea="12375.0 -4500.0 2250.0 2250.0" data-controller="geoJsonExample2.html#exec=appearOnLayerLoad" property="name,address,phone,url"> <defs> <g id="p0"> <circle cx="0" cy="0" r="10" stroke="none"/> </g> </defs> <globalCoordinateSystem srsName="http://purl.org/crs/84" transform="matrix(100.0,0.0,0.0,-100.0,0.0,0.0)" /> <g id="mapContents"></g> </svg>
[編集] geoJsonExample2.html, geoJsonExample2.js
[編集] USGS Earthquake GeoJSON Real-time Feedsサービスについて
このサービスは全世界の地震発生状況を更新間隔1分リアルタイム配信しています。出力形式はGeoJson、出力データは時間間隔および地震規模でいくつか選択できるようになっています。リクエストにはクエリパートはなく、更新されたデータが常に同じURLで配信されます。
[編集] コード
- geoJsonExample2.svgに紐付けられ、そのDOMをコントロールできるwebApp
- チュートリアル6#geoJsonExample1.htmlに対して以下が相違点
- addEventListener("load", function(){..})-  changeData()UIの設定に基づき、地震データをリクエストして可視化する関数-  getUSGSURL()USGSが配信する地震データを取得するためのGETリクエストを生成-  クロスオリジンアクセスを行うリクエストを作っています。USGS Earthquake GeoJSON Real-time Feedsはaccess-control-allow-origin: *レスポンスヘッダを持っているためアクセス可能です。
 
-  クロスオリジンアクセスを行うリクエストを作っています。USGS Earthquake GeoJSON Real-time Feedsは
-  loadAndDrawGeoJson()非同期でjsonデータを取得し描画する関数- loadJSON()ブラウザ側キャッシュを効かせないように、常に変化する適当なクエリパートをつけています(- getTime()より適切な方法がありますが、ここでは古典的なBad Tipsを用いています)
- buildSchema()- svgMapGIStool.drawGeoJson関数で可視化する際に、SVGMap.jsが持つメタデータ表示フレームワークに適応させるためのスキーマデータを構築するとともに、SVGMapコンテンツのドキュメントルート要素に設定
- svgMapGIStool.drawGeoJson関数で渡す末尾の引数(metaSchema)を生成している
 
- setMagColors()- svgMapGIStool.drawGeoJson関数の持つ、各フィーチャーのproperties値を使ってスタイルを設定可能な機能を使い、マグニチュード値をもとにpointフィーチャの色を指定
 
- svgMapGIStool.drawGeoJson()- buildSchema()で生成したスキーマ(- metaSchema)を与え、SVGMap.jsのメタデータ表示フレームワークでメタデータがうまく表示できるようにしています
 
 
 
-  
-  setInterval(function(){..}..)指定した間隔で定期的に更新する関数(地震データはリアルタイムに更新されるため)
 
-  
geoJsonExample2.html
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>SVGMapのwebAppレイヤーで、geoJsonを描画するサンプル</title> </head> <script src="https://cdn.jsdelivr.net/gh/svgmap/svgmapjs@latest/svgMapLayerLib.js"></script> <script src="geoJsonExample2.js"></script> <body> <h3>area layer</h3> <p><a href="https://earthquake.usgs.gov/earthquakes/feed/">USGS Earthquake Hazards Program Feed</a>の可視化</p> 期間<select id="dataSelect1" onchange="changeData()"></select><br> 規模<select id="dataSelect2" onchange="changeData()"></select> <div id="messageDiv"></div> </body> </html>
geoJsonExample2.js
var usgsEarthquakeService="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/";
var timeSpanKeys=["hour","day","week","month"]; // 配信データの期間設定の選択枝
var timeSpanDefault=2; // 過去1週間のデータの表示をデフォルトに
var levelKeys=["significant","4.5","2.5","1.0","all"]; // マグニチュード別の配信データの選択枝
var levelDefault=2; // M2.5以上の地震の表示をデフォルトに
var intervalMinutes=10; // 10分おきに更新する
var metaSchema; // SVGMap.jsの標準で用意されているジオメトリ選択時のメタデータ表示UIの正規化されたスキーマを格納する
addEventListener("load", function(){
	buildDataSelect();
	changeData();
	setInterval(function(){
		changeData();
		messageDiv.innerText=new Date().toLocaleString() + " update";
	} ,intervalMinutes * 60 * 1000);
});
function changeData(){
	var param1 = dataSelect1.selectedIndex;
	var param2 = dataSelect2.selectedIndex;
	var path = getUSGSURL(param1,param2);
	loadAndDrawGeoJson(path);
}
async function loadAndDrawGeoJson(dataPath){
	var gjs = await loadJSON(dataPath);
	buildSchema(gjs.features);
	setMagColors(gjs.features);
	console.log("geoJson:",gjs);
	var parentElm = svgImage.getElementById("mapContents");
	removeChildren(parentElm);
	svgMapGIStool.drawGeoJson(gjs, layerID, "orange", 2, "orange", "p0", "poi", "", parentElm, metaSchema);
	svgMap.refreshScreen();
}
function buildDataSelect(){
	var first=true;
	for ( var i = 0 ; i < timeSpanKeys.length; i++){
		var timeSpanKey = timeSpanKeys[i];
		var selectedOpt="";
		if ( timeSpanDefault == i){
			selectedOpt="selected";
		}
		dataSelect1.insertAdjacentHTML('beforeend', `<option value="${timeSpanKey}" ${selectedOpt}>${timeSpanKey}</option>`);
	}
	for ( var i = 0 ; i < levelKeys.length ; i++){
		var levelKey = levelKeys[i];
		var selectedOpt="";
		if ( levelDefault == i){
			selectedOpt="selected";
		}
		dataSelect2.insertAdjacentHTML('beforeend',  `<option value="${levelKey}" ${selectedOpt}>${levelKey}</option>`);
	}
}
async function loadJSON(url){
	var response = await fetch(url+"?time="+new Date().getTime()); // 常に最新のデータを得るには何かダミーのクエリパートを付けるBad Tips..
	// https://stackoverflow.com/questions/37204296/cache-invalidation-using-the-query-string-bad-practice
	// https://stackoverflow.com/questions/9692665/cache-busting-via-params
	var json = await response.json();
	return ( json );
}
function removeChildren(element){
	while (element.firstChild) element.removeChild(element.firstChild);
}
function getUSGSURL(timeSpan, level){
	if (!timeSpanKeys[timeSpan]){return};
	if (!levelKeys[level]){return};
	var ans = `${usgsEarthquakeService}${levelKeys[level]}_${timeSpanKeys[timeSpan]}.geojson`;
	console.log("getUSGSURL:",ans);
	return (ans);
}
function buildSchema(features){ // geojsonのfeatureのproprerty名から正規化されたスキーマを生成
	metaSchema={};
	for ( var feature of features){ // 一応全データをトレース
		for ( var propName in feature.properties){
			if (!metaSchema[propName]){
				metaSchema[propName]=true;
			}
		}
	}
	metaSchema=Object.keys(metaSchema);
	svgImage.documentElement.setAttribute("property",metaSchema.join());
}
function setMagColors(features){ // [[解説書#drawGeoJson]]のスタイリング仕様を使い、マグニチュードに応じた色を付ける
	features.sort(function(a,b){ //マグニチュード昇順でソート
		return(a.properties.mag - b.properties.mag);
	});
	
	for ( var feature of features){
		var cmag = feature.properties.mag;
		// マグニチュード3...7でクリッピング
		cmag = Math.max(3,cmag);
		cmag = Math.min(7,cmag);
		// 色相(hue)に変換し、そこからRGBカラーを生成
		var hue = (7-cmag)/(4)*240;
		var rgb = svgMapGIStool.hsv2rgb(hue,100,100);
		console.log(rgb);
		if ( rgb){
			feature.properties["marker-color"]=`#${rgb.r.toString(16).padStart(2, '0')}${rgb.g.toString(16).padStart(2, '0')}${rgb.b.toString(16).padStart(2, '0')}`;
		}
	}
	console.log(features);
}
[編集] appendix:クロスオリジンアクセス
クロスオリジンアクセス については(独立したページに移行しました)
