17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OpenStreetMapAdvent Calendar 2016

Day 12

OpenStreetMap & kintoneで「いまどこ」チェックイン

Posted at

地図とIT…便利な連携ができそうです。
自分の居場所を知られたくないケースはよくありますが、知ってほしいケースもあります。

例えば

  • 待ち合わせで今いる場所を正確に伝えたい(今ここにいるよーという声)
  • 災害時に報告して安否を通達したい(大丈夫ですよーという声)
  • ラウンダー業務の証拠づくり(現場で仕事していますよーという声)

今回はOpenStreetMapOpenLayersOpenStreetMap Nominatim を使って、いま・どこで・どうなっているかを記録して通達する仕組みを作ってみました。記録したデータはkintoneに貯めておきます。

できあがり

スマートフォンのkintoneアプリから保存、閲覧したkintone画面
だれが、いつ、どこにいたかが早わかり
20161209-9-36_No-00.png

素材

OpenStreetMap

道路地図などの地理情報データを誰でも無償で利用できるサービスで、APIも豊富です。Google Mapも無料で利用しているのになぜ?と思われがちですが、APIを使う際にはライセンス(有償)が必要なことがあるようです。

OpenLayers

ブラウザに様々な地図を、簡単に重ね合わせて表示できるオープンソースのJavaScriptライブラリです。

OpenStreetMap Nominatim

geocoding ができる WebAPIで、緯度・経度から場所を取得できます。

kintone

kintoneは、業務システムをエンドユーザーが素早く作れる&使えるクラウドサービスで、cybozu developer networkに載っているようにREST API、JavaScript API もあるので、いろいろカスタマイズできちゃいます。

使ったAPI、function、method

  • ol.Map
  • ol.layer.Tile
  • ol.View
  • ol.source.OSM
  • ol.proj.transform
  • (OpenLayers).addOverlay
  • kintone.app.getId
  • kintone.api.url
  • kintone.api
  • kintone.[mobile.]app.record.getFieldElement
  • kintone.app.record.setFieldShown
  • kintone.mobile.app.getHeaderSpaceElement
  • kintone.app.record.getSpaceElement
  • kintone.events.on
  • kintone.proxy
  • kintone.Promise

準備

作り方

kintoneからの挙動

  • レコードを追加したら、位置情報を取得して保存
  • 緯度経度情報を元にOpenStreetMapで地図を表示
  • 緯度経度情報を元にNominatimを使い逆ジオゴ-ディング
  • 中心部にピント、登録者名+日時を表示
  • 緯度経度はブラウザから編集できないように非表示

プログラム

https://github.com/ushiront/kintone-osmPoint
20161209-17-12_No-00.png

Point.1

sample-osmpoint.js
var appId = kintone.app.getId() ? kintone.app.getId() : 
Number(location.pathname.replace(/\/k\/m\//, "").split("/")[0]);

スマートフォン用のJavaScriptではアプリIDを取得できないのでブラウザのアドレスから取得。

Point.2

sample-osmpoint.js
var hideGroupFields = function(event) {
    if (event.type.match(/^mobile./)) {
        kintone.mobile.app.record.setFieldShown("Lat", false);
        kintone.mobile.app.record.setFieldShown("Lng", false);
    } else {
        if (kintone.app.record.getFieldElement("Lat") === "undefined") { return; }
        if (kintone.app.record.getFieldElement("Lng") === "undefined") { return; }
        if (kintone.app.record.getFieldElement("Title") === "undefined") { return; }
        if (kintone.app.record.getFieldElement("Address") === "undefined") { return; }

        kintone.app.record.setFieldShown("Lat", false);
        kintone.app.record.setFieldShown("Lng", false);
     }
     event.record["Title"]["disabled"] = true;
     event.record["Address"]["disabled"] = true;
};

フィールドの表示、非表示、非アクティブ化。
スマートフォン用のJavaScriptでは要素が取れないのでPC用のみでエラーチェック。

Point.3

sample-osmpoint.js
// OpenStreetMap and OpenLayers
var map = new ol.Map({
    target: 'map',
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        })
    ],
    view: new ol.View({
        center: ol.proj.fromLonLat([lng, lat]),
        zoom: osmPosition.defZoom
    })
});

// Append Overlay
var pos = ol.proj.transform([lng, lat], 'EPSG:4326', 'EPSG:3857');
// Marker pin
var imgElement = document.createElement('img');
var imgSrc = 'data:image/png;base64,base64 imagedata';
imgElement.setAttribute('src', imgSrc);

var marker = new ol.Overlay({
    position: pos,
    element: imgElement,
    stopEvent: false,
    positioning: 'center-center'
});
map.addOverlay(marker);

中心部の緯度経度、縮尺を指定して地図を取得
pin画像をレイヤ追加

Point.4

sample-osmpoint.js
// kintone promise
return new kintone.Promise(function(resolve, reject) {
    // geolocation API
    navigator.geolocation.getCurrentPosition(function(position) {

        event.record["Lat"]["value"] = position.coords.latitude.toFixed(7);
        event.record["Lng"]["value"] = position.coords.longitude.toFixed(7);

        var url = "https://nominatim.openstreetmap.org/reverse?format=json";
        url += "&lat=" + event.record["Lat"]["value"];
        url += "&lon=" + event.record["Lng"]["value"];

        // Get address by Re-Geocording
        kintone.proxy(url, 'GET', {}, {}).then(function(args) {
            var resp = JSON.parse(args[0]);
            var respValue = {
                state: resp.address.state ? resp.address.state : "",
                city: resp.address.city ? resp.address.city : "",
                traffic_signals: resp.address.traffic_signals ? resp.address.traffic_signals : "",
                country: resp.address.country ? resp.address.country : ""
            };
            event.record["Address"]["value"] =
            respValue.state + respValue.city + respValue.traffic_signals + "(" + respValue.country + ")";

            resolve(event);
        }, function(error) {
            console.log(error);
            reject(event);
        });

    }, function(error) {
        // error event
        reject(event);
    });
});

レコード保存時に位置情報を取得し、住所を取得
※位置情報は詳細特定をされないように桁指定
kintone.Promise, kintone.proxyを利用して外部サービスを実行

今後やってみたいこと

  • スタッフの最新情報を表示
  • トレース
  • 地図に関するiPhoneAppを作ってみたい
17
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?