aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/components/ParkMap.astro
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/ParkMap.astro
parentcf5468ffaef1b43e5cc529af2d072f1f08af9ba4 (diff)
parks: 複数ポリゴンとOSMポリゴンの置き換えに対応
同じ公園名の複数ポリゴンをまとめてズーム・アイコン表示する。import-manual-parks.py に --override-name を追加し、手入力ポリゴンでOSMを置き換えられるようにした。草地広場・多目的広場を一覧の検索・ピクニック絞り込みに反映。
Diffstat (limited to 'src/components/ParkMap.astro')
-rw-r--r--src/components/ParkMap.astro41
1 files changed, 37 insertions, 4 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",