diff options
| author | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-25 12:24:24 +0900 |
|---|---|---|
| committer | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-25 12:24:24 +0900 |
| commit | a01062f43d36112c00d5c007ac9d488c14d8fb0d (patch) | |
| tree | b99ddac9928e02b9cd07d372fa42842a348bfb61 /src/data/parks-rows.ts | |
| parent | a71727538f65ab4f10f5239550be82590f9d47d1 (diff) | |
parks: アイコン・フィルタ・編集画面を更新し、公開を一時停止
- 遊具アイコンをSVGRepo素材に差し替え、施設種別をアイコン表示
- フィルタに種類・遊具・ピクニックを追加し、適用時の地図移動を停止
- 現在地ボタンを追跡トグルに変更し、初回以外は地図を動かさない
- 編集画面を市内公園・周辺公園・公共施設の4タブに拡張
- 公園ページをドラフト化し、サイドバーとPWAの公開を停止
Diffstat (limited to 'src/data/parks-rows.ts')
| -rw-r--r-- | src/data/parks-rows.ts | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/data/parks-rows.ts b/src/data/parks-rows.ts new file mode 100644 index 0000000..39d7ae0 --- /dev/null +++ b/src/data/parks-rows.ts @@ -0,0 +1,141 @@ +import parksData from "@/data/kodaira-parks.json"; +import osmData from "@/data/parks-geojson"; +import nearbyData from "@/data/kodaira-nearby-parks.json"; +import facilitiesData from "@/data/kodaira-facilities.json"; +import nearbyFacilitiesData from "@/data/kodaira-nearby-facilities.json"; + +export type Park = Record<string, string>; + +function nearbyCentroid(feature: any): [number, number] { + const g = feature.geometry; + if (g.type === "Point") return [g.coordinates[1], g.coordinates[0]]; + const ring = g.type === "Polygon" ? g.coordinates[0] : g.coordinates[0][0]; + if (!ring?.length) return [0, 0]; + let lat = 0; + let lon = 0; + for (const [x, y] of ring) { + lon += x; + lat += y; + } + return [lat / ring.length, lon / ring.length]; +} + +function mapsQueryForNearby(name: string, city: string): string { + return name ? (city && !name.includes(city) ? `${city}${name}` : name) : ""; +} + +// 「小平市小川町2-1325」→「小川町」。公共施設の住所から町名を取り出す。 +function townFromAddress(address: string): string { + const match = /^小平市(.+?)(?:\d|$)/.exec(address || ""); + return match ? match[1].trim() : ""; +} + +// 市境500m以内の市外公園。小平市の公園と同じ表に「市外」バッジ付きで並べる。 +const nearbyRows: Park[] = ((nearbyData as any).features ?? []).map((f: any) => { + const p = f.properties || {}; + const [lat, lon] = nearbyCentroid(f); + const area = Math.round(Number(p.area_m2) || 0); + const name = String(p.name || "").trim(); + const mapsQuery = name + ? mapsQueryForNearby(name, String(p.city || "")) + : `${lat},${lon}`; + return { + "公園名": name, + "住所": p.city ? `${p.city}(市外)` : "市外", + "町名": "市外", + "面積㎡": area ? String(area) : "", + "500㎡以上": "", + "種別": "市外", + "南西部指定管理": "", + "トイレ": "", + "水飲み場": "", + "ベンチ・椅子": "", + "テーブル": "", + "パーゴラ": "", + "東屋": "", + "防災用具": "", + "ボール遊び": "", + "遊具": "", + "駐車場": "", + "その他設備": "", + "緯度": String(lat), + "経度": String(lon), + "備考": `市外・小平市境から約${Math.round(Number(p.distance_m) || 0)}m${ + f.geometry?.type === "Point" ? "・範囲未取得" : "" + }`, + "設置者": "市外", + "状態": "", + "地図キー": p.key || `${p.osm_type || ""}/${p.osm_id || ""}`, + "地図URL": `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(mapsQuery)}`, + }; +}); + +// 市内・市外の公共施設を公園一覧と同じ行形式にする。 +function facilityRow(f: any, nearby: boolean): Park { + const name = String(f.name || "").trim(); + const type = String(f.type || ""); + const city = String(f.city || "").trim(); + const address = String(f.address || city || (nearby ? "市外" : "")).trim(); + const hours = f.hours ? `開館 ${f.hours}` : ""; + const closed = f.closed ? `休館 ${f.closed}` : ""; + const note = [type, hours, closed, f.note].filter(Boolean).join("。"); + const mapsQuery = nearby ? mapsQueryForNearby(name, city) : `小平市${name}`; + const toilet = f.toilet === "○" ? "○" : ""; + const water = f.water === "○" ? "○" : ""; + return { + "公園名": name, + "住所": address, + "町名": nearby ? "市外" : townFromAddress(address), + "面積㎡": "", + "500㎡以上": "", + "種別": type, + "南西部指定管理": "", + "トイレ": toilet, + "水飲み場": "", + "給水": water, + "ベンチ・椅子": "", + "テーブル": "", + "パーゴラ": "", + "東屋": "", + "防災用具": "", + "ボール遊び": "", + "遊具": "", + "駐車場": "", + "その他設備": "", + "緯度": f.lat != null ? String(f.lat) : "", + "経度": f.lon != null ? String(f.lon) : "", + "備考": note, + "設置者": nearby ? "市外" : "小平市", + "状態": "", + "地図URL": `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(mapsQuery)}`, + "公式URL": String(f.source || ""), + "施設": "1", + }; +} + +const facilityRows: Park[] = [ + ...(facilitiesData as any[]).map((f) => facilityRow(f, false)), + ...(nearbyFacilitiesData as any[]).map((f) => facilityRow(f, true)), +]; + +export const parks: Park[] = [ + ...(parksData as Park[]), + ...nearbyRows, + ...facilityRows, +]; + +export const total = parks.length; + +export const towns = [...new Set(parks.map((p) => p["町名"]).filter(Boolean))].sort( + (a, b) => a.localeCompare(b, "ja"), +); + +// OpenStreetMapにポリゴンがあり、地図から位置を表示できる公園名。 +export const mappedNames = new Set<string>([ + ...(osmData as any).features + .map((f: any) => f.properties?.our_name) + .filter(Boolean), + ...((nearbyData as any).features ?? []) + .map((f: any) => String(f.properties?.name || "").trim()) + .filter(Boolean), +]); |
