Monacaアプリの開発④ Leafletの利用

Image from Gyazo

Leaflet

Leafletは,ウェブ地図を表示するためのオープンソースのJavaScriptライブラリです. OpenStreetMapMapboxのタイル地図を表示させることができます. Monacaで利用するには,JS/CSSコンポーネントをクリックして,Leafletのライブラリをプロジェクトに追加します. このとき,次の2つのファイルを選択してインストールします(CDNで設定しても構いません).

Image from Gyazo

プロジェクトの作成

新規にプロジェクトを作成します. テンプレートは前回と同じ Onsen UI V2 Vue Minimum を選択しましょう.

Image from Gyazo

プロジェクト名に「Monacaでアプリ開発④」,説明に「Leafletの利用」を設定しましょう.

Image from Gyazo

テンプレートの確認

クラウドIDEを起動し,テンプレートの/src/App.vueを確認します.

HTML

v-ons-toolbarの次にあるdiv要素とp要素を削除しておきます.

<template>
    <v-ons-page>
      <v-ons-toolbar>
        <div class="center">{{ title }}</div>
        <div class="right">
          <v-ons-toolbar-button>
            <v-ons-icon icon="ion-navicon, material: md-menu"></v-ons-icon>
          </v-ons-toolbar-button>
        </div>
      </v-ons-toolbar>

      <!-- 削除 -->

    </v-ons-page>
</template>
<script>
 /* JavaScriptのコード */
</script>

JavaScript

title地図アプリ に設定します. methodsオプションの内容を削除しておきます.

export default{
  data() {
    return {
      title: '地図アプリ'
    };
  },
  methods: {
    // 削除
  }
};

地図アプリの開発

Leafletを利用した地図アプリを開発します. 地図には日進市のオープンデータを利用して, 日進市の教育機関や医療機関をマーカーとして表示します.

地図の表示

HTML

地図を表示するdiv要素を作成します. 要素の高さは360pxに設定しておきます.

<div id="map" style="height:360px"></div>

JavaScript

地図の緯度・経度をlatlng,ズームレベルをzoomで定義します. 緯度:35.130621,経度:137.037568は日進市役所です. mountedオプションは,Vueのインスタンスが初期化され,DOM(Document Object Model)が利用可能になったときに実行されます. ここでは,mapオブジェクトを生成し,オープンストリートマップの地図タイルを表示しています.

