ブラウザおよびnode.jsのための高度な地理空間データ分析ライブラリ「turf.js」
選択した範囲内の家賃相場を求めるとかいろんなことに使えます。
Turf.jsはMapbox社謹製の地理空間データ分析ライブラリです。ピュアJavaScriptで作成されていてフロントエンドでもサーバーサイドでも動作します。
Turfの特徴としては、対応するデータ形式をGeoJSONを絞っており、基本GeoJSONで受け取ったデータを分析して分析結果をGeoJSONで返すといったライブラリになっています。
そのため、GeoJSONに対応した地図ライブラリと組み合わせることで、分析結果を簡単に視覚化することができます。もちろんD3.jsと組み合わせて使うのも簡単! いろいろな可能性を秘めた今後が楽しみなライブラリです。
今回は入門編として、Leaflet上で選択した範囲内のデータの基本統計量を計算します。
マーカーのプロパティには、それぞれ「value」値が設定されていて、選択範囲に含まれるマーカーのvalue値の合計や平均値、標準偏差などを動的に求めます。
今回は四角いポリゴンの中に含まれるデータを分析していますが、例えば町境データのようなもっと複雑なポリゴンを使ってデータ分析を行うなどもできます。
サンプル
マーカーの下部、一番尖がっている部分が選択範囲内に含まれていないと計算対象にならないので注意。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
//jsonデータの読み込み。fetchを使っているが jQuery.ajaxでもいい。 fetch('../_dataset/sample.geojson') .then(function(response) { return response.json() }).then(function(json) { draw(json) }); function draw(points){ //出力設定 var aggregations = [ { aggregation: 'sum', inField: 'value', outField: '合計' }, { aggregation: 'average', inField: 'value', outField: '平均値' }, { aggregation: 'median', inField: 'value', outField: '中央値' }, { aggregation: 'min', inField: 'value', outField: '最少値' }, { aggregation: 'max', inField: 'value', outField: '最大値' }, { aggregation: 'deviation', inField: 'value', outField: '標準偏差値' }, { aggregation: 'variance', inField: 'value', outField: '分散値' }, { aggregation: 'count', inField: '', outField: '個数' } ]; var map = L.map('map').setView([36.3219088 , 139.0032936], 14); //地理院地図レイヤー追加 L.tileLayer( 'http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { attribution: "<a href='http://www.gsi.go.jp/kikakuchousei/kikakuchousei40182.html' target='_blank'>国土地理院</a>" } ).addTo(map); //マーカー追加 var onEachFeature = function(feature, layer) { var popupContent = "value:"; if (feature.properties && feature.properties.value) { popupContent += feature.properties.value; } layer.bindPopup(popupContent); } var markerLayer = L.geoJson(points, { onEachFeature: onEachFeature }).addTo(map); //areaセレクター追加 var areaSelect = L.areaSelect({width:200, height:250}); //セレクターチェンジイベント areaSelect.on("change", function() { //四隅取る var b = this.getBounds(); var extend = [ [b.getSouthWest().lng , b.getSouthWest().lat], [b.getSouthEast().lng, b.getSouthEast().lat], [b.getNorthEast().lng, b.getNorthEast().lat], [b.getNorthWest().lng, b.getNorthWest().lat] ] //ポリゴンにする var polygons = turf.featurecollection([ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [ extend ] } } ]); //ポリゴン内に含まれるポイントの統計データを取得 var aggregated = turf.aggregate(polygons, points, aggregations); //統計データを出力 document.querySelector(".info").value = JSON.stringify(aggregated.features[0].properties, null, "t"); }); areaSelect.addTo(map); } |
Turfには他にも素晴らしい機能が沢山あるので、随時紹介していこうと思います。