From a01062f43d36112c00d5c007ac9d488c14d8fb0d Mon Sep 17 00:00:00 2001 From: Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> Date: Sun, 25 Oct 2026 12:24:24 +0900 Subject: parks: アイコン・フィルタ・編集画面を更新し、公開を一時停止 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 遊具アイコンをSVGRepo素材に差し替え、施設種別をアイコン表示 - フィルタに種類・遊具・ピクニックを追加し、適用時の地図移動を停止 - 現在地ボタンを追跡トグルに変更し、初回以外は地図を動かさない - 編集画面を市内公園・周辺公園・公共施設の4タブに拡張 - 公園ページをドラフト化し、サイドバーとPWAの公開を停止 --- scripts/make-park-qgis-kit.py | 65 ++++++++- scripts/park-editor.html | 254 ++++++++++++++++++++++++++++-------- scripts/park-editor.mjs | 106 ++++++++++++--- scripts/update-nearby-facilities.py | 179 +++++++++++++++++++++++++ scripts/update-nearby-parks.py | 243 +++++++++++++++++++++++++++++++++- 5 files changed, 771 insertions(+), 76 deletions(-) create mode 100644 scripts/update-nearby-facilities.py (limited to 'scripts') diff --git a/scripts/make-park-qgis-kit.py b/scripts/make-park-qgis-kit.py index 0df6d5a..b84630e 100644 --- a/scripts/make-park-qgis-kit.py +++ b/scripts/make-park-qgis-kit.py @@ -25,8 +25,10 @@ ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) OURS = os.path.join(ROOT, "src", "data", "kodaira-parks.json") OSM = os.path.join(ROOT, "src", "data", "kodaira-parks-osm.json") MANUAL = os.path.join(ROOT, "src", "data", "kodaira-parks-manual.json") +NEARBY = os.path.join(ROOT, "src", "data", "kodaira-nearby-parks.json") OUT_DIR = os.path.join(ROOT, "reference", "qgis") MANUAL_QGIS = os.path.join(OUT_DIR, "manual-parks.geojson") +NEARBY_MANUAL_QGIS = os.path.join(OUT_DIR, "nearby-parks-manual.geojson") if hasattr(sys.stdout, "reconfigure"): sys.stdout.reconfigure(encoding="utf-8") @@ -85,6 +87,7 @@ def main(): ours = load(OURS) osm = load(OSM) manual = load(MANUAL) + nearby = load(NEARBY) # QGISで描いたが、まだ取り込んでいないポリゴンの公園名 drawn_names = set() @@ -100,6 +103,19 @@ def main(): except (ValueError, OSError) as e: print(f" warning: {MANUAL_QGIS} を読めません: {e}", file=sys.stderr) + nearby_drawn_names = set() + if os.path.exists(NEARBY_MANUAL_QGIS): + try: + for feat in load(NEARBY_MANUAL_QGIS).get("features", []): + p = feat.get("properties") or {} + if not has_coords(feat.get("geometry")): + continue + name = str(p.get("our_name") or "").strip() + if name: + nearby_drawn_names.add(norm(name)) + except (ValueError, OSError) as e: + print(f" warning: {NEARBY_MANUAL_QGIS} を読めません: {e}", file=sys.stderr) + polygons = [] covered = set() osm_by_id = {} @@ -170,10 +186,42 @@ def main(): "drawn": norm(name) in drawn_names, "lat": lat, "lon": lon, + "source": "city", + }, + "geometry": {"type": "Point", "coordinates": [lon, lat]}, + } + ) + + # 市外の近隣公園のうち、まだポリゴンがないもの(点)も描画対象に含める。 + nearby_points = 0 + for feat in nearby.get("features", []): + geom = feat.get("geometry") or {} + if geom.get("type") != "Point": + continue + p = feat.get("properties") or {} + name = str(p.get("name") or "").strip() + if not name: + continue + lon, lat = geom["coordinates"][:2] + points.append( + { + "type": "Feature", + "properties": { + "no": len(points) + 1, + "our_name": name, + "address": f"{p.get('city') or '市外'}(市外)", + "kind": "市外の近隣公園", + "official_area_m2": p.get("area_m2", ""), + "drawn": norm(name) in nearby_drawn_names, + "lat": lat, + "lon": lon, + "source": "nearby", + "distance_m": p.get("distance_m", ""), }, "geometry": {"type": "Point", "coordinates": [lon, lat]}, } ) + nearby_points += 1 counts = { "covered": len(covered), @@ -181,6 +229,7 @@ def main(): "no_point": len(no_point), "already": len(already), "drawn": sum(1 for p in points if p["properties"]["drawn"]), + "nearby_points": nearby_points, } os.makedirs(OUT_DIR, exist_ok=True) @@ -193,6 +242,7 @@ def main(): - ポリゴン整備済み: {counts['covered']} 件 - OSM側に既にポリゴンあり(未リンク): {counts['already']} 件 - ポリゴン未整備: {counts['missing']} 件(うち手入力済み・未取り込み {counts['drawn']} 件、座標なし {counts['no_point']} 件) +- 市外の近隣公園(点): {counts['nearby_points']} 件 ## 1. QGIS に背景地図を追加 @@ -206,7 +256,7 @@ def main(): ## 2. 下地を読み込む -- `parks-without-polygon.geojson` … まだポリゴンがない公園(点)。`our_name` に公園名が入っています +- `parks-without-polygon.geojson` … まだポリゴンがない公園(点)。`our_name` に公園名が入っています。`source` が `city` なら小平市内、`nearby` なら市外の近隣公園です - `existing-parks.geojson` … 整備済みポリゴン。二重描き防止用 ## 3. ポリゴン用レイヤを作る @@ -225,6 +275,15 @@ def main(): > `our_name` を空欄にしても、取り込み時に最寄りの公園点から自動で判定します > (既定 60m 以内・曖昧でない場合のみ)。 +### 市外の近隣公園を描く場合 + +`parks-without-polygon.geojson` の `source` が `nearby` の点は、小平市外の近隣公園です。 +小平市内の公園とは別のファイルに描きます。 + +1. `reference/qgis/nearby-parks-manual.geojson` を新規作成(Polygon / EPSG:4326、`our_name` フィールド) +2. 公園の輪郭を描き、`our_name` に点の名前を入れる +3. `py -X utf8 scripts/update-nearby-parks.py` で取り込む + ## 4. 取り込む ```bash @@ -234,11 +293,12 @@ py -X utf8 scripts/import-manual-parks.py reference/qgis/manual-parks.geojson `--dry-run` で公園名・面積・台帳面積との倍率・警告を確認してから本実行してください。 台帳面積の 0.7〜1.5 倍を外れると警告が出ます。 +市外の近隣公園は `py -X utf8 scripts/update-nearby-parks.py` で取り込みます。 取り込み後に `npm run build` で地図と表を確認します。 ## 進捗の管理 -`parks-without-polygon.geojson` の `drawn` は、`manual-parks.geojson` に同じ `our_name` のポリゴンがあると `true` になります。 +`parks-without-polygon.geojson` の `drawn` は、`manual-parks.geojson` または `nearby-parks-manual.geojson` に同じ `our_name` のポリゴンがあると `true` になります。 - 属性テーブルで `drawn` を確認できます - スタイルを `drawn = true` で灰色にすると、残りが分かりやすくなります @@ -258,6 +318,7 @@ py -X utf8 scripts/import-manual-parks.py reference/qgis/manual-parks.geojson print(f"ポリゴン整備済み: {counts['covered']} 件") print(f"OSM側に既にポリゴンあり(未リンク): {counts['already']} 件") print(f"ポリゴン未整備: {counts['missing']} 件(座標なし {counts['no_point']} 件)") + print(f"市外の近隣公園(点): {counts['nearby_points']} 件") if no_point: print("座標がないため地図に出せない公園(先に kodaira-parks.json の緯度・経度を埋める):") for n in no_point: diff --git a/scripts/park-editor.html b/scripts/park-editor.html index 8c519e9..868a510 100644 --- a/scripts/park-editor.html +++ b/scripts/park-editor.html @@ -3,17 +3,22 @@ -公園データ編集 +公園・施設データ編集