LoginSignup
3
4

More than 3 years have passed since last update.

Electron で地図を表示する無料で最短の道

Last updated at Posted at 2020-05-18

概要

Electron で地図を表示するアプリを作ってみます。
ライブラリとして地図ライブラリはleafletを、マーカークラスタのためにleaflet.markerclusterを使います。

それぞれのバージョンは以下のとおりです。

ライブラリ バージョン
electron 1.12.2
leaflet 1.6.0
leaflet.markercluster 1.4.1

準備

node と npm

 ここからダウンロード 

最短の道

ディレクトリを作成

ディレクトリを名前はなんでもいいので作って、そこに以下の内容の package.json をおきます。ディレクトリの名前はとりあえず le にしておきます。

package.json
{
  "name": "le",
  "version": "1.0.0",
  "description": "Sample map application.",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "author": ""
}

Electron をインストール

npm i electron --save

アプリの作成

le の下に以下の3ファイルを作成します。

index.html

index.html
<!DOCTYPE html>
<html lang=zxx>
<link
    rel="stylesheet"
    href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
>
<script
    src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
></script>

<style>
html, body, #mapid { height: 100% }
body { margin: 0 }
</style>

<title>Electron-Leaflet</title>
<div id="mapid"></div>

main.js

main.js
const { app, BrowserWindow } = require('electron')

const
createWindow = () => {
    const mainWindow = new BrowserWindow(
        {   width           : 1000
        ,   height          : 1000
        ,   webPreferences  : {
                preload         : __dirname + '/preload.js'
            }
        }
    )

    mainWindow.loadFile( 'index.html' )
}

app.whenReady().then(
    () => {
        createWindow()
        app.on(
            'activate'
        ,   () => !BrowserWindow.getAllWindows().length && createWindow()
        )
    }
)

app.on(
    'window-all-closed'
,   () => process.platform !== 'darwin' && app.quit()
)

preload.js

preload.js
window.onload = () => {
    const
    map = L.map( 'mapid' ).setView( [ 35.6825, 139.752778 ], 15 )
    L.tileLayer(
        'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
    ).addTo( map )
}

デバッグ

npm run start

image.png

勘所

html, body, #mapid { height: 100% }

で地図を囲む全ての要素の height を 100% にしないと地図が表示されません。

body { margin: 0 }

がないと、地図の左上にちょっと余白ができて、右下が切れてしまいます。

L.map( 'mapid' ).setView( [ 35.6825, 139.752778 ], 15 )

で id が mapid の div に地図をつけています。
center と zoom の両方を指定しないと、地図が表示されません。

発展

デフォルトのマーカー

デフォルトのマーカーを皇居に置いてみます。

  • preload.js の onload の中に以下の内容を加えます。
    L.marker( [ 35.6825, 139.752778 ] ).addTo( map ).bindPopup( 'Imperial Palace.' ).openPopup()

image.png

divIcon を使ったマーカー

divIcon を使うと、マーカーのアイコンとして div を使えます。div なんでやりたい放題できます。とりあえず赤いぽっちにしてみます。

  • index.html の <style>に以下の内容を加えます。
.marker {
    text-align      : center
;   color           : white
;   font-size       : 16
;   border-radius   : 8px
;   box-shadow      : 8px 8px 8px rgba( 0, 0, 0, 0.4 )
}
.red {
    background      : red
}
  • preload.js の onload の中に以下の内容を加えます。
    const   redMarker = { icon: L.divIcon( { className: 'red marker', iconSize: [ 16, 16 ] } ) }
    L.marker( [ 35.6825, 139.752778 ], redMarker ).addTo( map ).bindPopup( 'Imperial Palace.' ).openPopup()

image.png

マーカークラスターグループ

leaflet.markercluster をインストールすると、地図にたくさんマーカーを置くとき、近接するマーカーをまとめて表示するような機能を実現できます。
とりあえず5個のマーカーのクラスターグループを北の丸公園においてみます。

  • index.html に以下の内容を加えます。
<link
    rel="stylesheet"
    href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css"
>
<link
    rel="stylesheet"
    href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css"
>
<script
    src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js"
></script>
  • preload.js の unload の中に以下の内容を加えます。
    map.addLayer(
        L.markerClusterGroup().addLayer(
            L.marker( [ 35.691, 139.752 ], redMarker )
        ).addLayer(
            L.marker( [ 35.692, 139.752 ], redMarker )
        ).addLayer(
            L.marker( [ 35.690, 139.752 ], redMarker )
        ).addLayer(
            L.marker( [ 35.691, 139.753 ], redMarker )
        ).addLayer(
            L.marker( [ 35.691, 139.751 ], redMarker )
        )
    )

5個まとめて表示されています。

image.png

5 と書いてあるクラスターにズームしてみます。

image.png

余談

z-index について

この記事では地図の上に他の HTML エレメントがのっていませんが、たとえばメニューみたいなものを上にのせたいというような場合が考えられます。この時 #mapid の z-index を 0 にするか、上にのせたいものの z-index を 400 以上にする必要があります。

#mapid {
    z-index         : 0
}

警告について

View メニューから Toggle Developer Tools を選ぶと、HTML のデバッガが出てきて、console をみると以下のような警告が表示されています。

security-warnings.ts:179 Electron Security Warning (Insecure Content-Security-Policy) This renderer process has either no Content Security
    Policy set or a policy with "unsafe-eval" enabled. This exposes users of
    this app to unnecessary security risks.

For more information and help, consult
https://electronjs.org/docs/tutorial/security.
This warning will not show up
once the app is packaged.

これが気になる方は preload.js の頭で

process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = '1'

としてください。

もう一つの方法としてスタンドアローンアプリであれば、index.html に以下のように書けばいいのですが、Leaflet を使う場合はこれを書くと地図データをダウンロードできなくなります。

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">

Leaflet 1.6.0

前回の記事(Vue で地図を表示する無料で最短の道)を書いた時に比べ Leaflet は少し書きやすくなりました。

また前回は npm でインストールしたのですが、いずれにしろネットワークが必ず必要なので今回は CDN にしてみました。

最後に

leaflet は機能豊富なライブラリなので、いくらでもネタはあるんですが、キリがないのでこのへんにしておきます。最後までおつきあいいただいてありがとうございました。

3
4
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
3
4