スポンサーリンク

1. 顧客管理に地図を使いたいって思いませんか?

結構民間の方だと営業活動、フィールドサービスの業務で「地図を活用したい」そんなお話をよく聞きます。

セールスフォースを導入したいけど、高い…

そんなあなたにkintone!もちろんプラグインもあるのですが、結構お高め。

https://kintone-sol.cybozu.co.jp/integrate/atcreation003.html

自分でカスタマイズしちゃえばタダなので、kintoneをカスタマイズして地図を使った業務アプリケーションを作っていきましょう!

「は?ノーコードツールなのにコード使うとかありえないわ。とっとと使えるもんよこせや。」
という方、記事の最後にアプリ配布しますので、ご安心ください。

2.この記事の対象

  • 地図を使っている業務のDXをしたい方
  • HTMLやJavaScriptの基本知識(入門レベル)がある方
  • kintoneのカスタマイズをやったことがある方

を対象とした記事となっております。

3.完成イメージ

一覧画面に表示されたレコードが地図にプロットされて

画像

マーカーをクリックするとレコード詳細へ


レコード詳細でも地図が表示されて

画像

編集や追加の際は、地図をクリックすると緯度経度を取得可能

画像

こんな感じです。

3.レコード一覧に地図を表示しよう

①初期設定

まずは、地図を表示してみましょう。
kintoneでは、地図を表示できるライブラリ(便利機能のおまとめみたいなもの)としてopenlayersというものが推奨されております。
openlayersを使えるようにするために、まずは初期設定していきましょう。

アプリの設定 > JavaScript / CSSでカスタマイズ」の「PC用のCSSファイル」に以下のURLを設定します。

  • https://js.cybozu.com/openlayers/v3.17.1/ol.css

「アプリの設定 > JavaScript / CSSでカスタマイズ」の「PC用のJavaScriptファイル」に以下のURL/ファイルを設定します。

  • https://js.cybozu.com/jquery/2.2.4/jquery.min.js
  • https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.1.0/load-image.all.min.js
  • https://js.cybozu.com/openlayers/v3.17.1/ol.js

これで準備完了です。

②地図とマーカーを表示する。

ご自身のEditorでindex.jsというファイルを作成します。

処理の流れは
①kintoneのレコード一覧の情報を取得する
②レコード一覧から緯度、経度、レコード番号を取得して地図にマーカーを立てるJSONに変換する
③現在地を取得する。
④現在地をもとに中心座標をセット
⑤地図を表示
⑥地図にマーカーを表示(レイヤー追加)

コードにすると以下のとおりです。

(function() {
  'use strict';

  kintone.events.on('app.record.index.show', function(event) {

    //追加したいスペースを指定して、nullチェック(増殖バグ防止)
    if (document.getElementById('map') !== null) {
        return;
    }
    //一覧のオブジェクトを取得
    let kobj = event.records

        //現在地を中心にセット
    navigator.geolocation.getCurrentPosition((position)=>{   
      let coords = position.coords;
      let nowLat = coords.latitude;
      let nowLng = coords.longitude;
      //一覧画面のヘッダ部の要素を取得
      let mapSpace = kintone.app.getHeaderSpaceElement();
      $(mapSpace).append('<div id="map" style="width:70%; height:400px"></div>');

      //現在地とオブジェクトを渡して、マップを表示
      setMarkerIndexMap(mapSpace, nowLat, nowLng, kobj); 
  });
    

    });
  })();

//中心地とオブジェクトを受け取り地図表示とマーカーをたてる関数
function setMarkerIndexMap(spaceElement,centerLat,centerLng,obj) {
 let map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                })
            ],
            view: new ol.View({
                zoom: 12
            })
        });

  //経度と緯度を変換
  let centerCoordinate = convertCoordinate(centerLng, centerLat);
  //指定した位置をマップの中央にセット
  map.getView().setCenter(centerCoordinate);
    
    //マーカーを立てる
  map.addLayer(indexMarker(obj));

  // クリックイベント
  map.on('click', function(e) {
      // クリックした箇所がFeature の場合、処理を実行する
      map.forEachFeatureAtPixel(e.pixel, function(feature, layer) {       
      // Feature から URL を取り出してきて、その結果に基づきページを開く
      window.open(feature.get('URL'));
      });
  })
};


//オブジェクトからマーカー情報を返す関数
function indexMarker(jsonObj){
  
    let listobj=[];

    //オブジェクトから緯度、経度、レコード番号を抜き出してJSONオブジェクトを作成する
  for (i=0;i<jsonObj.length;i++){
  var MarkerFeature = new ol.Feature({
      geometry: new ol.geom.Point(convertCoordinate(parseFloat(jsonObj[i]["経度"]["value"]),parseFloat(jsonObj[i]["緯度"]["value"]))),
      URL: "https://{ドメイン}.cybozu.com/k/2/show#record=" + jsonObj[i]["レコード番号"]["value"]
  })
  listobj.push(MarkerFeature)
  }

  var markerStyle = new ol.style.Style({
      image: new ol.style.Icon({
        anchor: [0.5, 46],
        anchorXUnits: 'fraction',
        anchorYUnits: 'pixels',
        src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAZCAYAAADe1WXtAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHwSURBVEiJpdW9a9NRFMbxT9qmNWmSRqlFhE6CLuIL1DcUHDqJm/0HBEUk3RQXpW7dXdysWlAEHQSlo4IoIohQKFJQxKWIIlTb5pc2anMdkmBbmleHZ3vul3Pvc865QggaCfu6uIOtTfkbGboYTRIN8yvJd5xoG4psmqk9LH0gBMJTQh+FJOPobAmKo718zbFcrACr+kI4TpThHQYbQhHr4WqG6MkG2FqtEsb5nWQJZ2pCMZDh5RBLc3WAa/WGsIMozV0k1kExnGR+jOKfJoFVLRBGKKT4jL0hBLq51kfhRZ2D04Qblfes5blNKcFynItwYTf5Ug3zc0KyolSlslrgIQpxxiCWYWaC0mbGUUIHASFDeFwD+Kjcbh/RWX3Tw1mixTYrzRP6iXBsXfppHl6m2M6bXqLYx4PNWmpnguhTi+m/L99iEf2bNn8P108RtQI9Qj5Ort5Ebenl27MmgfcoZZhFR93Zx8gu8o2GYIGQLYdzqKmFkuHtTVbrQXOsZJhsZUvtT1P4UQM4/S+cbS3t0xSTOVY2AkuEA+Q7Od/Okt6eID+7ATpRDmcGsba+k26unCRfBc6XRzXCwba+k0q18RRzUxXoOZZT3Kp3piG0Aj49SP41IcFPZP8bWmmxVwOsxDjbjL8pKPZ3c79eOGv1F5xHWAKxXNwiAAAAAElFTkSuQmCC'
      })
  })

  let MarkerLayer = new ol.layer.Vector(
      {
          source: new ol.source.Vector({
              features: listobj
          }),
          style: markerStyle
      }   
  )
  return MarkerLayer
};


// 緯度経度を球面メルカトル図法に変換
 function convertCoordinate(longitude, latitude) {
     return ol.proj.transform([longitude, latitude], 'EPSG:4326', 'EPSG:3857');
 }

これでレコードの状況を一覧で確認できるようになりました!!

以降については有料でnote記事を書いています。(申し訳ございません。)

https://note.com/datukoumuin_com/n/n2ef67c2f7d2f

アプリの配付はこちらでおこなってますので、ご購入いただいて、業務に活用いただければ幸いです。

スポンサーリンク
おすすめの記事