CODE HOUSE


Hello, I'm a freelance software engineer.


[GoogleMaps] Node.jsを使ったgoogle mapの初期化

Node.js、coffeescript、Backbone.jsでgoogle map??

今回の記事ではNode.js、coffeescript、Backbone.jsを使って、サクッとgoogle mapを初期化してみようと思う。最近の流行りとして、node.jsはわかるものの、coffeescriptとBackbone.jsはどうなのよ?と言われそうである。今から何かを始めるのであれば、JavascriptはES2015、ES2016あたりで記載すべきだと思うし、フレームワークはReactとかを使いたいところである。しかし、現在作成しているwebアプリが上記のタイトルの構成なのでそれで説明をしたいと思う。coffeescriptはともかく、Backbone.jsはそれなりに使いやすいし、まだ現役ではあると思う。

この記事用にgithubのレポジトリを作成してみたので参考に。

mm-git/googleMapsSample

今回の記事では画面全体に地図を表示するまでを説明するが、この方法が楽なポイントは下記の通りである。

  • htmlファイルで、google mapsのapiやjqueryなどの読込が不要。(ビルド済みのjsファイルだけ読み込めばOK!!)
  • google mapsの初期化を待ってから何かの処理する場合のスクリプトが簡潔に書ける

nodeの初期化

google mapの表示のためにフロントエンドで使用しているモジュールをインストールする。今回のmapの表示だけなら、backboneやbootstrapは全く必要ないかもしれない。しかし、今後地図上にマーカーや線を書いたりするのに、データを持つmodelとマーカ、線を描画するviewを分けたい。また、今後画面には地図以外の要素も描画したい。そのため今回、backboneやbootstrapもインストールしておく。

1npm i backbone jquery bootstrap google-maps -D

以下は、coffeescriptのビルドやテスト用のサーバを起動するためのgulp関連のモジュールである。直接今回の記事とは関係ないがインストールする。

1npm i browser-sync coffee-loader coffee-script gulp gulp-plumber gulp-rename gulp-uglify gulp-webpack require-dir webpack -D

gulp関連の詳細は Gulp関連の記事 を参照。

スクリプトの説明

ファイル構成

今回の説明に関するファイルの構成は以下のようになっている。

googleMapsSample
├──public
│   ├── css
│   │   ├── bootstrap-theme.min.css
│   │   ├── bootstrap.min.css
│   │   └── main.css
│   ├── index.html
│   └── js
│       └── main.min.js
└── src
    ├── main.coffee
    └── map
        └── view
            ├── MapView.coffee
            └── overlayView.coffee
  • index.htmlmain.min.jscssファイルを読み込むだけの単純なファイル。
  • main.min.jsmain.coffeeをビルドして作成される。

public/index.html

public/index.html
 1<!DOCTYPE html>
 2<html lang="ja">
 3<head>
 4    <meta charset="UTF-8">
 5    <title>Map Sample</title>
 6    <meta name="description" content="Google map sample application">
 7    <meta name="viewport" content="width=device-width, initial-scale=1">
 8    <link rel="stylesheet" href="css/bootstrap.min.css">
 9    <link rel="stylesheet" href="css/bootstrap-theme.min.css">
10    <link rel="stylesheet" href="css/main.css">
11</head>
12<body>
13    <div class="container-fluid">
14        <div class="row">
15            <div class="col-md-12">
16                <div id="map"></div>
17            </div>
18        </div>
19    </div>
20    <script type="text/javascript" src="js/main.min.js"></script>
21</body>
22</html>
  • js/main.min.jscssファイルを読み込んでいるだけの単純なhtmlファイルとなっている。
  • <div id="map"></div>に地図が表示される。
  • coffeeファイル内で、jquerybootstrapbackbonegoogle-mapsを読み込んでいるので、index.htmlではこれらを読み込むための<script>タグを書く必要がない

src/map/view/mapView.coffee

src/map/view/mapView.coffee
 1GoogleMapsLoader = require('google-maps')
 2Backbone = require('backbone')
 3
 4class MapView extends Backbone.View
 5  el: "#map"
 6
 7  initialize: (options) ->
 8    @google = null
 9    @map = null
