2018年9月26日水曜日

OpenLayers5 Workshop - 2.6 Downloading features

2 Vector Data
2.6 Downloading features
フィーチャをダウンロード

After uploading data and editing it, we want to let our users download the result. To do this, we'll serialize our feature data as GeoJSON and create an <a> element with a download attribute that triggers the browser's file save dialog. At the same time, we'll add a button to the map that let's users clear existing features and start over.

データをアップロードして編集した後、ユーザが結果をダウンロードできるようにします。これをするために、フィーチャデータを GeoJSON としてシリアル化し、ブラウザのファイル保存ダイアログをトリガ(動作開始)する download 属性と共う <a> エレメントを作成します。同時に、ユーザが既存のフィーチャを削除し、やり直すボタンをマップに追加します。

First, we need a bit of markup to represent the buttons. Add the following elements below the map-container in your index.html:

最初に、ボタンを表示する少しのマークアップが必要です。index.html の map-container の下に次のエレメントを追加します:
<div id="tools">
 <a id="clear">Clear</a>
 <a id="download" download="features.json">Download</a>
</div>
Now we need some CSS to make the buttons look right. Add something like this to the <style> element in index.html:

次に、右の方に見えるボタンを作るためのいくつかの CSS が必要です。 index.html にこのようなものを <style> エレメントに追加します:
#tools {
 position: absolute;
 top: 1rem;
 right: 1rem;
}
#tools a {
 display: inline-block;
 padding: 0.5rem;
 background: white;
 cursor: pointer;
}
Clearing features is the easier part, so we'll do that first. The vector source has a source.clear() method. We want clicks on the "Clear" button to call that method, so we'll add a listener for click in our main.js:

フィーチャの削除は簡単な部分なので、最初に行います。ベクタソース(vector source)は source.clear() メソッドがあります。メッソドを呼び出すために "Clear" ボタンをクリックしたいので、main.js に click のリスナを追加します:
const clear = document.getElementById('clear');
clear.addEventListener('click', function() {
 source.clear();
});
To serialize our feature data for download, we'll use a GeoJSON format. Since we want the "Download" button to work at any time during editing, we'll serialize features on every change event from the source and construct a data URI for the anchor element's href attribute:

ダウンロード用のフィーチャデータをシリアル化するために、GeoJSON フォーマットを使います。編集中いつでも動作する "Download" ボタンがほしいので、いつの change イベントでもソースからフィーチャをシリアル化し、アンカーエレメントの href 属性用のデータ URI を構築します:
const format = new GeoJSON({featureProjection: 'EPSG:3857'});
const download = document.getElementById('download');
source.on('change', function() {
 const features = source.getFeatures();
 const json = format.writeFeatures(features);
 download.href = 'data:text/json;charset=utf-8,' + json;
});
Buttons to clear and download data

■□ Debian9 で試します■□
前回使用した index.html のバックアップを保存して次のように修正します。

user@deb9-vmw:~/openlayers-workshop-en$ cp index.html index.html_snap
user@deb9-vmw:~/openlayers-workshop-en$ vim index.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>OpenLayers</title>
  <style>
   html, body, #map-container {
    margin: 0;
    height: 100%;
    width: 100%;
    font-family: sans-serif;
    background-color: #04041b;
   }
   #tools {
    position: absolute;
    top: 1rem;
    right: 1rem;
   }
   #tools a {
    display: inline-block;
    padding: 0.5rem;
    background: white;
    cursor: pointer;
   }
  </style>
 </head>
 <body>
  <div id="map-container"></div>
  <div id="tools">
   <a id="clear">Clear</a>
   <a id="download" download="features.json">Download</a>
  </div>
 </body>
</html>
前回使用した main.js のバックアップを保存して次のように修正します。

user@deb9-vmw:~/openlayers-workshop-en$ cp main.js main.js_snap user@deb9-vmw:~/openlayers-workshop-en$ vim main.js
import 'ol/ol.css';
import GeoJSON from 'ol/format/GeoJSON':
import Map from 'ol/Map';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import DragAndDrop from 'ol/interaction/DragAndDrop';
import Modify from 'ol/interaction/Modify';
import Draw from 'ol/interaction/Draw';
import Snap from 'ol/interaction/Snap';
import sync from 'ol-hashed';
const map = new Map({
 target: 'map-container',
 view: new View({
  center: [0, 0],
  zoom: 2
 })
}); 
sync(map);

const source = new VectorSource();

const layer = new VectorLayer({
 source: source
});
map.addLayer(layer);

map.addInteraction(new DragAndDrop({
 source: source,
 formatConstructors: [GeoJSON]
}));

map.addInteraction(new Modify({
 source: source
}));

map.addInteraction(new Draw({
 type: 'Polygon',
 source: source
}));

map.addInteraction(new Snap({
 source: source
}));

const clear = document.getElementById('clear');
clear.addEventListener('click', function() {
 source.clear();
});

const format = new GeoJSON({featureProjection: 'EPSG:3857'});
const download = document.getElementById('download');
source.on('change', function() {
 const features = source.getFeatures();
 const json = format.writeFeatures(features);
 download.href = 'data:text/json;charset=utf-8,' + json;
});
http://localhost:3000/ とブラウザでマップを開きます。(もし開かなければ、'npm start' を実行してください。

三角形を描画します。(地図は表示しません。そのデータもダウンロードされてしまいます。)


「Download」ボタンをクリックします。


ダイアログで「OK」ボタンをクリックします。


ファイルがダウンロードディレクトリに保存されます。


内容は次のようになていました。
{"type":"FeatureCollection","features":
 [{"type":"Feature","geometry":
  {"type":"Polygon","coordinates":
   [[
    [76.76796875,59.17592824927138],
    [56.02578125,40.97989806962016],
    [93.99453125,40.17887331434699],
    [76.76796875,59.17592824927138]
   ]]
  },
  "properties":null
}]}

0 件のコメント: