| <script lang="ts"> |
| import { onMount } from 'svelte'; |
| import { POSITRON } from '$lib/components/map/baseStyle'; |
| import 'maplibre-gl/dist/maplibre-gl.css'; |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| const ADDR: [number, number] = [-74.0095, 40.6781]; |
|
|
| let container: HTMLDivElement | null = $state(null); |
|
|
| |
| |
| |
| |
| type Map = import('maplibre-gl').Map; |
| let map: Map | null = null; |
|
|
| onMount(() => { |
| let cancelled = false; |
| (async () => { |
| if (!container || cancelled) return; |
| const maplibre = await import('maplibre-gl'); |
| if (cancelled || !container) return; |
| map = new maplibre.Map({ |
| container, |
| style: POSITRON, |
| center: ADDR, |
| zoom: 14.5, |
| interactive: false, |
| attributionControl: false, |
| }); |
|
|
| map.on('load', () => { |
| if (!map) return; |
| |
| |
| map.addSource('fema-ae', { |
| type: 'geojson', |
| data: { |
| type: 'FeatureCollection', |
| features: [{ |
| type: 'Feature', properties: {}, |
| geometry: { |
| type: 'Polygon', |
| coordinates: [[ |
| [-74.0140, 40.6790], |
| [-74.0070, 40.6800], |
| [-74.0050, 40.6770], |
| [-74.0090, 40.6755], |
| [-74.0140, 40.6790], |
| ]], |
| }, |
| }], |
| }, |
| }); |
| map.addLayer({ |
| id: 'fema-ae-fill', type: 'fill', source: 'fema-ae', |
| paint: { 'fill-color': '#2A6FA8', 'fill-opacity': 0.22 }, |
| }); |
| map.addLayer({ |
| id: 'fema-ae-line', type: 'line', source: 'fema-ae', |
| paint: { 'line-color': '#2A6FA8', 'line-width': 1, 'line-dasharray': [3, 2] }, |
| }); |
|
|
| |
| map.addSource('hwm-contour', { |
| type: 'geojson', |
| data: { |
| type: 'Feature', properties: {}, |
| geometry: { |
| type: 'LineString', |
| coordinates: [ |
| [-74.0125, 40.6790], |
| [-74.0105, 40.6792], |
| [-74.0080, 40.6790], |
| [-74.0060, 40.6786], |
| ], |
| }, |
| }, |
| }); |
| map.addLayer({ |
| id: 'hwm-contour-line', type: 'line', source: 'hwm-contour', |
| paint: { 'line-color': '#0B5394', 'line-width': 1.4 }, |
| }); |
|
|
| |
| map.addSource('proxy-311', { |
| type: 'geojson', |
| data: { |
| type: 'FeatureCollection', |
| features: [ |
| [-74.0118, 40.6770], [-74.0114, 40.6767], [-74.0121, 40.6772], |
| ].map((c) => ({ |
| type: 'Feature', properties: {}, |
| geometry: { type: 'Point', coordinates: c }, |
| })), |
| }, |
| }); |
| map.addLayer({ |
| id: 'proxy-311-circle', type: 'circle', source: 'proxy-311', |
| paint: { |
| 'circle-radius': 3, |
| 'circle-color': 'transparent', |
| 'circle-stroke-color': '#6B6B6B', |
| 'circle-stroke-width': 1, |
| }, |
| }); |
|
|
| |
| |
| |
| map.addSource('floodnet', { |
| type: 'geojson', |
| data: { |
| type: 'Feature', properties: {}, |
| geometry: { type: 'Point', coordinates: [-74.0103, 40.6788] }, |
| }, |
| }); |
| map.addLayer({ |
| id: 'floodnet-pin', type: 'circle', source: 'floodnet', |
| paint: { |
| 'circle-radius': 4, |
| 'circle-color': '#0B5394', |
| 'circle-stroke-color': '#FFFFFF', |
| 'circle-stroke-width': 1, |
| }, |
| }); |
|
|
| |
| map.addSource('addr', { |
| type: 'geojson', |
| data: { |
| type: 'Feature', properties: {}, |
| geometry: { type: 'Point', coordinates: ADDR }, |
| }, |
| }); |
| map.addLayer({ |
| id: 'addr-ring', type: 'circle', source: 'addr', |
| paint: { |
| 'circle-radius': 9, |
| 'circle-color': 'transparent', |
| 'circle-stroke-color': '#0F172A', |
| 'circle-stroke-width': 1.4, |
| }, |
| }); |
| map.addLayer({ |
| id: 'addr-dot', type: 'circle', source: 'addr', |
| paint: { 'circle-radius': 3, 'circle-color': '#0F172A' }, |
| }); |
| }); |
| })(); |
|
|
| return () => { |
| cancelled = true; |
| if (map) { |
| map.remove(); |
| map = null; |
| } |
| }; |
| }); |
| </script> |
|
|
| <div class="land-mapmini" role="img" aria-label="Live mini-map preview of Red Hook flood exposure layers"> |
| <div bind:this={container} class="land-mapmini-canvas"></div> |
| <div class="land-mapmini-legend"> |
| <span><span class="lm-sw lm-sw-emp"></span>empirical</span> |
| <span><span class="lm-sw lm-sw-mod"></span>modeled</span> |
| <span><span class="lm-sw lm-sw-prx"></span>proxy</span> |
| </div> |
| </div> |
|
|
| <style> |
| .land-mapmini { |
| position: relative; |
| aspect-ratio: 6 / 5; |
| border: 1px solid var(--rule-soft); |
| overflow: hidden; |
| background: var(--paper-deep); |
| } |
| .land-mapmini-canvas { |
| position: absolute; |
| inset: 0; |
| } |
| .land-mapmini-legend { |
| position: absolute; |
| left: 6px; |
| bottom: 6px; |
| right: 6px; |
| display: flex; |
| gap: 10px; |
| padding: 4px 6px; |
| background: rgba(255, 255, 255, 0.92); |
| font-family: var(--font-mono); |
| font-size: 9.5px; |
| letter-spacing: 0.04em; |
| color: var(--ink-secondary); |
| z-index: 1; |
| pointer-events: none; |
| } |
| .land-mapmini-legend span { |
| display: inline-flex; |
| align-items: center; |
| gap: 4px; |
| } |
| .lm-sw { display: inline-block; width: 8px; height: 8px; } |
| .lm-sw-emp { background: var(--tier-empirical); } |
| .lm-sw-mod { |
| background: rgba(42, 111, 168, 0.4); |
| border: 1px dashed var(--tier-modeled); |
| } |
| .lm-sw-prx { |
| background: transparent; |
| border: 1px solid #6B6B6B; |
| border-radius: 50%; |
| } |
| </style> |
|
|