diff --git a/apps/web/public/style.json b/apps/web/public/style.json index 9954b44..467de31 100644 --- a/apps/web/public/style.json +++ b/apps/web/public/style.json @@ -59,13 +59,25 @@ }, "overture_buildings": { "type": "vector", - "tiles": ["https://tiles.intaleqapp.com/overture_building/{z}/{x}/{y}"], + "tiles": [ + "https://tiles.intaleqapp.com/overture_building/{z}/{x}/{y}" + ], "maxzoom": 14 }, "overture_segments": { "type": "vector", - "tiles": ["https://tiles.intaleqapp.com/overture_segment/{z}/{x}/{y}"], + "tiles": [ + "https://tiles.intaleqapp.com/overture_segment/{z}/{x}/{y}" + ], "maxzoom": 14 + }, + "approved_roads": { + "type": "vector", + "tiles": [ + "http://188.68.36.205:3202/approved_roads/{z}/{x}/{y}" + ], + "minzoom": 8, + "maxzoom": 18 } }, "layers": [ @@ -599,7 +611,7 @@ "track", "path", "footway", - "cycleway", + "cycleway", "steps" ], "minzoom": 14, @@ -687,6 +699,59 @@ ] } }, + { + "id": "approved-road-casing", + "type": "line", + "source": "approved_roads", + "source-layer": "approved_roads", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-color": "#B9C2CE", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 2.2, + 16, + 10 + ], + "line-opacity": 0.9 + } + }, + { + "id": "approved-road-core", + "type": "line", + "source": "approved_roads", + "source-layer": "approved_roads", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-color": "#FFFFFF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 0.8, + 16, + 8 + ] + } + }, { "id": "road-casing-tertiary", "type": "line", @@ -927,15 +992,44 @@ "minzoom": 15, "filter": [ "all", - ["in", "highway", "motorway", "trunk", "primary", "secondary", "tertiary", "residential", "unclassified", "living_street"], - ["==", "oneway", "yes"] + [ + "in", + "highway", + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "residential", + "unclassified", + "living_street" + ], + [ + "==", + "oneway", + "yes" + ] ], "layout": { "symbol-placement": "line", "symbol-spacing": 80, "text-field": "▸", - "text-font": ["Noto Sans Regular"], - "text-size": ["interpolate", ["linear"], ["zoom"], 15, 12, 18, 18], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 12, + 18, + 18 + ], "text-keep-upright": false, "text-rotation-alignment": "map", "text-allow-overlap": true, @@ -943,7 +1037,19 @@ "text-padding": 0 }, "paint": { - "text-color": ["interpolate", ["linear"], ["zoom"], 15, "rgba(100,116,139,0.4)", 18, "rgba(100,116,139,0.7)"], + "text-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + "rgba(100,116,139,0.4)", + 18, + "rgba(100,116,139,0.7)" + ], "text-halo-color": "rgba(255,255,255,0.3)", "text-halo-width": 0.5 } @@ -977,21 +1083,54 @@ "fill-extrusion-color": "#DDD8D0", "fill-extrusion-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, [ "*", - ["coalesce", ["to-number", ["get", "num_floors"], null], 3], + [ + "coalesce", + [ + "to-number", + [ + "get", + "num_floors" + ], + null + ], + 3 + ], 2.5 ], 17, [ "coalesce", - ["to-number", ["get", "height"], null], + [ + "to-number", + [ + "get", + "height" + ], + null + ], [ "*", - ["coalesce", ["to-number", ["get", "num_floors"], null], 3], + [ + "coalesce", + [ + "to-number", + [ + "get", + "num_floors" + ], + null + ], + 3 + ], 3.5 ], 12 @@ -1000,10 +1139,16 @@ "fill-extrusion-base": 0, "fill-extrusion-opacity": [ "interpolate", - ["linear"], - ["zoom"], - 14, 0.55, - 16, 0.85 + [ + "linear" + ], + [ + "zoom" + ], + 14, + 0.55, + 16, + 0.85 ], "fill-extrusion-vertical-gradient": true } @@ -1178,12 +1323,32 @@ "layout": { "text-field": [ "coalesce", - ["get", "name:ar"], - ["get", "name"], + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], "" ], - "text-font": ["Noto Sans Regular"], - "text-size": ["interpolate", ["linear"], ["zoom"], 15, 10, 18, 13], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 10, + 18, + 13 + ], "symbol-placement": "line", "text-letter-spacing": 0.05, "text-padding": 15, @@ -1216,12 +1381,34 @@ "layout": { "text-field": [ "coalesce", - ["get", "name:ar"], - ["get", "name"], + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], "" ], - "text-font": ["Noto Sans Bold"], - "text-size": ["interpolate", ["linear"], ["zoom"], 12, 10, 14, 13, 18, 16], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 10, + 14, + 13, + 18, + 16 + ], "symbol-placement": "line", "text-letter-spacing": 0.06, "text-padding": 20, @@ -1445,7 +1632,7 @@ "" ], "text-font": [ - "Noto Sans Regular" + "Noto Sans Regular" ], "text-size": 11, "text-offset": [ @@ -1550,7 +1737,7 @@ "" ], "text-font": [ - "Noto Sans Regular" + "Noto Sans Regular" ], "text-size": [ "interpolate", @@ -1730,7 +1917,7 @@ "text-size": [ "interpolate", [ - "linear" + "linear" ], [ "zoom" @@ -1760,7 +1947,11 @@ "source": "places_syria", "source-layer": "places_syria", "minzoom": 10, - "filter": ["!in", "category", "street"], + "filter": [ + "!in", + "category", + "street" + ], "layout": { "text-field": [ "coalesce", @@ -1810,7 +2001,11 @@ "source": "places_jordan", "source-layer": "places_jordan", "minzoom": 10, - "filter": ["!in", "category", "street"], + "filter": [ + "!in", + "category", + "street" + ], "layout": { "text-field": [ "coalesce", @@ -1905,11 +2100,37 @@ "source": "overture_segments", "source-layer": "overture_segment", "minzoom": 14, - "filter": ["has", "names"], + "filter": [ + "has", + "names" + ], "layout": { - "text-field": ["coalesce", ["get", "names"], ""], - "text-font": ["Noto Sans Regular"], - "text-size": ["interpolate", ["linear"], ["zoom"], 14, 9, 16, 12, 18, 14], + "text-field": [ + "coalesce", + [ + "get", + "names" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + 9, + 16, + 12, + 18, + 14 + ], "symbol-placement": "line", "text-rotation-alignment": "map", "text-pitch-alignment": "viewport", @@ -1928,4 +2149,4 @@ } } ] -} \ No newline at end of file +} diff --git a/apps/web/src/components/MapComponent.tsx b/apps/web/src/components/MapComponent.tsx index 5cb86be..64e54b5 100644 --- a/apps/web/src/components/MapComponent.tsx +++ b/apps/web/src/components/MapComponent.tsx @@ -54,7 +54,7 @@ const MapComponent: React.FC = ({ const tilesUrl = (import.meta as any).env.VITE_TILES_URL || 'https://tiles.intaleqapp.com'; try { - map.current = new maplibregl.Map({ + const initialMap = new maplibregl.Map({ container: mapContainer.current, style: { version: 8, @@ -75,6 +75,12 @@ const MapComponent: React.FC = ({ type: 'vector', tiles: [`${tilesUrl}/planet_osm_point/{z}/{x}/{y}`], maxzoom: 14 + }, + 'approved_roads': { + type: 'vector', + tiles: [`${tilesUrl}/approved_roads/{z}/{x}/{y}`], + minzoom: 8, + maxzoom: 18 } }, layers: [ @@ -145,6 +151,26 @@ const MapComponent: React.FC = ({ 'line-width': ['interpolate', ['linear'], ['zoom'], 13, 1, 16, 8] as any } }, + { + id: 'approved-casing', + type: 'line', + source: 'approved_roads', + 'source-layer': 'approved_roads', + paint: { + 'line-color': '#d4d4d4', + 'line-width': ['interpolate', ['linear'], ['zoom'], 13, 1, 16, 8] as any + } + }, + { + id: 'approved-core', + type: 'line', + source: 'approved_roads', + 'source-layer': 'approved_roads', + paint: { + 'line-color': '#ffffff', + 'line-width': ['interpolate', ['linear'], ['zoom'], 13, 0.5, 16, 6] as any + } + }, { id: 'road-core-minor', type: 'line', @@ -352,19 +378,37 @@ const MapComponent: React.FC = ({ 'text-anchor': 'top', 'visibility': showPOIs ? 'visible' : 'none' }, - paint: { - 'text-color': '#222', - 'text-halo-color': 'rgba(255, 255, 255, 0.9)', + paint: { + 'text-color': '#222', + 'text-halo-color': 'rgba(255, 255, 255, 0.9)', 'text-halo-width': 2 } } ] }, center: [35.9106, 31.9539], - zoom: 12, }); - map.current.on('load', () => { + map.current = initialMap; + + // Request User Location + if ('geolocation' in navigator) { + navigator.geolocation.getCurrentPosition( + (position) => { + if (initialMap) { + initialMap.flyTo({ + center: [position.coords.longitude, position.coords.latitude], + zoom: 14, + essential: true + }); + } + }, + (error) => console.warn('Geolocation denied or failed', error), + { timeout: 5000 } + ); + } + + initialMap.on('load', () => { console.log("MapComponent: Map Loaded Successfully"); onMapLoad(map.current!); }); @@ -394,13 +438,13 @@ const MapComponent: React.FC = ({ return (
{/* Intaleq Premium Branding Watermark */} -
= ({ border: '1px solid rgba(255,255,255,0.35)' }} > - Intaleq - = { @@ -48,14 +51,27 @@ const CompareView: React.FC = () => { const start: [number, number] = [35.91, 31.95]; const startZoom = 15; - const lMap = new maplibregl.Map({ container: leftDiv.current, style: TILES + '/style.json', center: start, zoom: startZoom, attributionControl: false }); + // Base style is served by the APP host as a static file (its internal sources + // already point at the absolute Martin host), so load it relatively — never + // prefixed with the tile host, which does not serve /style.json. + const lMap = new maplibregl.Map({ container: leftDiv.current, style: '/style.json', center: start, zoom: startZoom, attributionControl: false }); const rMap = new maplibregl.Map({ container: rightDiv.current, style: rasterStyle(REFS['esri-sat']), center: start, zoom: startZoom, attributionControl: false }); lMap.addControl(new maplibregl.NavigationControl({ showCompass: false }), 'top-left'); rMap.addControl(new maplibregl.AttributionControl({ compact: true }), 'bottom-right'); + if ('geolocation' in navigator) { + navigator.geolocation.getCurrentPosition((pos) => { + const coords: [number, number] = [pos.coords.longitude, pos.coords.latitude]; + lMap.flyTo({ center: coords, zoom: 14, essential: true }); + rMap.flyTo({ center: coords, zoom: 14, essential: true }); + setCenter({ lng: coords[0], lat: coords[1], zoom: 14 }); + }); + } + lMap.on('load', () => { lMap.addSource('approved', { type: 'vector', tiles: [`${TILES}/approved_roads/{z}/{x}/{y}`], minzoom: 8, maxzoom: 18 }); - lMap.addLayer({ id: 'approved', type: 'line', source: 'approved', 'source-layer': 'approved_roads', paint: { 'line-color': '#22c55e', 'line-width': ['interpolate', ['linear'], ['zoom'], 10, 1.5, 16, 8] } }); + lMap.addLayer({ id: 'approved-casing', type: 'line', source: 'approved', 'source-layer': 'approved_roads', paint: { 'line-color': '#d4d4d4', 'line-width': ['interpolate', ['linear'], ['zoom'], 13, 1, 16, 8] } }); + lMap.addLayer({ id: 'approved', type: 'line', source: 'approved', 'source-layer': 'approved_roads', paint: { 'line-color': '#ffffff', 'line-width': ['interpolate', ['linear'], ['zoom'], 13, 0.5, 16, 6] } }); }); // Keep the two views locked together. The guard stops the move→jumpTo→move loop. diff --git a/apps/web/src/pages/IntelligenceDashboard.tsx b/apps/web/src/pages/IntelligenceDashboard.tsx index f716009..30d95a8 100644 --- a/apps/web/src/pages/IntelligenceDashboard.tsx +++ b/apps/web/src/pages/IntelligenceDashboard.tsx @@ -59,15 +59,18 @@ const IntelligenceDashboard: React.FC = () => { }, [drawing]); const redrawDrawing = () => { - const lm = leftMapRef.current; - const rm = rightMapRef.current; + const lMap = leftMapRef.current; const rMap = rightMapRef.current; + if (!lMap || !rMap) return; const pts = pointsRef.current; - const feats: any[] = []; - pts.forEach(p => feats.push({ type: 'Feature', geometry: { type: 'Point', coordinates: p } })); - if (pts.length > 1) feats.push({ type: 'Feature', geometry: { type: 'LineString', coordinates: pts } }); - const col = { type: 'FeatureCollection', features: feats }; - if (lm && lm.isStyleLoaded()) (lm.getSource('draw') as maplibregl.GeoJSONSource)?.setData(col as any); - if (rm && rm.isStyleLoaded()) (rm.getSource('draw') as maplibregl.GeoJSONSource)?.setData(col as any); + const data = { + type: 'FeatureCollection', + features: [ + ...(pts.length >= 2 ? [{ type: 'Feature' as const, geometry: { type: 'LineString' as const, coordinates: pts }, properties: {} }] : []), + ...pts.map(p => ({ type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: p }, properties: {} })) + ] + }; + (lMap.getSource('draw') as maplibregl.GeoJSONSource)?.setData(data as any); + (rMap.getSource('draw') as maplibregl.GeoJSONSource)?.setData(data as any); }; const pushMapData = () => { @@ -163,6 +166,15 @@ const IntelligenceDashboard: React.FC = () => { }); lMap.addControl(new maplibregl.NavigationControl({ showCompass: false }), 'top-left'); + rMap.addControl(new maplibregl.AttributionControl({ compact: true }), 'bottom-right'); + + if ('geolocation' in navigator) { + navigator.geolocation.getCurrentPosition((pos) => { + const coords: [number, number] = [pos.coords.longitude, pos.coords.latitude]; + lMap.flyTo({ center: coords, zoom: 14, essential: true }); + rMap.flyTo({ center: coords, zoom: 14, essential: true }); + }); + } // Sync logic const link = (from: maplibregl.Map, to: maplibregl.Map) => { @@ -178,6 +190,14 @@ const IntelligenceDashboard: React.FC = () => { lMap.addSource('cands', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } } as any); lMap.addSource('closures', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } } as any); lMap.addSource('hl', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } } as any); + + // approved_roads is served by Martin on the tile host — NOT the app host. An + // empty default made this resolve to /approved_roads on the app host (404), so + // approved roads never drew. Point it at the real Martin host. + const TILES = (import.meta as any).env.VITE_TILES_URL || 'https://tiles.intaleqapp.com'; + lMap.addSource('approved', { type: 'vector', tiles: [`${TILES}/approved_roads/{z}/{x}/{y}`], minzoom: 8, maxzoom: 18 }); + lMap.addLayer({ id: 'approved-casing', type: 'line', source: 'approved', 'source-layer': 'approved_roads', paint: { 'line-color': '#d4d4d4', 'line-width': ['interpolate', ['linear'], ['zoom'], 13, 1, 16, 8] } }); + lMap.addLayer({ id: 'approved', type: 'line', source: 'approved', 'source-layer': 'approved_roads', paint: { 'line-color': '#ffffff', 'line-width': ['interpolate', ['linear'], ['zoom'], 13, 0.5, 16, 6] } }); lMap.addSource('draw', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } } as any); lMap.addLayer({ id: 'cl', type: 'line', source: 'closures', paint: { 'line-color': '#ef4444', 'line-width': 4, 'line-dasharray': [3, 2] } }); @@ -208,18 +228,31 @@ const IntelligenceDashboard: React.FC = () => { const onCandidateClick = (e: any) => { const p = e.features?.[0]?.properties as any; if (!p) return; + const l = e.features?.[0]?.layer?.id; setSel(p.id); const isOvt = p.source === 'overture'; - const title = isOvt ? '🗺️ Overture road (missing)' : '🛣️ Driver-traced road'; + const isAppr = l === 'approved'; + const title = isAppr ? '✅ Approved Road' : isOvt ? '🗺️ Overture road (missing)' : '🛣️ Driver-traced road'; const nameLine = p.name ? `${p.name}
` : ''; - const evidence = isOvt ? `${p.uniqueDriverCount ?? 0} trace pts corroborate` : `${p.uniqueDriverCount} drivers`; + const evidence = isOvt ? `${p.uniqueDriverCount ?? 0} trace pts corroborate` : `${p.uniqueDriverCount || 1} drivers`; if (popupRef.current) popupRef.current.remove(); - popupRef.current = new maplibregl.Popup({ offset: 12 }).setLngLat(e.lngLat) - .setHTML(`
${nameLine}${title}
Conf: ${Math.round(p.confidence * 100)}%
${Math.round(p.lengthMeters)}m | ${evidence}
`) - .addTo(lMap); + + const popupDiv = document.createElement('div'); + popupDiv.style.font = '12px sans-serif'; + popupDiv.style.color = '#1e293b'; + popupDiv.style.lineHeight = '1.6'; + popupDiv.innerHTML = `${nameLine}${title}
Conf: ${Math.round(p.confidence * 100)}%
${Math.round(p.lengthMeters || 0)}m | ${evidence} +
`; + + popupDiv.querySelector(`#btn-del-${p.id}`)?.addEventListener('click', () => { + deleteRoad(p.id, isAppr ? 'approved' : 'candidate'); + popupRef.current?.remove(); + }); + + popupRef.current = new maplibregl.Popup({ offset: 12 }).setLngLat(e.lngLat).setDOMContent(popupDiv).addTo(lMap); }; - ['cp', 'cp-overture'].forEach(layer => { + ['cp', 'cp-overture', 'approved'].forEach(layer => { lMap.on('click', layer, onCandidateClick); lMap.on('mouseenter', layer, () => { lMap.getCanvas().style.cursor = 'pointer'; }); lMap.on('mouseleave', layer, () => { lMap.getCanvas().style.cursor = ''; }); @@ -278,6 +311,25 @@ const IntelligenceDashboard: React.FC = () => { setTimeout(() => setMsg(''), 5000); }; + const deleteRoad = async (id: string, type: 'approved' | 'candidate') => { + try { + const res = await fetch(`${API}/map-refinement/roads/${type}/${id}`, { + method: 'DELETE', + headers: { 'x-api-key': apiKey } + }); + if (!res.ok) throw new Error('Failed to delete'); + setMsg(`🗑️ Deleted ${type} road successfully.`); + setSel(null); + (leftMapRef.current?.getSource('hl') as maplibregl.GeoJSONSource)?.setData({ type: 'FeatureCollection', features: [] }); + load(); + // Force MapLibre to drop cached vector tiles completely for approved roads + if (type === 'approved') { + setTimeout(() => window.location.reload(), 1500); + } + } catch { setMsg('Delete failed.'); } + setTimeout(() => setMsg(''), 5000); + }; + const runAI = async () => { setMsg('🧠 Deep analysis started...'); try { @@ -298,18 +350,18 @@ const IntelligenceDashboard: React.FC = () => { setTimeout(() => setMsg(''), 6000); }; - const submitDrawing = async () => { + const submitRoad = async () => { if (pointsRef.current.length < 2) return setMsg('Draw at least 2 points!'); - const roadName = window.prompt('Enter a name for this new road:', 'Unnamed Road'); - if (roadName === null) return; // User cancelled - + if (roadName === null) return; + const highway = window.prompt('Enter road category (primary, secondary, residential, unclassified, service):', 'unclassified'); + if (highway === null) return; try { const geojson = { type: 'LineString', coordinates: pointsRef.current }; const res = await fetch(`${API}/map-refinement/roads/candidates/manual`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey }, - body: JSON.stringify({ geojson, name: roadName }), + body: JSON.stringify({ geojson, name: roadName, highway }), }); if (!res.ok) throw new Error('Failed to submit road'); setMsg('Road submitted for intelligence analysis!'); @@ -400,7 +452,7 @@ const IntelligenceDashboard: React.FC = () => {
Click on either map to trace the street.
- +
diff --git a/packages/flutter-sdk/assets/style.json b/packages/flutter-sdk/assets/style.json index 972b5f5..b4c0ade 100644 --- a/packages/flutter-sdk/assets/style.json +++ b/packages/flutter-sdk/assets/style.json @@ -70,6 +70,14 @@ "https://tiles.intaleqapp.com/overture_segment/{z}/{x}/{y}" ], "maxzoom": 14 + }, + "approved_roads": { + "type": "vector", + "tiles": [ + "http://188.68.36.205:3202/approved_roads/{z}/{x}/{y}" + ], + "minzoom": 8, + "maxzoom": 18 } }, "layers": [ @@ -691,6 +699,59 @@ ] } }, + { + "id": "approved-road-casing", + "type": "line", + "source": "approved_roads", + "source-layer": "approved_roads", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-color": "#D4D8DF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 1.5, + 16, + 10 + ], + "line-opacity": 0.7 + } + }, + { + "id": "approved-road-core", + "type": "line", + "source": "approved_roads", + "source-layer": "approved_roads", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-color": "#FFFFFF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 0.8, + 16, + 8 + ] + } + }, { "id": "road-casing-tertiary", "type": "line", diff --git a/packages/flutter-sdk/assets/style_dark.json b/packages/flutter-sdk/assets/style_dark.json index 32ac54a..6799e83 100644 --- a/packages/flutter-sdk/assets/style_dark.json +++ b/packages/flutter-sdk/assets/style_dark.json @@ -70,6 +70,14 @@ "https://tiles.intaleqapp.com/overture_segment/{z}/{x}/{y}" ], "maxzoom": 14 + }, + "approved_roads": { + "type": "vector", + "tiles": [ + "http://188.68.36.205:3202/approved_roads/{z}/{x}/{y}" + ], + "minzoom": 8, + "maxzoom": 18 } }, "layers": [ @@ -691,6 +699,59 @@ ] } }, + { + "id": "approved-road-casing", + "type": "line", + "source": "approved_roads", + "source-layer": "approved_roads", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-color": "#D4D8DF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 1.5, + 16, + 10 + ], + "line-opacity": 0.7 + } + }, + { + "id": "approved-road-core", + "type": "line", + "source": "approved_roads", + "source-layer": "approved_roads", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-color": "#FFFFFF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 0.8, + 16, + 8 + ] + } + }, { "id": "road-casing-tertiary", "type": "line", diff --git a/style-dark.json b/style-dark.json index d9e226f..0a7490d 100644 --- a/style-dark.json +++ b/style-dark.json @@ -74,7 +74,7 @@ "approved_roads": { "type": "vector", "tiles": [ - "https://tiles.intaleqapp.com/approved_roads/{z}/{x}/{y}" + "http://188.68.36.205:3202/approved_roads/{z}/{x}/{y}" ], "minzoom": 8, "maxzoom": 18 @@ -709,7 +709,7 @@ "line-join": "round" }, "paint": { - "line-color": "#B9C2CE", + "line-color": "#D4D8DF", "line-width": [ "interpolate", [ @@ -719,11 +719,11 @@ "zoom" ], 12, - 2.2, + 1.5, 16, 10 ], - "line-opacity": 0.9 + "line-opacity": 0.7 } }, { diff --git a/style.json b/style.json index d4bbe0d..2f23ec1 100644 --- a/style.json +++ b/style.json @@ -74,7 +74,7 @@ "approved_roads": { "type": "vector", "tiles": [ - "https://tiles.intaleqapp.com/approved_roads/{z}/{x}/{y}" + "http://188.68.36.205:3202/approved_roads/{z}/{x}/{y}" ], "minzoom": 8, "maxzoom": 18 @@ -709,7 +709,7 @@ "line-join": "round" }, "paint": { - "line-color": "#B9C2CE", + "line-color": "#D4D8DF", "line-width": [ "interpolate", [ @@ -719,11 +719,11 @@ "zoom" ], 12, - 2.2, + 1.5, 16, 10 ], - "line-opacity": 0.9 + "line-opacity": 0.7 } }, { diff --git a/sync_to_server.sh b/sync_to_server.sh index e5900e0..82fcf1d 100755 --- a/sync_to_server.sh +++ b/sync_to_server.sh @@ -41,7 +41,7 @@ if [ $? -eq 0 ]; then echo "------------------------------------------------" echo "Now run the following on your SERVER terminal:" echo "cd $REMOTE_PATH" - echo "docker compose up -d --build api dashboard" + echo "docker compose up -d --build api dashboard web" echo "Dashboard will be live at: http://$SERVER_IP:3204" echo "------------------------------------------------" else