aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/components
diff options
context:
space:
mode:
authorYasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com>2026-10-29 14:44:19 +0900
committerYasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com>2026-10-29 14:44:19 +0900
commit17f6009bfc6589d43e10233040b125675d24c5c8 (patch)
tree8f6606e4b5b086e3e61792a6965b27867bed5c18 /src/components
parentcf5468ffaef1b43e5cc529af2d072f1f08af9ba4 (diff)
parks: 複数ポリゴンとOSMポリゴンの置き換えに対応
同じ公園名の複数ポリゴンをまとめてズーム・アイコン表示する。import-manual-parks.py に --override-name を追加し、手入力ポリゴンでOSMを置き換えられるようにした。草地広場・多目的広場を一覧の検索・ピクニック絞り込みに反映。
Diffstat (limited to 'src/components')
-rw-r--r--src/components/ParkMap.astro41
-rw-r--r--src/components/ParksTable.astro8
2 files changed, 44 insertions, 5 deletions
diff --git a/src/components/ParkMap.astro b/src/components/ParkMap.astro
index 7ca85ab..ac85c0e 100644
--- a/src/components/ParkMap.astro
+++ b/src/components/ParkMap.astro
@@ -629,7 +629,21 @@
lyr._parkName = ourName;
lyr._osmName = name;
allLayers.push(lyr);
- if (ourName) layersByName.set(ourName, lyr);
+ if (ourName) {
+ const existing = layersByName.get(ourName);
+ if (!existing) {
+ layersByName.set(ourName, lyr);
+ } else if (
+ typeof existing.getLayers === "function" &&
+ typeof existing.addLayer === "function"
+ ) {
+ existing.addLayer(lyr);
+ } else {
+ const group = L.featureGroup([existing, lyr]);
+ group._osmName = existing._osmName;
+ layersByName.set(ourName, group);
+ }
+ }
if (ourName) {
lyr.on("add", () => {
@@ -760,6 +774,25 @@
addFacilities(nearbyFacilities as any[], true);
publicFacilityLayer.addTo(map);
+ // 道路で分かれた公園など、同じ公園に複数のポリゴンがある場合は
+ // いちばん大きいポリゴンの中心にアイコンを置く。
+ const centerOfLayer = (lyr: any) => {
+ if (lyr && typeof lyr.getLayers === "function") {
+ let best: any = null;
+ let bestArea = -1;
+ for (const child of lyr.getLayers()) {
+ const b = child.getBounds();
+ const area = (b.getNorth() - b.getSouth()) * (b.getEast() - b.getWest());
+ if (area > bestArea) {
+ bestArea = area;
+ best = child;
+ }
+ }
+ if (best) return best.getBounds().getCenter();
+ }
+ return lyr.getBounds().getCenter();
+ };
+
// 拡大時だけ表示する設備アイコン(トイレ・水飲み場)
// 一覧と一致した公園のポリゴン内にだけ表示する。
const facilityLayer = L.layerGroup();
@@ -778,7 +811,7 @@
);
}
const clock = (p["時計"] || "").trim();
- if (clock === "○" || clock === "あり" || clock === "有") {
+ if (clock === "○" || clock === "あり" || clock === "有" || clock === "1") {
icons.push(
'<span class="park-fac park-fac-clock" title="時計あり" aria-label="時計あり">⏰</span>',
);
@@ -795,7 +828,7 @@
);
}
if (!icons.length) return;
- const center = lyr.getBounds().getCenter();
+ const center = centerOfLayer(lyr);
L.marker([center.lat, center.lng], {
icon: L.divIcon({
className: "park-fac-markers",
@@ -854,7 +887,7 @@
);
}
if (!icons.length) return;
- const center = lyr.getBounds().getCenter();
+ const center = centerOfLayer(lyr);
L.marker([center.lat, center.lng], {
icon: L.divIcon({
className: "park-play-markers",
diff --git a/src/components/ParksTable.astro b/src/components/ParksTable.astro
index f0864d6..17841cc 100644
--- a/src/components/ParksTable.astro
+++ b/src/components/ParksTable.astro
@@ -123,13 +123,15 @@ function facTokens(p: Park): string {
const ball = p["ボール遊び"];
if (ball && ball !== "禁止") tokens.push("ball");
const clock = (p["時計"] || "").trim();
- if (clock === "○" || clock === "あり" || clock === "有") tokens.push("clock");
+ if (clock === "○" || clock === "あり" || clock === "有" || clock === "1") tokens.push("clock");
if (p["南西部指定管理"]) tokens.push("cm");
// ピクニック広場・芝生広場・テーブルのある公園。
const picnicText = `${p["公園名"] || ""} ${p["種別"] || ""} ${p["その他設備"] || ""} ${p["備考"] || ""}`;
if (
(p["テーブル"] || "").trim() ||
p["種別"] === "広場" ||
+ p["草地広場"] ||
+ p["多目的広場"] ||
picnicText.includes("芝生") ||
picnicText.includes("ピクニック") ||
picnicText.includes("広場")
@@ -145,6 +147,8 @@ const DETAIL_FIELDS: { key: string; icon: string }[] = [
{ key: "ベンチ・椅子", icon: "🪑" },
{ key: "テーブル", icon: "🍽" },
{ key: "シェルター等", icon: "⛱" },
+ { key: "草地広場", icon: "🌿" },
+ { key: "多目的広場", icon: "🏟" },
{ key: "防災用具", icon: "🧯" },
{ key: "遊具", icon: "🎠" },
{ key: "時計", icon: "⏰" },
@@ -211,6 +215,8 @@ function searchIndex(p: Park): string {
p["トイレ"],
p["水飲み場"],
p["給水"],
+ p["草地広場"] ? "草地広場" : "",
+ p["多目的広場"] ? "多目的広場" : "",
p["ボール遊び"],
...DETAIL_FIELDS.map((f) => p[f.key]),
]