From 206adb6b7df93925bbaac8ba8e5dc2d7ea71fab6 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Thu, 24 Jul 2025 12:02:28 -0500 Subject: [PATCH] back to raster --- assets/js/map.ts | 293 ++++++++++++++---- .../components/layouts/root.html.heex | 36 ++- lib/aprsme_web/router.ex | 8 +- 3 files changed, 262 insertions(+), 75 deletions(-) diff --git a/assets/js/map.ts b/assets/js/map.ts index 90591e5..446a25d 100644 --- a/assets/js/map.ts +++ b/assets/js/map.ts @@ -287,105 +287,284 @@ let MapAPRSMap = { // Try to use vector tiles if L.vectorGrid is available (loaded from CDN) let tileLayer: L.Layer; - // Check if L.vectorGrid is available + // Check if L.vectorGrid is available and if we should use vector tiles console.log('Checking for L.vectorGrid:', typeof (L as any).vectorGrid); console.log('Checking for L.vectorGrid.protobuf:', typeof (L as any).vectorGrid?.protobuf); - if ((L as any).vectorGrid && (L as any).vectorGrid.protobuf) { + // Use raster tiles by default for better appearance + // Vector tiles have rendering issues with water features at lower zoom levels + const useVectorTiles = false; // Can be made configurable later + + if (useVectorTiles && (L as any).vectorGrid && (L as any).vectorGrid.protobuf) { try { console.log('L.vectorGrid.protobuf is available, attempting to use OpenStreetMap vector tiles'); const vectorProvider = tileProviders.osmVector; - // Style configuration for OpenStreetMap Shortbread schema + // Style configuration to match OSM raster tiles appearance const vectorTileStyles = { - // Water features - water_polygons: { + // Water features - hide at lower zoom levels to match raster tiles + 'water': function(properties: any, zoom: number) { + // Hide ALL water features at zoom 12 and below + if (zoom <= 12) { + return { fill: false, stroke: false, weight: 0, opacity: 0 }; + } + // Only show water at zoom 13+ + return { + fill: true, + fillColor: '#aad3df', + fillOpacity: 0.8, + weight: 0 + }; + }, + 'water_areas': function(properties: any, zoom: number) { + // Also hide water_areas at low zoom + if (zoom <= 12) { + return { fill: false, stroke: false, weight: 0, opacity: 0 }; + } + return { + fill: true, + fillColor: '#aad3df', + fillOpacity: 0.8, + weight: 0 + }; + }, + 'water_polygons': function(properties: any, zoom: number) { + // Hide water polygons too + if (zoom <= 12) { + return { fill: false, stroke: false, weight: 0, opacity: 0 }; + } + return { + fill: true, + fillColor: '#aad3df', + fillOpacity: 0.8, + weight: 0 + }; + }, + 'ocean': { fill: true, - fillColor: '#a0c8f0', + fillColor: '#aad3df', fillOpacity: 1, weight: 0 }, - water_lines: { - weight: 2, - color: '#a0c8f0', - opacity: 1 - }, - water_areas: { - fill: true, - fillColor: '#a0c8f0', - fillOpacity: 1, - weight: 0 - }, - // Landuse and parks - landuse_areas: { - fill: true, - fillColor: '#f0f0f0', - fillOpacity: 0.6, - weight: 0 - }, - parks: { - fill: true, - fillColor: '#c8facc', - fillOpacity: 0.8, - weight: 0 - }, - // Buildings - buildings: { - fill: true, - fillColor: '#e0e0e0', - fillOpacity: 0.8, + 'water_lines': { weight: 1, - color: '#cccccc' + color: '#aad3df', + opacity: 0.6 }, - // Transportation (roads) - transport_lines: function(properties: any) { + // Land - match OSM raster background + 'land': { + fill: true, + fillColor: '#f2efe9', + fillOpacity: 1, + weight: 0 + }, + // Landcover layers + 'landcover': function(properties: any) { + const kind = properties.kind || properties.class; + // Parks and recreation areas - light green + if (kind === 'park' || kind === 'recreation_ground' || kind === 'grass') { + return { + fill: true, + fillColor: '#c8facc', + fillOpacity: 0.6, + weight: 0 + }; + } + // Forests and woods - darker green + if (kind === 'forest' || kind === 'wood') { + return { + fill: true, + fillColor: '#add19e', + fillOpacity: 0.8, + weight: 0 + }; + } + // Residential areas - light gray + if (kind === 'residential') { + return { + fill: true, + fillColor: '#e0e0e0', + fillOpacity: 0.3, + weight: 0 + }; + } + // Commercial/industrial - slightly darker + if (kind === 'commercial' || kind === 'industrial') { + return { + fill: true, + fillColor: '#dfdfdf', + fillOpacity: 0.4, + weight: 0 + }; + } + // Default landcover + return { + fill: true, + fillColor: '#f2efe9', + fillOpacity: 0.5, + weight: 0 + }; + }, + // Streets/roads - match OSM styling + 'streets': function(properties: any) { const kind = properties.kind || properties.highway; - if (kind === 'motorway' || kind === 'trunk') { + // Motorways - orange + if (kind === 'motorway' || kind === 'motorway_link') { return { weight: 4, - color: '#e9ac77', + color: '#e892a2', opacity: 1 }; - } else if (kind === 'primary' || kind === 'secondary') { + } + // Trunk roads - pinkish + if (kind === 'trunk' || kind === 'trunk_link') { + return { + weight: 4, + color: '#f9b29c', + opacity: 1 + }; + } + // Primary roads - orange/yellow + if (kind === 'primary' || kind === 'primary_link') { return { weight: 3, - color: '#ffd380', + color: '#fcd6a4', opacity: 1 }; - } else { + } + // Secondary roads - yellow + if (kind === 'secondary' || kind === 'secondary_link') { + return { + weight: 2.5, + color: '#f7fabf', + opacity: 1 + }; + } + // Tertiary roads + if (kind === 'tertiary' || kind === 'tertiary_link') { return { weight: 2, color: '#ffffff', + opacity: 1 + }; + } + // Residential streets + if (kind === 'residential' || kind === 'living_street') { + return { + weight: 1.5, + color: '#ffffff', + opacity: 0.9 + }; + } + // Service roads + if (kind === 'service') { + return { + weight: 1, + color: '#ffffff', opacity: 0.8 }; } - }, - // Places - places: function(properties: any, zoom: number) { - if (zoom < 10) return { weight: 0 }; // Hide at low zoom + // Default road style return { - weight: 0, - fillOpacity: 0, - interactive: false + weight: 1, + color: '#ffffff', + opacity: 0.8 }; }, - // Default style for unmatched layers - _default: { + 'streets_med': function(properties: any) { + // Medium priority streets + return { + weight: 2, + color: '#ffffff', + opacity: 0.9 + }; + }, + 'streets_low': { + // Low priority streets weight: 1, - color: '#cccccc', - opacity: 0.5 + color: '#ffffff', + opacity: 0.7 + }, + // Buildings - subtle gray + 'buildings': { + fill: true, + fillColor: '#d9d0c9', + fillOpacity: 0.7, + weight: 0.5, + color: '#cfc7c0', + opacity: 0.8 + }, + // POIs - hide them to match raster simplicity + 'pois': { + weight: 0, + opacity: 0, + fillOpacity: 0 + }, + // Places - hide labels + 'places': { + weight: 0, + opacity: 0, + fillOpacity: 0 + }, + // Boundaries - subtle + 'boundaries': { + weight: 0.8, + color: '#a09090', + opacity: 0.4, + dashArray: '3, 3' + }, + // Transit - hide for simplicity + 'transit': { + weight: 0, + opacity: 0 + }, + // Default style - should rarely be used + '*': { + fill: false, + weight: 0, + opacity: 0 } }; // Create vector grid layer using L.vectorGrid.protobuf tileLayer = (L as any).vectorGrid.protobuf(vectorProvider.url, { attribution: vectorProvider.attribution, - maxZoom: vectorProvider.maxZoom, - vectorTileLayerStyles: vectorTileStyles, - interactive: true, + maxNativeZoom: vectorProvider.maxZoom, + maxZoom: 19, + rendererFactory: L.canvas.tile, + interactive: false, getFeatureId: function(feature: any) { return feature.properties.osm_id || feature.properties.id; + }, + // Use a function for vectorTileLayerStyles to have full control + vectorTileLayerStyles: function(properties: any, zoom: number) { + // Access layer name from 'this' context + const layerName = this.layerName || ''; + + // Apply styles based on layer name + const styles = vectorTileStyles; + + // Check if we have a specific style for this layer + if (styles[layerName]) { + const style = styles[layerName]; + if (typeof style === 'function') { + return style.call(this, properties, zoom); + } + return style; + } + + // Use wildcard style if defined + if (styles['*']) { + const style = styles['*']; + if (typeof style === 'function') { + return style.call(this, properties, zoom); + } + return style; + } + + // Default: hide unknown features + return { fill: false, stroke: false, weight: 0, opacity: 0 }; } }); diff --git a/lib/aprsme_web/components/layouts/root.html.heex b/lib/aprsme_web/components/layouts/root.html.heex index 9b52e09..e360ce4 100644 --- a/lib/aprsme_web/components/layouts/root.html.heex +++ b/lib/aprsme_web/components/layouts/root.html.heex @@ -35,28 +35,36 @@ - + - - - - - + + + + + - - - + + + - - + + - - + + - +