データの前処理はいつだって大変です。
例えばこのデータ、何を表しているかわかりますか?
{
"title": "こみっくがーるず",
"place": "新宿三丁目前",
"lng": "139.861979",
"lat": "35.760790"
}
作品のタイトル(title)と場所(place)、そして緯度経度(longitude, latitude)があることから、勘のいい人は「聖地の場所を表すデータだ」と気が付くかもしれません。
では次に、このデータは"正しい"データでしょうか?
確かに『こみっくがーるず』には、登場キャラクターが新宿三丁目を練り歩くシーンがあります。
ただ、場所の詳細度が低く、『新宿三丁目前』がどこを指しているのか具体的には分かりません。
それとも、都バス「新宿三丁目」停留所前?
考えていても埒があかないので、緯度経度をもとに地図上で確認してみましょう。
んんん???
調べてみると、葛飾区にも新宿(にいじゅく)*という地名があるとのこと。
そして、残念ながら『こみっくがーるず』には葛飾区が描かれていません。
つまり上記のデータは、文脈上の緯度経度が間違っていました。
こんなことが位置情報データの前処理段階で時々起こります。(多くが単純なヒューマンエラーや、Geocodingでの変換が不安定なことが原因)
さて、ここで問題なのは、「地図上にプロットするまでデータが正しいかどうか確認できないこと」です。
正直、データをいちいち地図上にプロットして、間違いを見つけては「正しい緯度経度を探してデータを書き換える」なんてことを繰り返すのはとても大変です。
それなら、地図上のUIで直接編集できるようにすればいいのでは?
と思い至り、早速デモを作ってみました。
デモ
上記のデモでは、ドラッグ操作だけで直感的にデータを編集できるようになっています。
具体的には、位置情報を示すCircle要素をドラッグで動かした分だけデータが書き換わるような仕組みです。(修正後のデータはExport
ボタンでDL可能)
実装コード
Circle要素にドラッグイベントを付与する実装は、Leaflet.jsをちょっと弄ればできました。
ポイントとしては、Circle要素をドラッグしている間は他のドラッグイベントを止め、Cicle要素のドラッグイベントのみが動作するようにすることです。
例えば、Circle要素の一つにドラッグイベントを与えるのは、以下の通りです。(Leaflet.jsを事前に読み込んであることが前提)
// set map object var map = L.map('map').setView([35.6915, 139.7015], 16); // set circle object var location = [circle_lat, circle_lng]; var option = { radius: 10, color: 'red', opacity: 1, fillColor: 'red', fillOpacity: .4 }; var circle = L.circle(location, option); // drag & drop event circle.on('mousedown', function (event) { map.dragging.disable(); var circleStartingLat = circle._latlng.lat; var circleStartingLng = circle._latlng.lng; var mouseStartingLat = event.latlng.lat; var mouseStartingLng = event.latlng.lng; map.on('mousemove', e => { var mouseNewLat = e.latlng.lat; var mouseNewLng = e.latlng.lng; var latDifference = mouseStartingLat - mouseNewLat; var lngDifference = mouseStartingLng - mouseNewLng; var center = [circleStartingLat - latDifference, circleStartingLng - lngDifference]; circle.setLatLng(center); }); map.on('mouseup', function() { map.dragging.enable(); map.removeEventListener('mousemove'); }); });
ちなみにデモの全コードはbl.ocksに載せていますので、気になる方は以下のリンクを参照してください。