export default{
  data() {
    return {
      title: "地図アプリ",
      map: null, // mapオブジェクト
      lat: 35.130621, // 緯度
      lng: 137.037568, // 経度
      zoom: 14, // ズームレベル
    };
  },
  methods: {
  },
  mounted: function(){

    // mapオブジェクトの作成
    this.map = L.map("map");

    // 緯度・経度・ズームレベルの設定
    this.map.setView([this.lat, this.lng], this.zoom);

    // オープンストリートマップ
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    {
      attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(this.map);

  }
}

実行結果

Image from Gyazo

外部JSファイルのインポート

日進市オープンデータポータルサイトで公開されている 教育機関と医療機関のオープンデータを取り込みます. JSON形式でダウンロードしたデータを,独自に加工したファイルが次の kyouiku.jsiryou.js です. これらのファイルを,/src/js/に配置してください.

Image from Gyazo

上記のファイルを,Vueで利用するには,次のようにimportを宣言します. JSON形式のデータには,kyouiku.kyouiku_listiryou.iryou_listでアクセスします.

JavaScript

import kyouiku from "./js/kyouiku"
import iryou from "./js/iryou"

正しくデータが取り込まれているか,次のコードをmountedプロパティに記述してみましょう. 「日進市立西小学校」と「愛知国際病院」がアラート・ダイアログで表示されます.

this.$ons.notification.alert(kyouiku.kyouiku_list[0]["名称"] + " " + iryou.iryou_list[0]["施設名称"]);

実行結果

Image from Gyazo

マーカーの表示

上記で取り込んだ教育機関と医療機関のデータをマーカーとして表示しましょう. 複数のマーカーを保持することができるL.FeatureGroupに, L.circleMarkerとして生成したマーカーを追加します. このとき,教育機関のマーカーは赤色,医療機関のマーカーは緑色に設定します.

JavaScript

data() {
  return {
    title: "地図アプリ",
    map: null,
    lat: 35.130621,
    lng: 137.037568,
    zoom: 14,
    kyouiku_group: null,
    iryou_group: null
  };
}
// 教育機関のマーカー
this.kyouiku_group = L.featureGroup()
for(let data of kyouiku.kyouiku_list){
  let lat = Number(data["緯度"]); // 緯度
  let lon = Number(data["経度"]); // 経度
  if(!isNaN(lat) || !isNaN(lon)){
    let marker = L.circleMarker([lat, lon], {color: "#ff0000"}); // マーカーは赤色
    marker.bindPopup(data["名称"]) // ポップアップ表示
    this.kyouiku_group.addLayer(marker);
  }
}
this.kyouiku_group.addTo(this.map);

// 医療機関のマーカー
this.iryou_group = L.featureGroup()
for(let data of iryou.iryou_list){
  let lat = Number(data["緯度"]); // 緯度
  let lon = Number(data["経度"]); // 経度
  if(!isNaN(lat) || !isNaN(lon)){
    let marker = L.circleMarker([lat, lon], {color: "#00ff00"}); // マーカーは緑色
    marker.bindPopup(data["施設名称"]) // ポップアップ表示
    this.iryou_group.addLayer(marker);
  }
}
this.iryou_group.addTo(this.map);

実行結果

Image from Gyazo

チェックボックスの作成

表示するマーカーを切り替えるためのチェックボックスv-ons-checkboxを生成します. object_listがチェックボックスの項目名であり, checked_listはチェックが入っているチェックボックスの配列です.

HTML

<v-ons-list>
  <v-ons-list-item v-for="(object, $index) in object_list" :key="object" tappable>
    <label class="left">
      <v-ons-checkbox
        :input-id="'checkbox-' + $index"
        :value="object"
        v-model="checked_list"
      >
      </v-ons-checkbox>
    </label>
    <label class="center" :for="'checkbox-' + $index">
      {{ object }}
    </label>
  </v-ons-list-item>
  <v-ons-list-item>
    <v-ons-button modifier="large" style="margin: 6px 0">更新</v-ons-button>
  </v-ons-list-item>
</v-ons-list>

JavaScript

data() {
  return {
    title: "地図アプリ",
    map: null,
    lat: 35.130621,
    lng: 137.037568,
    zoom: 14,
    kyouiku_group: null,
    iryou_group: null,
    object_list: ["教育機関", "医療機関"],
    checked_list: ["教育機関", "医療機関"]
  };
}

実行結果

Image from Gyazo

マーカーのフィルタ

チェックボックスの状態に応じて表示するマーカーを切り替えます. 更新ボタンをタップするとfilterメソッドを呼び出します. filterメソッドでは,checked_listの状態に応じて,対応するL.featureGroupを地図に追加します.

HTML

<v-ons-list-item>
  <v-ons-button @click="filter" modifier="large" style="margin: 6px 0">更新</v-ons-button>
</v-ons-list-item>

JavaScript

methods: {
  filter(){

    // マーカーを削除
    this.kyouiku_group.removeFrom(this.map);
    this.iryou_group.removeFrom(this.map);

    //チェックされているマーカーを追加
    for(let item of this.checked_list){
      if(item == "教育機関"){
        this.kyouiku_group.addTo(this.map);
      }
      else if(item == "医療機関"){
        this.iryou_group.addTo(this.map);
      }
    }
  }
}

実行結果

Image from Gyazo

課題

アプリが完成したら,次の課題に挑戦してみよう!

プロジェクトのソースコード

参考書籍

愛知県名古屋市にある椙山女学園大学 文化情報学部 向研究室の公式サイトです. 専門は情報科学であり,人工知能やデータベースなどの技術要素を指導しています. この公式サイトでは,授業で使用している教材を公開すると共に, ベールに包まれた女子大教員のミステリアスな日常を4コマ漫画でお伝えしていきます. サイトに関するご意見やご質問はFacebookまたはTwitterでお問い合わせください.