Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MapLibre GL JSとOverpass APIで Webアプリを作る / Create...

K.Sakanoshita
September 14, 2023

MapLibre GL JSとOverpass APIで Webアプリを作る / Create a web application with MapLibre GL JS and Overpass API

ハンズオン資料

K.Sakanoshita

September 14, 2023
Tweet

More Decks by K.Sakanoshita

Other Decks in Education

Transcript

  1. P.2 自己紹介 - 坂ノ下 勝幸 ◼ 主な所属コミュニティ・団体 ⚫ OpenStreetMap Foundation

    Japan ⚫ Code for OSAKA/Kusatsu/Harima/Suita ⚫ 淀川アートネット ⚫ 諸国・浪漫 / etc.. ◼ 主な活動内容 ⚫ マッピングパーティの開催および協力 ⚫ ウィキペディアタウンの開催および協力 ⚫ オープンソース/データの活用(アプリ開発など) ◼ 目指していること ⚫ 地元の情報は、自分たちで発信する文化を作る ⚫ 現場こそ最強のツールとデータが使えるように P.2
  2. P.4 オープンデータって? ◼ オープンデータは利用規約の一種 ⚫ データ(文書、写真など)を何処まで 使って良いかを決めたルールのこと ⚫ 「自由に使える」がオープンデータ ◼

    オープンデータは誰のもの? ⚫ 作った人や組織の著作物 ⚫ 著作権の枠組みに則った「自由」 ⚫ 「守るべきルール」はちゃんとある P.4 官民データ活用推進基本法で国と地方自治 体はオープンデータに取り組む義務がある
  3. P.6 インターネットで伝え方が変化 ◼ Webサイト(ブログ、SNS)でも 筆者の知識と想いを伝えられる ◼ ネット上の情報は失いやすい ⚫ Yahoo!ジオシティーズも閉鎖 ⚫

    本は正しく保管すれば長持ちする ◼ コピーを保存していても、筆者 しかどこまで使って良いかが 判断出来ない P.6 「伝わるけど残りにくい」ことと 「残しても活かしにくい」時代へ
  4. P.7 オープンデータで残して伝える ◼ 著作権は作者の権利を守る ⚫ 基本的に作者の許可が必要 ⚫ 許可する範囲が違う可能性 ◼ 「残して伝える」を目的に

    ⚫ ブログもSNSも残りにくく、 利用規約(ルール)が曖昧 ⚫ オープンデータとして公開し、誰もが自由に 活用出来るようにすると、残る可能性がある P.7 オープンデータとして公開すると 残して活かすことが出来る可能性
  5. P.8 「清水寺」は最初から世界遺産? ◼ 清水寺の創建年代 ⚫ 「清水寺縁起絵巻」「今昔物語集」「扶桑略記」によれば、 宝亀9年(778年)音羽山に着いた僧の賢心は、観音の化身から 寺を任されたことが始まり ◼ 清水の舞台から飛び降りた人

    ⚫ 「成就院日記」によると、飛び降りは 元禄7年(1694年)~元治元年(1864年)に 未遂含む235件、生存率は85.4% P.8 様々な事を記録、将来に残すことで 地域の魅力や価値が生まれる可能性
  6. P.9 要するに ◼ 「オープンデータ=無料」では無い ⚫ 「行政が公開している無料データ」の理解はよくある間違い ⚫ FOSS4Gが目指す「Free」の思想に沿ったデータがその目的 ◼ 「オープンデータ=自由」の意味

    ⚫ 自由とは、時間や場所を超えて、世界中の方たちの想いや様々な 活動を支えようとする考え方のこと。と、私は考えています。 ⚫ 一見無駄に見えるものの、100年後に価値が出る可能性がある ✓ 何に価値を見出すか、それはその時の文化、経済、人の考え次第と言える オープンデータで残し、将来に伝えていけたら 将来の地域にとって大きな宝物になると思う P.9
  7. P.11 OpenStreetMapのロゴ画像 ※3単語をまとめて1単語(スペース無し) 最初にお伝えしたいこと ◼ OpenStreetMapとは ⚫ 何処かの企業の製品や提供しているサービスではありません ⚫ 世界中のみんなと一緒に「地図」を作る国際プロジェクトです

    ⚫ 2004年に英国から始まり、日本では2008年頃に始まりました ◼ みんなとは ⚫ 個人、企業やNGO、NPOなどの組織も含みます ⚫ 誰でも自由に参加出来るオープンな活動です ◼ OpenStreetMapは誰のもの? ⚫ 英国のOpenStreetMap Foundation(財団)が オープンデータ(ODbL)で提供しています P.11
  8. P.14 他の地図でも良いのでは? ◼ OpenStreetMap以外の地図じゃ出来ないの? ⚫ もちろん、地図やデータを他社に販売している会社もあります ⚫ そういったビジネスが行われているのは一般的に良くあります ◼ 他の地図やデータはその会社の商品です

    ⚫ ビジネス上の理由で、一般人は地図アプリを無料提供している 会社もありますが、あくまで無料なだけで自由には使えません ⚫ アプリは無料で使えても、地図を印刷してチラシ内に 使ったり、データを抜き出すのは、ほとんどの地図で 禁止されており、自由な地図ではありません P.14
  9. P.15 自由な地図じゃなくても良いのでは? ◼ 「自由な地図」で無くても、目的を達したら良くない? ⚫ はい。目的が達するなら、自由な地図で無くても構いません ⚫ ただ、「目的」とは何でしょうか。みんな目的は同じでしょうか ◼ 人や地域には事情があるので、いろんな目的があります

    ⚫ 需要が高い地図には様々な会社が参入するので、安くて充実した サービスが提供されますが、需要が少ない地図はどうでしょうか ⚫ また、地域の事情(人口、犯罪、災害など)、地図を 使う方の事情(言語、文化、視聴覚、身体など)も 考慮された地図は十分あるでしょうか P.15
  10. P.17 OpenStreetMapが実現したいこと 店舗情報 背景地図 店舗情報 背景地図 経路情報 投稿情報 経路情報 大企業が提供している地図

    OpenStreetMapと組み合わせた地図 企業、団体、個人が 必要な層を追加できる (車いす、アレルギー、保育園 防災、防犯、歴史など) OpenStreetMap 交通情報 ベースはOpenStreetMap 必要な所に注力出来るので 大企業に限らず活用出来る P.17
  11. P.18 様々な活動を支えるデータの共同整備 店舗情報 背景地図 経路情報 OpenStreetMapと組み合わせた地図 企業、団体、個人が 必要な層を追加できる (車いす、アレルギー、保育園 防災、防犯、歴史など)

    OpenStreetMap 例えば、商店街のランチマップを作って 印刷して配布する場合、道路や建物から 地図を描いていくのはコストが掛かる そのため、様々な活動でも利用している 基礎データ(道路や建物など)を共同で 整備することで、コスト削減が出来る また、地域に住んでいる方たちが地図を 直接更新することで、バリアフリーなど きめ細かいデータの整備が行える そして、マップを作る団体が活動停止し ても、新しい団体が生まれた時は、その データを引き継いで活動が再開出来る 国際プロジェクトなため、国境を超えた 国際的なマップを作ることが出来る P.18
  12. P.20 要するに ◼ OpenStreetMapは「地図では無い」 ⚫ 様々な方たちの想いを記録し続ける「データベース」が本質 ⚫ 地図は「主題(テーマ)」が重要だが、OpenStreetMapが地図では 無いのは、「主題が存在していない」ことからも分かる ◼

    一見無駄に見えるデータも残すことが出来る ⚫ 文化が違うと理解が難しくなる。例えば「鳥居と門の違い」は? ⚫ OpenStreetMapは、この違いもマッピングすることが推奨される ⚫ その上で、コミュニティ同士で多様性と標準化を話し合う ◼ OpenStreetMapから地図を作ることが出来る ⚫ 主題を持つことでOpenStreetMapから地図を作れる ⚫ 世界中の人たちが日々更新し、様々な活動に活かす 地理空間データベースのプラットフォームがOSM P.20
  13. P.22 サンプルアプリ ◼ Playgrounds-Easyのfork ⚫ https://github.com/K-Sakanoshita/Playgrounds-Easy ⚫ ご自身のリポジトリにforkしてPCにCloneしてください ⚫ Visual

    Studio CodeのLive Serverなどで実行させてください ◼ サンプルアプリの内容 ⚫ 別に開発している「遊具のある公園マップ」の簡易版 ⚫ 機能を極限まで削減して、ソースコードをシンプル化 P.22
  14. P.23 サンプルアプリの構成 ◼ ライブラリ ⚫ maplibre-gl 今回の主役1 ⚫ jquery Bootstrap4が必要なので残っています

    ⚫ Bootstrap4 Web画面のCSSフレームワーク ⚫ Osmtogeojson Overpass APIで取得したデータの変換 P.23
  15. P.24 サンプルアプリの構成 ◼ サンプルアプリ ⚫ dataフォルダ ✓ config.json アプリの設定が書かれたファイル ✓

    category.json OpenStreetMapのタグから種類名を判別するファイル ✓ marker.json OpenStreetMapのタグからアイコンを判別するファイル ✓ overpass.json Overpass APIを呼び出すクエリー文が書かれたファイル ✓ style.json MapLibreで地図を表示するためのスタイルファイル ⚫ libフォルダ ✓ winlib.js 画面操作などちょっとしたライブラリ ✓ maplib.js MapLibre操作などちょっとしたライブラリ ✓ poilib.js 地図に表示するマーカーを管理 ✓ overpasslib.js 今回の主役2「Overpass API」を操作 ✓ detaillib.js マーカーをクリックした時の詳細表示 ⚫ cmapmaker.js アプリの本体プログラム ⚫ initialize.js アプリの初期化プログラム P.24 その他 Image:画像 maki-icon:アイコン
  16. P.26 基本的な話をざっくりと ◼ 地図を表示するにはタイルサーバが必要 ⚫ OpenStreetMapプロジェクト自体は、タイルサーバの提供は慎重 ✓ タイルサーバは、Maxbox社やMaptiler社などのサービス利用を推奨している ✓ OpenStreetMap.orgサイト向けのタイルサーバは、常識の範囲内で利用可能

    ✓ 詳しくは、OSM Wiki「JA:タイル利用規約」に書かれているので参照 ⚫ OpenStreetMap Foundation Japanが提供しているタイルサーバを利用 ✓ 日本国内のコミュニティ向けにタイルサーバの提供を行っている ➢ https://tile.openstreetmap.jp/ ✓ 今回は3D地図を使うので、ベクタ形式のタイルサーバを利用する ➢ 以前は2D地図(ラスタ形式)のタイルサーバが一般的だった サンプルアプリの「◆が重なったボタン」を押せば ラスタタイルとベクタタイルの違いが分かります P.26
  17. P.27 地図表示に使うライブラリ ◼ MapLibre GL JS ⚫ Mapbox社のMapbox GL JSのライセンス変更によってforkされた

    地図を表示するためのライブラリ ⚫ そのため、Mapbox GL JS向けのドキュメントでも基本的な所は 共通点があるので、困ったことがあれば検索対象にするのも良い ◼ 地図を表示するだけなら、かなりシンプルに書ける P.27 【Index.html】スタイルシートとライブラリの読み込み <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/maplibre-gl.css" /> <script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script> <div id=“mapid”></div> ※地図を表示させる場所 【maplib.js】地図表示エリアの設定(init内) this.map = new maplibregl.Map({ "container": 'mapid', "style": this.styles[this.selectStyle], "maxZoom": Conf.maxZoom, "zoom": Conf.initZoom, "antialias": true, "hash": true, "center": Conf.initView });
  18. P.28 地図を表示するスタイル ◼ MapLibreは様々なタイルサーバに対応している ⚫ 今回はラスタタイルとベクタタイルの設定方法を説明する ⚫ 地図の表示は「new maplibregl.Map(パラメータ)」で出来る ✓

    実行結果を map 変数などに入れておく(マーカー追加などで利用する) style.jsonの設定は膨大。普通はスタイル編集ツールを使う P.28 【maplib.js】地図表示エリアの設定(init内) this.map = new maplibregl.Map({ "container": 'mapid', "style": this.styles[this.selectStyle], "maxZoom": Conf.maxZoom, "zoom": Conf.initZoom, "antialias": true, "hash": true, "center": Conf.initView }); 【maplib.js】地図表示エリアの設定(init内) this.stylesの中身はconfig.jsonに記載されている内容を読み込んだもの 最初のエントリ "OpenStreetMapJP": { "style": "./data/style.json" }, このファイルを参照する指示
  19. P.29 ざっくりstyle.jsonの概要説明 ◼ style.jsonはsourceとlayersエリアの設定が大事 ⚫ タイルサーバを提供している会社は、このstyle.jsonを作るための スタイル編集ツールを提供していることがあるので使ってみよう ラスタタイルの設定はconfig.jsonの「OSM_Standard」参照 P.29 {

    “style”: { “version”: 8, // 8固定 “sources”: { “ソース名”: { // ソース名は自分で決めて良い url: “タイルサーバのurl”, “type”: “vector” // ベクタタイルサーバは”vector” } }, “layers”: { { 背景の設定 }, // レイヤー設定がいろいろ { 土地利用の設定 } } }
  20. P.30 ラスタスタイルを追加してみよう ◼ config.json の “GSI_pale”の下に以下のコードを追加しよう P.30 "GSI_ort": { "style":

    { "version": 8, "sources": { "rtile": { "type": "raster", "tiles": ["https://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg"], "tileSize": 256, "maxzoom": 18, "attribution": "<a href='https://www.gsi.go.jp/kikakuchousei/kikakuchousei40182.html'>国土地理院(オルソ画像) | &copy OpenStreetMap contributors</a>" } }, "layers": [ { "id": "raster-tiles", "type": "raster", "source": "rtile" } ] } }
  21. P.31 地図にアイコンを追加する方法 ◼ createElementでdiv要素を作り、スタイルを設定した上で maplibregl.Markerメソッドでdivを指定し、座標などを追加 した上でaddTo(map)メソッドで追加する ⚫ アイコン画像やテキストはdiv要素中のinnerHTMLに書けば良い P.31 //

    maplib.js より addMarker(params) { var icon = document.createElement('div'); icon.style.width = `${params.size + params.span_width}px`; icon.style.height = `${params.size}px`; let marker = new maplibregl.Marker(icon).setLngLat(params.poi.lnglat).addTo(this.map); marker.getElement().innerHTML= params.html; return marker; }; ※maplib.js の addMarker は poilib.js の setMarker から 呼び出されている(setMarkerでHTMLなどを生成)
  22. P.34 Overpass API ◼ OSM地図データから個別に選択された部分を取り出すAPI ⚫ Web APIによる地理空間データベースとして提供されている ⚫ 読み取り専用だが、ユーザー認証が不要なので気軽に使える

    ◼ OpenStreetMap公式のOverpass APIは提供されていない ⚫ ドイツやフランス、ロシアの企業や団体が個別に提供されている ⚫ OSM WikiにOverpass API提供サーバーの一覧がある ✓ https://wiki.openstreetmap.org/wiki/Overpass_API ⚫ いずれも無料で使えるが、常識の範囲内での利用が良い ✓ ドイツのサーバはよく使われる半公式な存在だが、短時間で何度も APIを叩くと、1分ほどアクセスを拒否されるなど制約もある P.34
  23. P.35 Overpass QL ◼ Overpass APIはWeb APIで公開されている ◼ サーバAPIアドレス以降に下記のパラメータを指定する ⚫

    ?data=[out:json][timeout:30][bbox:Area];(Query);out body meta;>;out skel;`; ⚫ Area 緯度経度 (例) [bbox: 34.75,135.32,34.77,135.35] ⚫ Query検索条件(例) node["leisure"="park"]; 上記のQuery言語のことをOverpass QLと呼ぶ P.35 ノード(点)の公園を探す 北西の緯度経度と 南東の緯度経度で 四角い範囲を返す // overpass.js より let LL = mapl.getLL(), query = ""; let maparea = LL.SE.lat + ',' + LL.NW.lng + ',' + LL.NW.lat + ',' + LL.SE.lng; overpass.forEach(val => query += val + ";"); let url = Conf.OverPassServer + `?data=[out:json][timeout:30] [bbox:${maparea}];(${query});out body meta;>;out skel;`; console.log("OverPassControl: getGeojson: " + url);
  24. P.36 Overpass Turboで遊んでみよう ◼ Overpass QLを触れる以下のサイトを開こう ⚫ https://overpass-turbo.eu/ ◼ 大阪市へ移動し、「ウィザード」ボタンを押す

    ◼ 「toilets in osaka」と入力し、クエリを作成して実行を押す P.36 toilets in osaka 「クエリを作成して実行」を押す
  25. P.37 Overpass QL ◼ Overpass QLは様々な機能が用意されている詳しくはWiki ⚫ https://wiki.openstreetmap.org/wiki/JA:Overpass_API/Overpass_QL ⚫ Chat

    GPT便利。例「大阪市内の図書館を出すOverpass QLを教えて」 ◼ 基本的なクエリの書き方 ⚫ node or way or relation[key=value] ✓ node : 点 ✓ way : 線・エリア ✓ relation : 組み合わせ ✓ key=value : OSMのタグ(key=value形式) ⚫ OSMのタグは下記参照 ✓ https://wiki.openstreetmap.org/wiki/JA:Map_Features ✓ 世界中のあらゆる動かないものをマッピング出来るよう日々見直し中 P.37
  26. P.38 サンプルアプリの設定 ◼ dataフォルダ内のoverpass.jsonを参照 ◼ サンプルアプリでは、公園、児童公園、リラクゼーション グランド、公園の遊具を取得するクエリになっている P.38 "overpass": [

    "node[¥"leisure¥"=¥"park¥"]", "way[¥"leisure¥"=¥"park¥"]", "node[¥"leisure¥"=¥"playground¥"]", "way[¥"leisure¥"=¥"playground¥"]", "way[¥"landuse¥"=¥"recreation_ground¥"]", "relation[¥"leisure¥"=¥"park¥"]", "relation[¥"leisure¥"=¥"playground¥"]", "relation[¥"landuse¥"=¥"recreation_ground¥"]", "node[¥"playground¥"]", "way[¥"playground¥"]" ],
  27. P.40 (再掲)サンプルアプリの構成 ◼ サンプルアプリ ⚫ dataフォルダ ✓ config.json アプリの設定が書かれたファイル ✓

    category.json OpenStreetMapのタグから種類名を判別するファイル ✓ marker.json OpenStreetMapのタグからアイコンを判別するファイル ✓ overpass.json Overpass APIを呼び出すクエリー文が書かれたファイル ✓ style.json MapLibreで地図を表示するためのスタイルファイル ⚫ libフォルダ ✓ winlib.js 画面操作などちょっとしたライブラリ ✓ maplib.js MapLibre操作などちょっとしたライブラリ ✓ poilib.js 地図に表示するマーカーを管理 ✓ overpasslib.js 今回の主役2「Overpass API」を操作 ✓ detaillib.js マーカーをクリックした時の詳細表示 ⚫ cmapmaker.js アプリの本体プログラム ⚫ initialize.js アプリの初期化プログラム P.40 その他 Image:画像 maki-icon:アイコン
  28. P.41 サンプルアプリの構成 ◼ サンプルアプリの構成は以下のイメージ P.41 initialize.js ライブラリの読み込み 設定ファイルの読み込み 地図初期化、イベント登録 cmapmaker.js

    地図画面上にあるボタンや マーカーから呼び出される winlib.js maplib.js poilib.js overpasslib.js detaillib.js cmapmaker.jsから必要に応じて呼び出される maplibre-gl MapLibreはmaplib.js/経由で間接的に呼び出す タイルサーバ Overpassサーバ
  29. P.43 何を開発するか考える ◼ しばらくサンプルアプリを遊んでみよう ⚫ 不便な所、機能を追加したい所を考えてみよう ⚫ 遊具以外に表示したい地物(アイコン)を考えてみよう ◼ 表示したいアイコンを思いついた方

    ⚫ 以下のサイトを開き、OSMタグを調べてみよう ⚫ https://wiki.openstreetmap.org/wiki/JA:Map_Features ✓ 例えばトイレは 「amenity=toilets」でマッピング ✓ 消火器、自動販売機、ベンチ、ゴミ箱などもあります ✓ 好きな組み合わせもOK。どんなマップを作りますか? P.43
  30. P.45 まずはサイトタイトルの変更 ◼ サイトタイトルを変更 ⚫ index.htmlのタイトルタグを変更しよう ◼ 説明文の見直し ⚫ config.jsonのaboutTitle~licenceMessageを変更しよう

    ✓ メニューやタイトルをクリックした時のメッセージが変化します ✓ cmapmaker.jsのviewMessageで表示させているので確認してみよう ◼ メニューの追加、変更 ⚫ config.jsonのmenuを参考に、メニューを変更して見よう ⚫ メニュー表示は「画面左上」と「詳細表示の画面左上」がある ✓ 画面左上は“menu“、 「詳細表示の画面左上」は”detailMenu”で変更できる P.45
  31. P.46 表示させる地物の変更 ◼ 表示させる地物を変更する ⚫ ./data/overpass.json のタグを見直そう ✓ 複数のタグを書いた場合、「and」では無く「or」でクエリは計算される ⚫

    tags内の書式は「overpassから取得したデータの絞り込み用」 ✓ 例えば、「amenity」で取得すると本当に様々なデータが取得される ✓ この場合、tagsで「amenity=toiltes」と書けばトイレだけ絞り込みが出来る ⚫ expressionの書式はラインの描画用 ✓ 敷地(way or relation)の場合、自動的に ラインを書くので、その描画色を指定する ※塗りつぶしは行いません P.46 "tags": [ "leisure=park", "leisure=playground", "landuse=recreation_ground", "playground" ], "expression": { "stroke": "#409040", "stroke-width": 2 }
  32. P.47 マップコントロールの追加 ◼ MapLibreには任意のコントロールを追加出来る P.47 // maplib.js より addControl(position, domid,

    html, cname) { // add mapl control class HTMLControl { onAdd(map) { this._map = map; this._container = document.createElement('div'); this._container.id = domid; this._container.className = 'maplibregl-ctrl ' + cname; this._container.innerHTML = html; this._container.style = "transform: initial;"; return this._container; } onRemove() { this._container.parentNode.removeChild(this._container); this._map = undefined; } } this.map.addControl(new HTMLControl(), position); };
  33. P.48 マップコントロールの追加 ◼ initialize.jsの40行目付近に以下のコードを追加すると ⚫ 「hello」と表示するコントロールを地図の左下に追加できます ⚫ 「Hello」をHTMLにすれば、本格的なコントロールが追加できる ⚫ index.htmlの後半に<div

    id=“basemenu”>で囲われたHTMLがあるので それを参考にして、index.html内にメニューを追加することも出来る ◼ アイコン情報の一覧表示方法 ⚫ デベロッパーツール(F12)を開き、以下を入力してみる ⚫ アイコンのID、名称、種別、緯度経度を配列で返してくれる ⚫ 画面左上のメインメニューにテーブル表示させるなども可能 ✓ テーブルをどう表示させるかはお任せします(ライブラリ利用もあり) ✓ キーワード検索機能とかあると便利ですよね P.48 mapl.addControl("bottom-left",“Hello",poiCont.makeList()) poiCont.makeList()
  34. P.49 他にも機能や設定があります ◼ 処理中を示すアニメーション制御 ◼ config.json で設定可能な項目 ◼ その他 ⚫

    アイコンのファイル名は ./data/marker.json で指定 ⚫ 「公園」などの種別名は ./data/category.json で指定 P.49 winCont.spinner(true); // falseにすると消える "splashUrl": "./image/Playgrounds.png", “initZoom”: 14, // 初期ズーム(大きいほどズームする) “maxZoom”: 21, // 最大ズーム(21だと一軒家レベル) “initView”: [ // 初期表示の緯度経度 135.4828, 34.7212 ], “PoiViewZoom”: 13, // アイコンを表示し始めるズーム
  35. P.53 参考情報 ◼ OSM Wiki(Overpass API/QL) ⚫ https://wiki.openstreetmap.org/wiki/Overpass_API ⚫ https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL

    ◼ Overpass関連の説明記事 ⚫ https://qiita.com/K-Sakanoshita/items/0c610d76bba2e7245ea5 ⚫ https://qiita.com/Aruneko/items/ef2e7efb4925a2f8515f ◼ MapLibre(Official Site) ⚫ https://maplibre.org/maplibre-gl-js/docs/API/ ⚫ MapLibreで使えるベクタタイルサーバ(OSMFJ提供) ✓ https://wiki.openstreetmap.org/wiki/Japan/OSMFJ_Tileserver P.53
  36. P.54 参考情報(続き) ◼ OpenStreetMap ⚫ 世界がOpenStreetMapを必要とする理由 https://qiita.com/nyampire/items/073c850f083cf9fb8d35 ⚫ learn OSM(はじめてからのOpenStreetMapガイド)

    https://learnosm.org/ja/ ◼ 講師(坂ノ下)のサイト ⚫ GitHub K-Sakanoshita https://github.com/K-Sakanoshita ✓ OpenStreetMapを駆使したWebアプリを公開中 ⚫ まち歩きマップメーカー(自由に加工&使える地図画像を作る) https://armd-02.github.io/mapmaker/ ⚫ コミュニティマップメーカー(今回のサンプルアプリの大元) https://github.com/K-Sakanoshita/community_mapmaker ✓ 公式だけど、少し古いソースコードなのが残念(なんとかします) P.54