v1.1.0: keyboard shortcuts (CH), onboarding tour, admin projects tab, remember-me login, Luftbild CH removed, hose settings in admin, credit link, font Barlow, map auto-save viewport, rate-limit 10/5min
This commit is contained in:
@@ -106,7 +106,7 @@ export function MapView({
|
||||
const measureMarkersRef = useRef<maplibregl.Marker[]>([])
|
||||
const measureCoordsRef = useRef<number[][]>([])
|
||||
const [isMapLoaded, setIsMapLoaded] = useState(false)
|
||||
const [activeBaseLayer, setActiveBaseLayer] = useState<'osm' | 'satellite' | 'swisstopo' | 'swissimage'>('osm')
|
||||
const [activeBaseLayer, setActiveBaseLayer] = useState<'osm' | 'satellite' | 'swisstopo'>('osm')
|
||||
const [layerDropdownOpen, setLayerDropdownOpen] = useState(false)
|
||||
const [measurePointCount, setMeasurePointCount] = useState(0)
|
||||
const [measureFinished, setMeasureFinished] = useState(false)
|
||||
@@ -699,15 +699,6 @@ export function MapView({
|
||||
attribution: '© swisstopo',
|
||||
maxzoom: 17,
|
||||
},
|
||||
'swissimage': {
|
||||
type: 'raster',
|
||||
tiles: [
|
||||
'https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg',
|
||||
],
|
||||
tileSize: 256,
|
||||
attribution: '© swisstopo SWISSIMAGE',
|
||||
maxzoom: 18,
|
||||
},
|
||||
},
|
||||
layers: [
|
||||
{
|
||||
@@ -727,12 +718,6 @@ export function MapView({
|
||||
source: 'swisstopo',
|
||||
layout: { visibility: 'none' },
|
||||
},
|
||||
{
|
||||
id: 'swissimage',
|
||||
type: 'raster',
|
||||
source: 'swissimage',
|
||||
layout: { visibility: 'none' },
|
||||
},
|
||||
],
|
||||
},
|
||||
center: [initialCenter.lng, initialCenter.lat],
|
||||
@@ -2168,7 +2153,7 @@ export function MapView({
|
||||
}}
|
||||
>
|
||||
<svg className="w-3.5 h-3.5 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
|
||||
{{ osm: 'OpenStreetMap', satellite: 'Satellit', swisstopo: 'Swisstopo', swissimage: 'Luftbild CH' }[activeBaseLayer]}
|
||||
{{ osm: 'OpenStreetMap', satellite: 'Satellit', swisstopo: 'Swisstopo' }[activeBaseLayer]}
|
||||
<svg className={`w-3 h-3 opacity-50 transition-transform ${layerDropdownOpen ? 'rotate-180' : ''}`} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M6 9l6 6 6-6"/></svg>
|
||||
</button>
|
||||
{layerDropdownOpen && (
|
||||
@@ -2180,13 +2165,12 @@ export function MapView({
|
||||
{ key: 'osm', label: 'OpenStreetMap' },
|
||||
{ key: 'satellite', label: 'Satellit (Esri)' },
|
||||
{ key: 'swisstopo', label: 'Swisstopo Karte' },
|
||||
{ key: 'swissimage', label: 'Luftbild CH' },
|
||||
] as const).map(({ key, label }) => (
|
||||
<button
|
||||
key={key}
|
||||
onClick={() => {
|
||||
if (!map.current) return
|
||||
const allLayers: Array<'osm' | 'satellite' | 'swisstopo' | 'swissimage'> = ['osm', 'satellite', 'swisstopo', 'swissimage']
|
||||
const allLayers: Array<'osm' | 'satellite' | 'swisstopo'> = ['osm', 'satellite', 'swisstopo']
|
||||
for (const l of allLayers) {
|
||||
map.current.setLayoutProperty(l, 'visibility', l === key ? 'visible' : 'none')
|
||||
}
|
||||
@@ -2315,6 +2299,16 @@ export function MapView({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Credit link */}
|
||||
<a
|
||||
href="/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="absolute bottom-1 left-24 z-10 text-[10px] text-muted-foreground/50 hover:text-muted-foreground/80 transition-colors no-underline hidden md:block"
|
||||
>
|
||||
mit ♥ von Pepe
|
||||
</a>
|
||||
|
||||
{/* Cursor-following tooltip — always mounted for stable ref */}
|
||||
<div
|
||||
ref={tooltipRef}
|
||||
|
||||
Reference in New Issue
Block a user