folium勉強③

# はじめに

前回から、foliumのチュートリアルを動かしています。

https://qiita.com/kiryu-3/items/49c2237b772e577058bd

今回は GeoJSONについてまとめました。

## イントロダクション

### GeoJSONとは何か
GeoJSONは、地理空間情報を表現するためのフォーマットの1つで、JSON形式でデータを表現します。  
GeoJSONは、地理空間情報を扱うための様々なアプリケーションで利用されています。

### GeoJSONの特徴や利点
GeoJSONの特徴や利点は以下の通りです。

 - 軽量で扱いやすい  
    GeoJSONは、JSON形式で記述されているため、  
    サイズが小さく、Webアプリケーションなどで扱いやすい特徴があります。  
- 様々な情報を表現できる
    GeoJSONでは、地理空間情報だけでなく、プロパティ情報も合わせて表現できるため、  
    様々な情報を一つのファイルで表現することができます。  
- オープンなフォーマット
    GeoJSONは、オープンなフォーマットであり、誰でも自由に利用することができます。

## GeoJSONの基礎知識

### ファイルフォーマット
GeoJSONのファイル形式は、拡張子が「.json」であるJSON形式のファイルです。  　　GeoJSONのファイルには、以下の要素が含まれます。

- Feature: 地物データ  
- FeatureCollection: 地物データの集合  
- Geometry: ジオメトリ情報  
- Properties: 地物データのプロパティ情報  

### ジオメトリオブジェクト
GeoJSONでは、ジオメトリオブジェクトと呼ばれるオブジェクトがあります。  
ジオメトリオブジェクトは、以下の種類があります。

- Point: 点  
- MultiPoint: 複数の点  
- LineString: 線分  
- MultiLineString: 複数の線分  
- Polygon: 面  
- MultiPolygon: 複数の面  

### プロパティ
GeoJSONでは、地物データのプロパティを定義することができます。  
プロパティには、地物の名前や種別、面積や長さなどの属性情報が含まれます。  
プロパティは、Featureオブジェクト内に定義されます。

