以前、MonacaとNCMBを使った地図検索アプリを作りました。
- Monaca × NCMBで位置情報検索アプリを作る(その1:画面と仕様について)
- Monaca × NCMBで位置情報検索アプリを作る(その2:位置情報データのインポート)
- Monaca × NCMBで位置情報検索アプリを作る(その3:位置情報検索と地図表示)
この時にはMapBoxの地図を表示していますので、MapBoxのアカウント取得が必要でした。今回は地図ライブラリをOpenLayersに変更し、アカウント取得不要にしてみました。
そのMapBox版とOpenLayers版との差分について解説します。
コード
実際のコードはNCMBMania/monaca-map-app-openlayersにあります。実装時の参考にしてください。
読み込むライブラリの違い
MapBox版では以下のJavaScript、CSSを読み込みます。
<link href='https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.css' rel='stylesheet' />
<script src='https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.js'></script>
OpenLayersでは以下になります(これは開発用途なので、プロダクションではDLした上で使うのがお勧めです。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.3.0/ol.css">
<script src="https://cdn.jsdelivr.net/npm/ol@v7.3.0/dist/ol.js"></script>
地図の初期化
MapBox版は以下のように初期化を行います。MapBoxのAPIキーは必須です。
mapboxgl.accessToken = mapboxAccessToken;
map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [139.7454329, 35.6585805], // 東京タワーの位置情報
zoom: 14
});
それに対してOpenLayersでは以下のようになります。コード量は多くなります。
// OpenLayerを準備
map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([139.7454329, 35.6585805]), // 東京タワーの位置情報
zoom: 14,
})
});
// マーカー用のVectorLayerを作成
const markerLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
});
map.addLayer(markerLayer);
地図をタップした際の位置情報取得
MapBoxの場合は、タップイベントから緯度経度が簡単に取得できます。
const {lng, lat } = e.lngLat;
それに対してOpenLayersではcoordinateから変換が必要です。
const [lng, lat] = ol.proj.toLonLat(e.coordinate);
地図にマーカーを追加する
MapBox版は分かりやすいです。
const marker = new mapboxgl.Marker()
.setLngLat([lng, lat])
.addTo(map);
OpenLayersの場合はちょっと複雑です。あらかじめレイヤーを追加しておき、そのレイヤーに対してマーカーを追加します。
const markerStyle = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: 'assets/icons/marker.png',
}),
});
const marker = new ol.Feature({
geometry: new ol.geom.Point(coordinate),
});
marker.setStyle(markerStyle);
map.getLayers().getArray()[1].getSource().addFeature(marker);
マーカーを削除する
MapBox版はマーカーオブジェクトを消す、という分かりやすい書き方です。
marker.remove();
OpenLayersの場合は該当マーカーをレイヤーから消すという指定です。
map.getLayers().getArray()[1].getSource().removeFeature(marker);
マーカーから位置情報を取得する
NCMBの位置情報検索は緯度経度が必要なので、マーカーから位置情報を取得します。MapBox版は次のようになります。
const {lng, lat} = marker._lngLat
OpenLayersの場合はかなり複雑です。もっと良い取得方法があるかも知れません。
const [lng, lat] = ol.proj.toLonLat(marker.getGeometry().flatCoordinates);
まとめ
OpenLayersの場合、若干コード量が多いのとMapBoxと比べて操作が分かりづらいのが難点かも知れません。アイコン画像もあらかじめ用意しておく必要があります。
しかし、アカウント取得やAPIキーなしで使えるのは魅力的です。関数などで複雑そうに見える部分を隠せれば、OpenLayersを使って地図表示を行うのは良さそうです。