10
11  loadMap: ->
12    new Promise((resolve, reject) =>
13      GoogleMapsLoader.KEY = 'your key';
14      GoogleMapsLoader.LANGUAGE = 'ja';
15      GoogleMapsLoader.LIBRARIES = ['geometry', 'places']
16
17      GoogleMapsLoader.load((google) =>
18        mapOpt =
19          center                 : new google.maps.LatLng(35.1660, 136.0135)
20          zoom                   : 12
21          scrollwheel            : true
22          disableDoubleClickZoom : true
23          keyboardShortcuts      : true
24          mapTypeId              : google.maps.MapTypeId.ROADMAP
25          mapTypeControl         : true
26          mapTypeControlOptions :
27            position             : google.maps.ControlPosition.TOP_LEFT
28          streetViewControl      : false
29          scaleControl           : true
30          scaleControlOptions :
31            position             : google.maps.ControlPosition.BOTTOM_RIGHT
32          zoomControl            : true
33          zoomControlOptions :
34            position             : google.maps.ControlPosition.TOP_LEFT
35
36        @map = new google.maps.Map(@$el[0], mapOpt)
37        @google = google
38
39        OverlayView = require('./overlayView.coffee')
40        @overlayView = new OverlayView(@map)
41
42        resolve(@)
43      )
44    )
45
46module.exports = MapView
  • google-mapsモジュールは、KEYLANGUAGELIBRARIESなどを設定した後、load()を呼ぶだけで簡単にgoogle apiのライブラリが読み込まれる。
  • googleライブラリ読み込み後は、よく見られるgoogle mapsの初期化と同じ。
  • loadMap()関数は、全体をPromise()で囲んでいる。google mapの初期化が終わるとresolve()を呼ぶようにしている。

src/map/view/overlayView.coffee

src/map/view/overlayView.coffee
 1class OverlayView extends google.maps.OverlayView
 2  constructor: (map) ->
 3    if !OverlayView.instance
 4      @setMap(map)
 5      OverlayView.instance = @
 6
 7    return OverlayView.instance
 8
 9  draw: ->
10    #do nothing
11
12  remove: ->
13    #do nothing
14
15  fromContainerPixelToLatLng: (point) ->
16    return @getProjection().fromContainerPixelToLatLng(point)
17
18  fromDivPixelToLatLng: (point) ->
19    return @getProjection().fromDivPixelToLatLng(point)
20
21  fromLatLngToContainerPixel: (point) ->
22    return @getProjection().fromLatLngToContainerPixel(point)
23
24  fromLatLngToDivPixel: (point) ->
25    return @getProjection().fromLatLngToDivPixel(point)
26
27module.exports = OverlayView
  • google maps API V3で fromContainerPixelToLatLng() などの関数を使うために、google.maps.OverlayViewの派生クラスOverlayViewを作っておく。
  • また、上記のOverlayViewクラスはSingletonパターンを用いたクラスとなっている。
  • src/map/view/mapView.coffeeでgoogle apiのloadが終わった時、一度new OverlayView(@map)を行っている。こうしておくと、以降newを行った場合に素早く同じインスタンスを返すことができる。

src/main.coffee

src/main.coffee
1MapView = require('./map/view/MapView')
2
3mapView = new MapView()
4mapView.loadMap()
5.then(
6  ->
7    alert("google map initialized !")
8)
  • main.coffeeMapViewを初期化して、loadMap()を呼ぶだけの簡単な処理となっている。
  • loadMap()はPromiseオブジェクトを返すので、.then()で地図初期化完了後に行う処理を簡潔に記載することができる。

ビルド & 実行

  • このプロジェクトはgulp coffeeを実行すると、public/js/main.jspublic/js/main.min.jsをビルドするようになっている。
  • gulp startでlocalで確認できるようになっている。
    • localで確認する際は、google API Keyを空にして実行する必要があるかも。

DEMO

Map Sample