## GeoJSONの例
以下に示すコードは、[こちら](https://geojson.io/#map=2/0/20)に貼れば結果を確認できます。

### Pointオブジェクトの作成方法  
以下のコードでは、北海道日本ハムファイターズの新球場、エスコンフィールドをマークしています。

```sample1.json
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [
      141.552515,
      42.9896012
    ]
  },
  "properties": {
    "name": "Escon Field"
  }
}
```

実行すると、以下のマップが得られます。

![sample1.jsonの実行結果](https://imgur.com/1gu1tXA.png)

### MultiPointオブジェクトの作成方法  
以下のコードでは、エスコンフィールドに加えて、最寄り駅である北広島駅をマークしています。

```sample2.json
{
  "type": "Feature",
  "geometry": {
    "type": "MultiPoint",
    "coordinates": [
      [141.552515, 42.9896012],
      [141.563163, 42.9787932]
    ]
  },
  "properties": {
    "name": "Escon Field and Kitahiroshima Station"
  }
}
```

実行すると、以下のマップが得られます。

![sample2.jsonの実行結果](https://imgur.com/gL3lIn2.png)

### LineStringオブジェクトの作成方法  
以下のコードでは、エスコンフィールドと北広島駅を線で結んでいます。

```sample3.json
{
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [
      [141.552515, 42.9896012],
      [141.563163, 42.9787932]
    ]
  },
  "properties": {
    "name": "Escon Field and Kitahiroshima Station"
  }
}
```

実行すると、以下のマップが得られます。

![sample3.jsonの実行結果](https://imgur.com/AdU88qR.png)

### MultiLineStringオブジェクトの作成方法  
以下のコードでは、エスコンフィールドと北広島駅、北広島市役所と北広島駅を線で結んでいます。

``` sample4.json
{
  "type": "Feature",
  "geometry": {
    "type": "MultiLineString",
    "coordinates": [
      [
        [141.552515, 42.9896012],
      	[141.563163, 42.9787932]
      ],
      [
        [141.562971, 42.9857792],
        [141.563163, 42.9787932]
      ]
    ]
  },
  "properties": {
    "name": "From Kitahiroshima Station to Escon Field and Kitahiroshima office"
  }
}
```

実行すると、以下のマップが得られます。

![sample4.jsonの実行結果](https://imgur.com/Llnq6F7.png)

### Polygonオブジェクトの作成方法  
以下のコードでは、エスコンフィールドと北広島駅、北広島市役所をポリゴンで結んでいます。

``` sample5.json
{
  "type": "Feature",
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [141.563163, 42.9787932],
        [141.552515, 42.9896012],
        [141.562971, 42.9857792],
        [141.563163, 42.9787932]
      ]
    ]
  },
  "properties": {
    "name": "Kitahiroshima Station and Escon Field and Kitahiroshima office"
  }
}
```

実行すると、以下のマップが得られます。

![sample5.jsonの実行結果](https://imgur.com/63QMS0j.png)

### MultiPolygonオブジェクトの作成方法  
以下のコードでは、エスコンフィールドと北広島駅を軸にして、  
北広島市役所とマックスバリュ北広島店をポリゴンで結んでいます。

``` sample6.json
{
  "type": "Feature",
  "geometry": {
    "type": "MultiPolygon",
    "coordinates": [
      [
        [
          [141.563163, 42.9787932],
          [141.552515, 42.9896012],
          [141.562971, 42.9857792],
          [141.563163, 42.9787932]
        ]
      ],
      [
        [
          [141.563163, 42.9787932],
          [141.552515, 42.9896012],
          [141.554326, 42.9819191],
          [141.563163, 42.9787932]
        ]
      ]
    ]
  },
  "properties": {
    "name": "From Kitahiroshima Station and Escon Field to Kitahiroshima office and Kitahiroshima Maxvalu"
  }
}
```

実行すると、以下のマップが得られます。

![sample6.jsonの実行結果](https://imgur.com/0KrLLuS.png)

### FeatureCollectionの活用方法  
以下のコードでは、エスコンフィールドと北広島駅を軸にして、  
北広島市役所とマックスバリュ北広島店をポリゴンで結んでいます。

```sample7.json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [141.552515, 42.9896012]
      },
      "properties": {
        "name": "Escon Field"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [141.563163, 42.9787932]
      },
      "properties": {
        "name": "Kitahiroshima Station"
      }
    }
  ]
}
```

実行すると、以下のマップが得られます。

![sample7.jsonの実行結果](https://imgur.com/teNIUtE.png)

### propertiesの活用方法  
"properties"には、そのFeatureに関する情報を付加することができます。  
nameのほかにも、Featureの種類、色、アイコンなどの情報を追加することができます。

"properties"に入れた情報は、地図上でマーカーやラインをクリックした際に表示される  
ポップアップの中身として利用することができます。  
そのため、何を入れるかは地図を作成する目的や利用シーンによって異なります。

以下のコードでは、エスコンフィールドと北広島駅を結ぶ線に対して、  
距離、所要時間、移動手段 という情報を加えています。

```sample8.json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [141.552515, 42.9896012]
      },
      "properties": {
        "name": "Escon Field"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [141.563163, 42.9787932]
      },
      "properties": {
        "name": "Kitahiroshima Station"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [141.552515, 42.9896012],
          [141.563163, 42.9787932]
        ]
      },
      "properties": {
        "name": "Escon Field and Kitahiroshima Station",
	"distance": "2.1km",
	"duration": "5 minutes, 19 minutes",
	"mode_of_transportation": "Shuttle bus, on foot"
      }
    }
  ]
}
```

実行すると、以下のマップが得られます。

![sample8.jsonの実行結果](https://imgur.com/DccsEXV.png)

## foliumとGeoJSON

### foliumの概要

以下の記事を参考にしてください。

https://qiita.com/kiryu-3/items/0e60a78bc6486a64b5da

### foliumでGeoJSONを表示する方法

#### シンプルなプロット

foliumでは、GeoJSON形式の地物データを地図上に表示することができます。  
以下は、GeoJSON形式で記述されたポイントデータをfoliumで表示する例です。

```sample1.py
point_geojson = {
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [
      141.552515,
      42.9896012
    ]
  },
  "properties": {
    "name": "Escon Field"
  }
}

# マップを作成する
folium_map = folium.Map(location=[42.9841738, 141.557832], zoom_start=13)

# GeoJSONデータをマップに追加する
folium.GeoJson(point_geojson).add_to(folium_map)

# 地図をHTMLファイルとして保存
folium_map.save('map-sample1.html')
```
`GeoJson`関数を使って、GeoJSON形式の地物データを作成し、  
`add_to`メソッドを使って地図上に追加しています。

実行すると、以下のマップが得られます。

![sample1.pyの実行結果](https://imgur.com/wJIJOrd.png)

同様に、LineStringやPolygonのデータも`GeoJSON`形式で定義し、  GeoJson関数を使ってマップ上に表示することができます。

#### ツールチップ指定

`folium.GeoJson`の引数`tooltip`を指定すると、ツールチップを出すことができます。

```sample2.py
point_geojson = {
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [
      141.552515,
      42.9896012
    ]
  },
  "properties": {
    "name": "Escon Field"
  }
}

# マップを作成する
folium_map = folium.Map(location=[42.9841738, 141.557832], zoom_start=13)

# GeoJSONデータをマップに追加する
folium.GeoJson(point_geojson, tooltip=point_geojson['properties']['name']).add_to(folium_map)

# 地図をHTMLファイルとして保存
folium_map.save('map-sample2.html')
```
`GeoJson`関数を使って、GeoJSON形式の地物データを作成し、  
`add_to`メソッドを使って地図上に追加しています。

ツールチップを追加しています。

実行すると、以下のマップが得られます。

![sample2.pyの実行結果](https://imgur.com/sracVV4.png)

#### ポップアップ指定

`folium.GeoJson`の引数`popup`を指定すると、ポップアップを出すことができます。

```sample3.py
point_geojson = {
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [
      141.552515,
      42.9896012
    ]
  },
  "properties": {
    "name": "Escon Field"
  }
}

# マップを作成する
folium_map = folium.Map(location=[42.9841738, 141.557832], zoom_start=13)

# GeoJSONデータをマップに追加する
folium.GeoJson(point_geojson, popup=folium.Popup(point_geojson['properties']['name'], max_width=200)).add_to(folium_map)

# 地図をHTMLファイルとして保存
folium_map.save('map-sample3.html')
```
`GeoJson`関数を使って、GeoJSON形式の地物データを作成し、  
`add_to`メソッドを使って地図上に追加しています。

ポップアップを追加しています。

実行すると、以下のマップが得られます。

![sample3.pyの実行結果](https://imgur.com/6aT2RdD.png)


# 最後に
本当はマーカーの色を変えたかったのですができませんでした…

次回は別軸で動いてきたPyQtと組み合わせていきます。

https://qiita.com/kiryu-3/items/d1388a6a584c3f26d914

# 参考
https://python-visualization.github.io/folium/quickstart.html#GeoJSON/TopoJSON-Overlays