概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題やってみた。
練習問題
Livebookで、jsonをパースして、geojsonを生成して、deck.gl地図にプロットせよ。
方針
- jason使う。
- kino.js使う。
- deck.js使う
写真
サンプルコード
defmodule KinoMap.Deckgl do
use Kino.JS
def new(html) when is_binary(html) do
Kino.JS.new(__MODULE__, html)
end
asset "main.js" do
"""
import "https://unpkg.com/deck.gl@latest/dist.min.js";
export function init(ctx, html) {
const mapid = document.createElement("div");
mapid.id = "map";
mapid.style.width = "800px";
mapid.style.height = "600px";
ctx.root.appendChild(mapid);
const tileLayer = new deck.TileLayer({
data: 'https://c.tile.openstreetmap.org/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 19,
tileSize: 256,
renderSubLayers: props => {
const {
bbox: {
west,
south,
east,
north
}
} = props.tile;
return new deck.BitmapLayer(props, {
data: null,
image: props.data,
bounds: [west, south, east, north]
});
}
});
var geojson = JSON.parse(html);
const geojsonLayer = new deck.GeoJsonLayer({
id: 'geojson_layer',
data: geojson.features,
pointType: 'circle',
getPointRadius: 300,
getFillColor: [255, 0, 0, 180],
getLineColor: [0, 255, 0, 255],
lineWidthMinPixels: 2,
});
const deckgl = new deck.DeckGL({
container: 'map',
initialViewState: {
latitude: 37.9,
longitude: 140.1,
zoom: 11,
maxZoom: 16,
pitch: 80,
bearing: -15
},
controller: true,
layers: [tileLayer, geojsonLayer, ],
});
}
"""
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": "モーターハウスK"
}, {
"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.Deckgl.new(geojson)
以上。