diff --git a/arches/app/media/js/viewmodels/map.js b/arches/app/media/js/viewmodels/map.js index eac6659c0a3..e6678ecdae6 100644 --- a/arches/app/media/js/viewmodels/map.js +++ b/arches/app/media/js/viewmodels/map.js @@ -12,6 +12,261 @@ define([ const viewModel = function(params) { var self = this; + const searchLayerIds = [ + 'searchtiles-unclustered-polygon-fill', + 'searchtiles-unclustered-point', + 'searchtiles-clusters', + 'searchtiles-clusters-halo', + 'searchtiles-cluster-count', + 'searchtiles-unclustered-polypoint' + ]; + const searchLayerDefinitions = [ + { + "id": "searchtiles-unclustered-polygon-fill", + "type": "fill", + "paint": { + "fill-color": "#fa6003", + "fill-opacity": 0.3, + "fill-outline-color": "#fa6003" + }, + "filter": [ + "==", + "$type", + "Polygon" + ], + "source": "search-layer-source", + "source-layer": "search_layer", + "minzoom": 10, + "tolerance": 0.75 + }, + { + "id": "searchtiles-unclustered-point", + "type": "circle", + "paint": { + "circle-color": "#fa6003", + "circle-radius": 6, + "circle-opacity": 1 + }, + "filter": [ + "!", + [ + "has", + "point_count" + ] + ], + "source": "search-layer-source", + "source-layer": "search_layer" + }, + { + "id": "searchtiles-clusters", + "type": "circle", + "paint": { + "circle-color": "#fa6003", + "circle-radius": [ + "step", + [ + "get", + "point_count" + ], + 10, + 100, + 20, + 750, + 30, + 1500, + 40, + 2500, + 50, + 5000, + 65 + ], + "circle-opacity": [ + "case", + [ + "boolean", + [ + "has", + "point_count" + ], + true + ], + 1, + 0 + ] + }, + "filter": [ + "all", + [ + "==", + "$type", + "Point" + ], + [ + "!=", + "highlight", + true + ] + ], + "source": "search-layer-source", + "source-layer": "search_layer" + }, + { + "id": "searchtiles-clusters-halo", + "type": "circle", + "paint": { + "circle-color": "#fa6003", + "circle-radius": [ + "step", + [ + "get", + "point_count" + ], + 20, + 100, + 30, + 750, + 40, + 1500, + 50, + 2500, + 60, + 5000, + 75 + ], + "circle-opacity": [ + "case", + [ + "boolean", + [ + "has", + "point_count" + ], + true + ], + 0.5, + 0 + ] + }, + "filter": [ + "all", + [ + "==", + "$type", + "Point" + ], + [ + "!=", + "highlight", + true + ] + ], + "maxzoom": 14, + "source": "search-layer-source", + "source-layer": "search_layer" + }, + { + "id": "searchtiles-cluster-count", + "type": "symbol", + "paint": { + "text-color": "#fff" + }, + "filter": [ + "has", + "point_count" + ], + "layout": { + "text-font": [ + "DIN Offc Pro Medium", + "Arial Unicode MS Bold" + ], + "text-size": 14, + "text-field": "{point_count}" + }, + "maxzoom": 14, + "source": "search-layer-source", + "source-layer": "search_layer" + }, + { + "id": "searchtiles-unclustered-polypoint", + "type": "circle", + "paint": { + "circle-color": "#fa6003", + "circle-radius": 0, + "circle-opacity": 0, + "circle-stroke-color": "#fff", + "circle-stroke-width": 0 + }, + "filter": [ + "!", + [ + "has", + "point_count" + ] + ], + "layout": { + "visibility": "none" + }, + "source": "search-layer-source", + "source-layer": "search_layer" + } + ]; + this.searchQueryId = params.searchQueryId; + this.searchQueryId.subscribe(function (searchId) { + if (searchId) { + self.addSearchLayer(searchId); + } else { + // optionally, remove the search layer if searchId becomes undefined + self.removeSearchLayer(); + } + }); + + this.addSearchLayer = function (searchId) { + console.log(searchId); + if (!self.map()) + return; + const tileUrlTemplate = `http://localhost:8000/search-layer/{z}/{x}/{y}.pbf?searchid=${encodeURIComponent(searchId)}`; + + // Remove existing source and layer if they exist + searchLayerIds.forEach(layerId => { + if (self.map().getLayer(layerId)) { + self.map().removeLayer(layerId); + } + if (self.map().getSource(layerId)) { + self.map().removeSource(layerId); + } + }); + if (self.map().getSource('search-layer-source')) { + self.map().removeSource('search-layer-source'); + } + + // Add the vector tile source + self.map().addSource('search-layer-source', { + type: 'vector', + tiles: [tileUrlTemplate], + minzoom: 0, + maxzoom: 22, + }); + + // Add the layer to display the data + searchLayerDefinitions.forEach(mapLayer => { + self.map().addLayer(mapLayer); + }); + + // Optionally, fit the map to the data bounds + // self.fitMapToDataBounds(searchId); + }; + + this.removeSearchLayer = function () { + searchLayerDefinitions.forEach(mapLayer => { + if (self.map().getLayer(mapLayer.id)) { + self.map().removeLayer(mapLayer.id); + } + }); + if (self.map().getSource('search-layer-source')) { + self.map().removeSource('search-layer-source'); + } + }; + var geojsonSourceFactory = function() { return {