Angular6とLeafletで地図を表示する

Angular6 と Leaflet で地図を表示するアプリを作りました。

[こちら](https://qiita.com/spice/items/22811539d3561bd1e73c)では、[@asymmetrik/ngx-leaflet](https://github.com/Asymmetrik/ngx-leaflet) を使う方法を紹介されていますが、ここでは[Leaflet Quick Start Guide](https://leafletjs.com/examples/quick-start/)に沿った方法を試してみました。

## 初期化

最初に Angular-cli でプロジェクトを作成します。

```
ng new AngularLeafletSampleMapViewer
cd AngularLeafletSampleMapViewer
```

## 地図表示

leaflet と @types/leaflet を npm でインストールします。

```
npm install leaflet --save
npm install @types/leaflet --save-dev
```

leaflet 用の css や画像ファイルを Angular で使えるように angular.json に設定します。

```angular.json
{
...
  "apps": [
    {
      ...
      "assets": [
        "src/favicon.ico",
        "src/assets",
        {
          "glob": "**/*",
          "input": "./node_modules/leaflet/dist/images",
          "output": "src/assets/"
        }
      ],
      ...
      "styles": [
        "styles.css",
        "./node_modules/leaflet/dist/leaflet.css"
      ],
      ...
    }
  ]
  ...
}
```

地図を表示するコンポーネントを作ります。

```
ng g component map
```

map.component.html, map.component.css, map.component.ts ができるのでそれぞれに以下のように書き換え・追加します。

```map.component.css
#map { height:100vh }
```

```map.component.html
<div id="map"></div>
```

```map.component.ts
import * as L from 'leaflet';
...
map:any;
...
ngOnInit() {
  // 地図表示
  this.map = L.map('map').setView([34.702485,135.495951], 13);
  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);
}
```
app.component.html に `<app-map></app-map>` を追加して、`ng serve`すれば地図が表示されると思います。

## マーカー表示
[Leaflet Quick Start Guide](https://leafletjs.com/examples/quick-start/)でのマーカー表示は`var marker = L.marker([51.5, -0.09]).addTo(mymap);`と書いていますが、上の設定だけではマーカーが表示されないので、`app.module.ts`に以下を追加します。

```app.module.ts
import {icon, Marker} from 'leaflet';
const iconRetinaUrl = 'src/assets/marker-icon-2x.png';
const iconUrl = 'src/assets/marker-icon.png';
const shadowUrl = 'src/assets/marker-shadow.png';
const iconDefault = icon({
  iconRetinaUrl,
  iconUrl,
  shadowUrl,
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
  tooltipAnchor: [16, -28],
  shadowSize: [41, 41]
});
Marker.prototype.options.icon = iconDefault;
```

※参考：https://github.com/Leaflet/Leaflet/issues/4968#issuecomment-371184633

## 現在地表示

現在地の表示には、[leaflet.locatecontrol](https://github.com/domoritz/leaflet-locatecontrol) を使いました。

```
npm install leaflet.locatecontrol --save
npm install @types/leaflet.locatecontrol --save-dev
npm install --save font-awesome
```

```angular.json
{
  ...
  "apps": [
    {
      ...
      "styles": [
        "styles.css",
        "./node_modules/leaflet/dist/leaflet.css",
        "./node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css",
        "./node_modules/font-awesome/css/font-awesome.css"
      ],
      ...
    }
  ]
  ...
}
```

```map.component.ts
import * as L from 'leaflet';
import 'leaflet.locatecontrol';
...
ngOnInit() {
  ...
  L.control.locate().addTo(this.map);
}
```

これで現在地が表示できる機能が地図上に付くと思います。

これらを反映したアプリは以下で公開しています。

https://uedayou.net/AngularLeafletSampleMapViewer/

また、ソースコードをgithubにあげました。

https://github.com/uedayou/AngularLeafletSampleMapViewer

単純に地図を表示するだけのつもりが、いくつかつまるポイントがあったので、参考になればと思います。