wslでelixir その75

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題やってみた。

# 練習問題
Livebookで、jsonをパースして、geojsonを生成して、leaflet地図にプロットせよ。

# 方針
- jason使う。
- kino.js使う。
- leaflet.js使う。

# 写真


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d60f7b3a-1b8a-e18d-cf0c-b552a429a78c.png)

# サンプルコード

```
defmodule KinoMap.Leaflet do
	use Kino.JS
	def new(html) when is_binary(html) do
		Kino.JS.new(__MODULE__, html)
	end
	asset "main.js" do
		"""
		import "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.js";
		export function init(ctx, html) {
			ctx.importCSS("https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.css");
			const mapid = document.createElement("div");
			mapid.id = "mapid";
			mapid.style.width = "800px";
			mapid.style.height = "500px";
			ctx.root.appendChild(mapid);
			var map = L.map('mapid').setView([37.9, 140.15], 11);
      L.control.layers({
	      "OpenStreetMap": L.tileLayer('https://c.tile.openstreetmap.org/{z}/{x}/{y}.png', {
				  maxZoom: 25,
				  maxNativeZoom: 19,
				  attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors, '
        }).addTo(map), 
				"地理院 標準地図": L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
					maxZoom: 25,
					maxNativeZoom: 18,
					attribution: 'Map data <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">国土地理院</a>'
	      }), 
				"地理院 淡色地図(Zoom2～)": L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png', {
					minZoom: 2,
					maxZoom: 18,
					attribution: 'Map data <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">国土地理院</a>'
	      }), 
				"地理院 写真(Zoom9～)": L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg', {
					minZoom: 9,
					maxZoom: 18,
					attribution: 'Map data <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">国土地理院</a>( Zoom9～13:Landsat8画像（GSI,TSIC,GEO Grid/AIST）, Landsat8画像（courtesy of the U.S. Geological Survey）, 海底地形（GEBCO）)'
	      })
      }).addTo(map);;
      var features = JSON.parse(html);
      L.geoJson(features).addTo(map);      
      L.marker([37.8, 140.0],{"title":"koko"}).addTo(map);
		}
		"""
	end
end


geojson =
  """
  {
  		"bikuya": [{
  				"lat": "37.929687",
  				"lon": "140.151111",
  				"name": "オートショップユニット"
  		}, {
  				"lat": "37.929220",
  				"lon": "140.109344",
  				"name": "（株）エイジュウプロ"
  		}, {
  				"lat": "37.923453",
  				"lon": "140.093108",
  				"name": "（株）ホンダウイングロードショウ"
  		}, {
  				"lat": "37.911333",
  				"lon": "140.112004",
  				"name": "（有）カーセンター葵商会"
  		}, {
  				"lat": "37.907591",
  				"lon": "140.108036",
  				"name": "塚本サイクル"
  		}, {
  				"lat": "37.928429",
  				"lon": "140.114247",
  				"name": "サイクルショップ川口"
  		}, {
  				"lat": "37.916279",
  				"lon": "140.099879",
  				"name": "サイクルショップ中村"
  		}, {
  				"lat": "37.917854",
  				"lon": "140.101416",
  				"name": "菅原商会"
  		}, {
  				"lat": "37.912485",
  				"lon": "140.108688",
  				"name": "サイクルセンター卯月"
  		}, {
  				"lat": "37.912049",
  				"lon": "140.105914",
  				"name": "ホンダ野村モータース"
  		}, {
  				"lat": "37.869915",
  				"lon": "140.103534",
  				"name": "モーターハウスＫ"
  		}, {
  				"lat": "37.918955",
  				"lon": "140.109289",
  				"name": "ライダースサロン・ヤマカ"
  		}, {
  				"lat": "37.915746",
  				"lon": "140.108313",
  				"name": "中央ホンダ"
  		}, {
  				"lat": "37.905011",
  				"lon": "140.107225",
  				"name": "香澄ホンダ"
  		}, {
  				"lat": "37.912663",
  				"lon": "140.123328",
  				"name": "佐藤オート商会"
  		}, {
  				"lat": "37.910789",
  				"lon": "140.121636",
  				"name": "香坂輪店"
  		}, {
  				"lat": "37.958525",
  				"lon": "140.125682",
  				"name": "斎藤モータース"
  		}, {
  				"lat": "37.956678",
  				"lon": "140.117820",
  				"name": "ニューホンダ石山"
  		}, {
  				"lat": "37.903901",
  				"lon": "140.131694",
  				"name": "二輪屋たかはし"
  		}, {
  				"lat": "37.886019",
  				"lon": "140.104554",
  				"name": "夢工場"
  		}, {
  				"lat": "37.874814",
  				"lon": "140.103239",
  				"name": "あべ輪店"
  		}, {
  				"lat": "37.905055",
  				"lon": "140.137379",
  				"name": "レッドバロン米沢"
  		}]
  }
  """
  |> Jason.decode!()
  |> Map.get("bikuya")
  |> Enum.reduce("{\"type\":\"FeatureCollection\",\"features\":[", fn i, acc ->
    lat = i |> Map.get("lat") 
    lon = i |> Map.get("lon") 
    name = i |> Map.get("name") 
    acc <> 	"{\"type\":\"Feature\",\"properties\":{\"name\":\"#{name}\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[\"#{lon}\",\"#{lat}\"]}},"
  end)
geojson = geojson <> "{}]}"
  
KinoMap.Leaflet.new(geojson)

```

以上。