チュートリアル15
提供: svg2wiki
(版間での差分)
(→CanadianGeoNames.html) |
(→REST API) |
||
| 29行: | 29行: | ||
==CanadianGeoNames.html== | ==CanadianGeoNames.html== | ||
===REST API=== | ===REST API=== | ||
| + | 少し複雑ですので、[https://www.nrcan.gc.ca/maps-tools-and-publications/maps/geographical-names-canada/application-programming-interface-api/9249 Geographical names in Canada : Geoname Service]が提供するAPIのうち今回使用する部分をまとめます。 | ||
| + | |||
| + | ====使用するクエリパラメータ==== | ||
| + | 今回は以下の二つを使います。 | ||
| + | |||
| + | * bbox 西、南、東、北の座標(世界測地系の度の値)をカンマ区切りで指定 | ||
| + | * num 出力する最大数 | ||
| + | |||
| + | *クロスオリジン設定 | ||
| + | |||
*geoJsonExample2.svgに紐付けられ、[[解説書#.E3.83.AC.E3.82.A4.E3.83.A4.E3.83.BC.E5.9B.BA.E6.9C.89.E3.81.AEUI|そのDOMをコントロールできるwebApp]] | *geoJsonExample2.svgに紐付けられ、[[解説書#.E3.83.AC.E3.82.A4.E3.83.A4.E3.83.BC.E5.9B.BA.E6.9C.89.E3.81.AEUI|そのDOMをコントロールできるwebApp]] | ||
| 47行: | 57行: | ||
<html> | <html> | ||
<head> | <head> | ||
| − | + | <title>basic dynamic wms layer controller</title> | |
| − | + | <meta charset="utf-8"></meta> | |
</head> | </head> | ||
| − | |||
<script> | <script> | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | var canadianGeoNamesService = "https://geogratis.gc.ca/services/geoname/en/geonames.csv"; | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | function | + | onload=function(){ |
| − | + | addEventListener("zoomPanMap", async function(){ | |
| − | + | geoNames = await getGeoNames(); | |
| − | + | }); | |
| − | + | getGeoNames(); | |
} | } | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | var crsAD=1; | |
| − | + | var maxItems=100; | |
| − | + | ||
| − | + | async function getGeoNames(){ | |
| − | + | console.log("called getGeoNames"); | |
| − | + | ||
| − | + | var geoViewBox = svgMap.getGeoViewBox(); | |
| − | + | var req = getCanadianGeoNamesReq(geoViewBox); | |
| − | + | var csv = await getCsv(req); | |
| − | + | if ( csv.length > maxItems){ | |
| − | + | messageDiv.innerText="Exceeded maximum number. Please zoom in."; | |
| − | + | }else{ | |
| − | + | messageDiv.innerText=""; | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
} | } | ||
| + | drawPoints(csv); | ||
| + | console.log(csv); | ||
} | } | ||
| − | + | function getCanadianGeoNamesReq(geoArea){ | |
| − | var | + | var area_x0=geoArea.x; |
| − | + | var area_y0=geoArea.y; | |
| − | + | var area_x1=geoArea.x+geoArea.width; | |
| − | var | + | var area_y1=geoArea.y+geoArea.height; |
| − | return ( | + | var ans = `${canadianGeoNamesService}?bbox=${area_x0},${area_y0},${area_x1},${area_y1}&num=${maxItems}`; |
| + | return ( ans ); | ||
} | } | ||
| − | function | + | async function getCsv(url){ |
| − | + | var response = await fetch(url); | |
| + | var txt = await response.text(); | ||
| + | txt = txt.split("\n"); | ||
| + | var ans = []; | ||
| + | for ( var line of txt ){ | ||
| + | // https://www.ipentec.com/document/csharp-read-csv-file-by-regex ダブルクォーテーションエスケープを加味したcsvパース | ||
| + | line = line.split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/); | ||
| + | if (line.length > 1){ | ||
| + | ans.push(line); | ||
| + | } | ||
| + | } | ||
| + | return ( ans ); | ||
} | } | ||
| − | function | + | function drawPoints(csv){ |
| − | + | removeUses(); | |
| − | + | var schema = csv[0].join(); | |
| − | var | + | var latCol=csv[0].indexOf("latitude"); |
| − | + | var lngCol=csv[0].indexOf("longitude"); | |
| − | + | svgImage.documentElement.setAttribute("property",schema); | |
| − | + | for ( var i = 1 ; i < csv.length ; i++){ | |
| − | + | var point = csv[i]; | |
| − | + | var meta = point.join(); | |
| − | + | var lat = Number(point[latCol]); | |
| − | + | var lng = Number(point[lngCol]); | |
| − | + | var use=svgImage.createElement("use"); | |
| − | + | use.setAttribute("xlink:href","#p0"); | |
| − | + | use.setAttribute("content",meta); | |
| − | + | use.setAttribute("x",0); | |
| − | + | use.setAttribute("y",0); | |
| + | use.setAttribute("transform",`ref(svg,${lng},${-lat})`); | ||
| + | svgImage.documentElement.appendChild(use); | ||
} | } | ||
| − | + | svgMap.refreshScreen(); | |
| − | + | ||
} | } | ||
| − | function | + | function removeUses(){ |
| − | + | var uses = svgImage.getElementsByTagName("use"); | |
| − | + | console.log(uses.length); | |
| − | + | for ( var i = uses.length-1 ; i >=0 ; i--){ | |
| − | + | uses[i].remove(); | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
} | } | ||
| − | console.log( | + | |
| + | console.log(svgImage.getElementsByTagName("use").length); | ||
} | } | ||
| − | |||
</script> | </script> | ||
<body> | <body> | ||
| − | <h3> | + | <h3>Canadian GeoNames layer controller</h3> |
| − | <p><a href="https:// | + | <p>Get CanadianGeoNames Features from <a href="https://www.nrcan.gc.ca/maps-tools-and-publications/maps/geographical-names-canada/application-programming-interface-api/9249" target="_blank">Canadian GeoNames Search Service</a></p> |
| − | + | <div id="messageDiv" style="color:red">-</div> | |
| − | + | ||
| − | + | ||
</body> | </body> | ||
</html> | </html> | ||
</pre> | </pre> | ||
2022年2月28日 (月) 07:07時点における版
目次 |
チュートリアル15 WebApp Layer 伸縮スクロールに応じたベクトル地理情報サービス結合
動的にベクトルデータが生成・配信されているサービスをSVGMap.jsに結合します。チュートリアル14に対して、こちらは伸縮スクロールする度にその表示領域に応じたデータをサービスから取得して表示します。またチュートリアル14はgeoJsonデータのサービスでしたがこちらはCSVデータです。
結合するサービスはNatural Resources Canadaが提供している、Geoname Service API(カナダの地名データサービス)です。
- 実際の動作は、こちらをクリック。
- ソースコードのディレクトリ
vectorService1.html
- チュートリアル14と特に違いはありません。
Container.svg
- チュートリアル14と特に違いはありません。
CanadianGeoNames.svg
- チュートリアル14と特に違いはありません。アイコンの色もこちらは赤に固定しています。
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="120,-50,30,30" data-controller="CanadianGeoNames.html#exec=appearOnLayerLoad"> <globalCoordinateSystem srsName="http://purl.org/crs/84" transform="matrix(1,0,0,-1,0,0)"/> <defs> <g id="p0"> <circle cx="0" cy="0" r="6" fill="red"/> </g> </defs> </svg>
CanadianGeoNames.html
REST API
少し複雑ですので、Geographical names in Canada : Geoname Serviceが提供するAPIのうち今回使用する部分をまとめます。
使用するクエリパラメータ
今回は以下の二つを使います。
- bbox 西、南、東、北の座標(世界測地系の度の値)をカンマ区切りで指定
- num 出力する最大数
- クロスオリジン設定
- geoJsonExample2.svgに紐付けられ、そのDOMをコントロールできるwebApp
- チュートリアル6#geoJsonExample1.htmlに対して以下が相違点
addEventListener("load", function(){..})-
changeData()UIの設定に基づき、地震データをリクエストして可視化する関数-
getUSGSURL()USGSが配信する地震データを取得するためのGETリクエストを生成 -
loadAndDrawGeoJson()buildSchema()- svgMapGIStool.drawGeoJson関数で可視化する際に、SVGMap.jsが持つメタデータ表示フレームワークに適応させるためのスキーマデータを構築
- svgMapGIStool.drawGeoJson関数で渡す末尾の引数(metaSchema)を生成している
setMagColors()- svgMapGIStool.drawGeoJson関数の持つ、各フィーチャーのproperties値を使ってスタイルを設定可能な機能を使い、マグニチュード値をもとにpointフィーチャの色を指定
-
-
setInterval(function(){..}..)指定した間隔で定期的に更新する関数(地震データはリアルタイムに更新されるため)
-
<!doctype html>
<html>
<head>
<title>basic dynamic wms layer controller</title>
<meta charset="utf-8"></meta>
</head>
<script>
var canadianGeoNamesService = "https://geogratis.gc.ca/services/geoname/en/geonames.csv";
onload=function(){
addEventListener("zoomPanMap", async function(){
geoNames = await getGeoNames();
});
getGeoNames();
}
var crsAD=1;
var maxItems=100;
async function getGeoNames(){
console.log("called getGeoNames");
var geoViewBox = svgMap.getGeoViewBox();
var req = getCanadianGeoNamesReq(geoViewBox);
var csv = await getCsv(req);
if ( csv.length > maxItems){
messageDiv.innerText="Exceeded maximum number. Please zoom in.";
}else{
messageDiv.innerText="";
}
drawPoints(csv);
console.log(csv);
}
function getCanadianGeoNamesReq(geoArea){
var area_x0=geoArea.x;
var area_y0=geoArea.y;
var area_x1=geoArea.x+geoArea.width;
var area_y1=geoArea.y+geoArea.height;
var ans = `${canadianGeoNamesService}?bbox=${area_x0},${area_y0},${area_x1},${area_y1}&num=${maxItems}`;
return ( ans );
}
async function getCsv(url){
var response = await fetch(url);
var txt = await response.text();
txt = txt.split("\n");
var ans = [];
for ( var line of txt ){
// https://www.ipentec.com/document/csharp-read-csv-file-by-regex ダブルクォーテーションエスケープを加味したcsvパース
line = line.split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/);
if (line.length > 1){
ans.push(line);
}
}
return ( ans );
}
function drawPoints(csv){
removeUses();
var schema = csv[0].join();
var latCol=csv[0].indexOf("latitude");
var lngCol=csv[0].indexOf("longitude");
svgImage.documentElement.setAttribute("property",schema);
for ( var i = 1 ; i < csv.length ; i++){
var point = csv[i];
var meta = point.join();
var lat = Number(point[latCol]);
var lng = Number(point[lngCol]);
var use=svgImage.createElement("use");
use.setAttribute("xlink:href","#p0");
use.setAttribute("content",meta);
use.setAttribute("x",0);
use.setAttribute("y",0);
use.setAttribute("transform",`ref(svg,${lng},${-lat})`);
svgImage.documentElement.appendChild(use);
}
svgMap.refreshScreen();
}
function removeUses(){
var uses = svgImage.getElementsByTagName("use");
console.log(uses.length);
for ( var i = uses.length-1 ; i >=0 ; i--){
uses[i].remove();
}
console.log(svgImage.getElementsByTagName("use").length);
}
</script>
<body>
<h3>Canadian GeoNames layer controller</h3>
<p>Get CanadianGeoNames Features from <a href="https://www.nrcan.gc.ca/maps-tools-and-publications/maps/geographical-names-canada/application-programming-interface-api/9249" target="_blank">Canadian GeoNames Search Service</a></p>
<div id="messageDiv" style="color:red">-</div>
</body>
</html>