feat: add point asset selection layer and synchronize feature selection states on map
This commit is contained in:
parent
594178c898
commit
28eebb0300
4 changed files with 316 additions and 49 deletions
|
|
@ -1055,6 +1055,89 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MapLibre layer definition for point asset selection / highlight halo (trees, poles, furniture, etc.).
|
||||||
|
*/
|
||||||
|
function getAssetsPointSelectionLayer(sourceId = 'assets') {
|
||||||
|
const isNatureExpr = [
|
||||||
|
'any',
|
||||||
|
['==', ['get', 'asset_type'], 'naturetree'],
|
||||||
|
['==', ['get', 'asset_type'], 'natureshrub'],
|
||||||
|
['==', ['get', 'thematic'], 'nature']
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
id: 'assets-point-selection',
|
||||||
|
type: 'circle',
|
||||||
|
source: sourceId,
|
||||||
|
filter: ['any',
|
||||||
|
['==', ['geometry-type'], 'Point'],
|
||||||
|
['==', ['geometry-type'], 'MultiPoint']
|
||||||
|
],
|
||||||
|
paint: {
|
||||||
|
'circle-radius': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
[
|
||||||
|
'case',
|
||||||
|
isNatureExpr,
|
||||||
|
[
|
||||||
|
'interpolate', ['linear'], ['zoom'],
|
||||||
|
8, 4,
|
||||||
|
11, 6,
|
||||||
|
13, 8,
|
||||||
|
15, 11,
|
||||||
|
17, 14,
|
||||||
|
19, 17,
|
||||||
|
22, 21
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'interpolate', ['linear'], ['zoom'],
|
||||||
|
8, 8,
|
||||||
|
11, 12,
|
||||||
|
13, 15,
|
||||||
|
15, 18,
|
||||||
|
17, 22,
|
||||||
|
19, 26,
|
||||||
|
22, 32
|
||||||
|
]
|
||||||
|
],
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'circle-color': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
'#fef08a',
|
||||||
|
'transparent'
|
||||||
|
],
|
||||||
|
'circle-opacity': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
0.85,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'circle-stroke-color': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
'#ca8a04',
|
||||||
|
'transparent'
|
||||||
|
],
|
||||||
|
'circle-stroke-width': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
2.5,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'circle-stroke-opacity': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
0.95,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
},
|
||||||
|
minzoom: 8,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ─── 6. Public Export ───────────────────────────────────────────────────────
|
// ─── 6. Public Export ───────────────────────────────────────────────────────
|
||||||
global.AssetSymbology = {
|
global.AssetSymbology = {
|
||||||
THEMATIC_CONFIG,
|
THEMATIC_CONFIG,
|
||||||
|
|
@ -1072,6 +1155,7 @@
|
||||||
getAssetsFillLayer,
|
getAssetsFillLayer,
|
||||||
getAssetsPolygonOutlineLayer,
|
getAssetsPolygonOutlineLayer,
|
||||||
getAssetsLineLayer,
|
getAssetsLineLayer,
|
||||||
|
getAssetsPointSelectionLayer,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure UNIFIED_ICON_URLS is globally available if not already defined
|
// Ensure UNIFIED_ICON_URLS is globally available if not already defined
|
||||||
|
|
|
||||||
|
|
@ -916,11 +916,13 @@ $(document).ready(function () {
|
||||||
row.state = true;
|
row.state = true;
|
||||||
selectedIds.add(row.id);
|
selectedIds.add(row.id);
|
||||||
updateSelectionStatus();
|
updateSelectionStatus();
|
||||||
|
setMapFeatureSelectionState(row, true);
|
||||||
},
|
},
|
||||||
onUncheck: function (row) {
|
onUncheck: function (row) {
|
||||||
row.state = false;
|
row.state = false;
|
||||||
selectedIds.delete(row.id);
|
selectedIds.delete(row.id);
|
||||||
updateSelectionStatus();
|
updateSelectionStatus();
|
||||||
|
setMapFeatureSelectionState(row, false);
|
||||||
},
|
},
|
||||||
onCheckAll: function (rows) {
|
onCheckAll: function (rows) {
|
||||||
selectAllTableRows();
|
selectAllTableRows();
|
||||||
|
|
@ -930,10 +932,15 @@ $(document).ready(function () {
|
||||||
},
|
},
|
||||||
onClickRow: function (row) {
|
onClickRow: function (row) {
|
||||||
if (!row.lon || !row.lat) return;
|
if (!row.lon || !row.lat) return;
|
||||||
|
// With clickToSelect: true, clicking a row toggles its state (checking or unchecking).
|
||||||
|
// If the row was already selected, clicking it will deselect it (onUncheck will run).
|
||||||
|
// Do not highlight a row that is about to be deselected.
|
||||||
|
if (!selectedIds.has(row.id)) {
|
||||||
const source = row.is_management_zone ? 'management_zones' : (row.is_location ? 'locations' : 'assets');
|
const source = row.is_management_zone ? 'management_zones' : (row.is_location ? 'locations' : 'assets');
|
||||||
if (typeof highlightMapFeature === 'function') {
|
if (typeof highlightMapFeature === 'function') {
|
||||||
highlightMapFeature(map, source, row.id, row.is_management_zone ? managementZonesHighlightState : (row.is_location ? locationshighlightState : assetshighlightState));
|
highlightMapFeature(map, source, row.id, row.is_management_zone ? managementZonesHighlightState : (row.is_location ? locationshighlightState : assetshighlightState));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1883,8 +1890,10 @@ function bindUnifiedBulkActions() {
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
bootstrap.Modal.getOrCreateInstance(bulkStatusModalEl).hide();
|
bootstrap.Modal.getOrCreateInstance(bulkStatusModalEl).hide();
|
||||||
|
selectedIds.forEach(id => setMapFeatureSelectionState(id, false));
|
||||||
selectedIds.clear();
|
selectedIds.clear();
|
||||||
updateSelectionStatus();
|
updateSelectionStatus();
|
||||||
|
resetAllHighlightStates();
|
||||||
refreshData();
|
refreshData();
|
||||||
} else {
|
} else {
|
||||||
if (bulkStatusError) {
|
if (bulkStatusError) {
|
||||||
|
|
@ -1943,8 +1952,10 @@ function bindUnifiedBulkActions() {
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
bootstrap.Modal.getOrCreateInstance(bulkValModalEl).hide();
|
bootstrap.Modal.getOrCreateInstance(bulkValModalEl).hide();
|
||||||
|
selectedIds.forEach(id => setMapFeatureSelectionState(id, false));
|
||||||
selectedIds.clear();
|
selectedIds.clear();
|
||||||
updateSelectionStatus();
|
updateSelectionStatus();
|
||||||
|
resetAllHighlightStates();
|
||||||
refreshData();
|
refreshData();
|
||||||
} else {
|
} else {
|
||||||
if (bulkValError) {
|
if (bulkValError) {
|
||||||
|
|
@ -2105,6 +2116,7 @@ function focusRowInUnifiedTable(rowRef) {
|
||||||
function collectClickedAssets(clickEvent) {
|
function collectClickedAssets(clickEvent) {
|
||||||
const layers = [
|
const layers = [
|
||||||
'assets',
|
'assets',
|
||||||
|
'assets-point-selection',
|
||||||
'assets-fill',
|
'assets-fill',
|
||||||
'assets-polygon-outline',
|
'assets-polygon-outline',
|
||||||
'assets-line',
|
'assets-line',
|
||||||
|
|
@ -2872,6 +2884,54 @@ var locationshighlightState = { previousId: null };
|
||||||
var assetshighlightState = { previousId: null };
|
var assetshighlightState = { previousId: null };
|
||||||
var managementZonesHighlightState = { previousId: null };
|
var managementZonesHighlightState = { previousId: null };
|
||||||
|
|
||||||
|
function resetAllHighlightStates(specificId = null) {
|
||||||
|
[assetshighlightState, locationshighlightState, managementZonesHighlightState].forEach(st => {
|
||||||
|
if (st) {
|
||||||
|
if (specificId == null || st.previousId === specificId || String(st.previousId) === String(specificId)) {
|
||||||
|
st.previousId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMapFeatureSelectionState(rowOrId, isSelected) {
|
||||||
|
if (typeof map === 'undefined' || !map) return;
|
||||||
|
const isObj = rowOrId && typeof rowOrId === 'object';
|
||||||
|
const id = isObj ? rowOrId.id : rowOrId;
|
||||||
|
if (id == null) return;
|
||||||
|
|
||||||
|
let targetSource = null;
|
||||||
|
if (isObj) {
|
||||||
|
targetSource = rowOrId.is_management_zone ? 'management_zones' : (rowOrId.is_location ? 'locations' : 'assets');
|
||||||
|
}
|
||||||
|
|
||||||
|
const sources = targetSource ? [targetSource] : ['assets', 'locations', 'management_zones'];
|
||||||
|
|
||||||
|
sources.forEach(src => {
|
||||||
|
try {
|
||||||
|
if (map.getSource(src)) {
|
||||||
|
if (isSelected) {
|
||||||
|
map.setFeatureState({ source: src, id: id }, { selected: true });
|
||||||
|
} else {
|
||||||
|
map.setFeatureState({ source: src, id: id }, { selected: false, highlighted: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isSelected) {
|
||||||
|
resetAllHighlightStates(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncMapSelectionFeatureStates() {
|
||||||
|
if (typeof map === 'undefined' || !map) return;
|
||||||
|
if (selectedIds.size === 0) return;
|
||||||
|
selectedIds.forEach(id => {
|
||||||
|
setMapFeatureSelectionState(id, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function isPanelTextSpriteId(missingId) {
|
function isPanelTextSpriteId(missingId) {
|
||||||
if (!missingId) return false;
|
if (!missingId) return false;
|
||||||
|
|
@ -2965,6 +3025,8 @@ function rebuildMapSources() {
|
||||||
locSrc.setData(mergedLocationsGeojson);
|
locSrc.setData(mergedLocationsGeojson);
|
||||||
asstSrc.setData(mergedAssetsGeojson);
|
asstSrc.setData(mergedAssetsGeojson);
|
||||||
if (zoneSrc) zoneSrc.setData(mergedManagementZonesGeojson);
|
if (zoneSrc) zoneSrc.setData(mergedManagementZonesGeojson);
|
||||||
|
|
||||||
|
syncMapSelectionFeatureStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3129,10 +3191,10 @@ maploader.addEventListener('mapLoaded', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Click interaction on map elements: show popup when assets are found at click position.
|
// Click interaction on map elements: show popup when assets are found at click position.
|
||||||
['assets', 'assets-fill', 'assets-line', 'assets-point', 'sign-panels-circles', 'sign-panels-symbols', 'sign-poles-orientation', 'sign-poles', 'sign-poles-vertical', 'locations', 'locations-circle', 'locations-radar', 'locations-radar-outline', 'locations-outline', 'management-zones-fill', 'management-zones-line'].forEach(layerId => {
|
['assets', 'assets-point-selection', 'assets-fill', 'assets-line', 'assets-point', 'sign-panels-circles', 'sign-panels-symbols', 'sign-poles-orientation', 'sign-poles', 'sign-poles-vertical', 'locations', 'locations-circle', 'locations-radar', 'locations-radar-outline', 'locations-outline', 'management-zones-fill', 'management-zones-line'].forEach(layerId => {
|
||||||
if (!map.getLayer(layerId)) return;
|
if (!map.getLayer(layerId)) return;
|
||||||
map.on('click', layerId, showAssetClickPopup);
|
map.on('click', layerId, showAssetClickPopup);
|
||||||
if (['assets', 'assets-fill', 'assets-line', 'assets-point', 'sign-panels-circles', 'sign-panels-symbols', 'sign-poles-orientation', 'sign-poles', 'sign-poles-vertical', 'management-zones-fill'].includes(layerId)) {
|
if (['assets', 'assets-point-selection', 'assets-fill', 'assets-line', 'assets-point', 'sign-panels-circles', 'sign-panels-symbols', 'sign-poles-orientation', 'sign-poles', 'sign-poles-vertical', 'management-zones-fill'].includes(layerId)) {
|
||||||
map.on('mouseenter', layerId, function () { map.getCanvas().style.cursor = 'pointer'; });
|
map.on('mouseenter', layerId, function () { map.getCanvas().style.cursor = 'pointer'; });
|
||||||
map.on('mouseleave', layerId, function () { map.getCanvas().style.cursor = ''; });
|
map.on('mouseleave', layerId, function () { map.getCanvas().style.cursor = ''; });
|
||||||
}
|
}
|
||||||
|
|
@ -3142,7 +3204,7 @@ maploader.addEventListener('mapLoaded', () => {
|
||||||
map.on('click', function (e) {
|
map.on('click', function (e) {
|
||||||
if (!assetClickPopup || !assetClickPopup.isOpen()) return;
|
if (!assetClickPopup || !assetClickPopup.isOpen()) return;
|
||||||
|
|
||||||
const interactiveLayers = ['assets', 'assets-fill', 'assets-line', 'assets-point', 'sign-panels-circles', 'sign-panels-symbols', 'sign-poles-orientation', 'sign-poles', 'sign-poles-vertical', 'locations', 'locations-circle', 'locations-radar', 'locations-radar-outline', 'locations-outline', 'management-zones-fill', 'management-zones-line']
|
const interactiveLayers = ['assets', 'assets-point-selection', 'assets-fill', 'assets-line', 'assets-point', 'sign-panels-circles', 'sign-panels-symbols', 'sign-poles-orientation', 'sign-poles', 'sign-poles-vertical', 'locations', 'locations-circle', 'locations-radar', 'locations-radar-outline', 'locations-outline', 'management-zones-fill', 'management-zones-line']
|
||||||
.filter(layerId => map.getLayer(layerId));
|
.filter(layerId => map.getLayer(layerId));
|
||||||
if (!interactiveLayers.length) {
|
if (!interactiveLayers.length) {
|
||||||
assetClickPopup.remove();
|
assetClickPopup.remove();
|
||||||
|
|
@ -3234,6 +3296,7 @@ function selectAllTableRows() {
|
||||||
allRows.forEach(r => {
|
allRows.forEach(r => {
|
||||||
selectedIds.add(r.id);
|
selectedIds.add(r.id);
|
||||||
r.state = true;
|
r.state = true;
|
||||||
|
setMapFeatureSelectionState(r, true);
|
||||||
});
|
});
|
||||||
$('#unified-table tbody tr').addClass('selected');
|
$('#unified-table tbody tr').addClass('selected');
|
||||||
$('#unified-table input[name="btSelectItem"]').prop('checked', true);
|
$('#unified-table input[name="btSelectItem"]').prop('checked', true);
|
||||||
|
|
@ -3250,11 +3313,16 @@ function deselectAllTableRows() {
|
||||||
const allRows = getAllTableRows();
|
const allRows = getAllTableRows();
|
||||||
allRows.forEach(r => {
|
allRows.forEach(r => {
|
||||||
r.state = false;
|
r.state = false;
|
||||||
selectedIds.delete(r.id);
|
setMapFeatureSelectionState(r, false);
|
||||||
});
|
});
|
||||||
|
selectedIds.forEach(id => {
|
||||||
|
setMapFeatureSelectionState(id, false);
|
||||||
|
});
|
||||||
|
selectedIds.clear();
|
||||||
$('#unified-table tbody tr').removeClass('selected');
|
$('#unified-table tbody tr').removeClass('selected');
|
||||||
$('#unified-table input[name="btSelectItem"]').prop('checked', false);
|
$('#unified-table input[name="btSelectItem"]').prop('checked', false);
|
||||||
updateSelectionStatus();
|
updateSelectionStatus();
|
||||||
|
resetAllHighlightStates();
|
||||||
} finally {
|
} finally {
|
||||||
isBulkSelectionInProgress = false;
|
isBulkSelectionInProgress = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -429,8 +429,16 @@ const _unified_management_zones_fill = {
|
||||||
['==', ['geometry-type'], 'MultiPolygon']
|
['==', ['geometry-type'], 'MultiPolygon']
|
||||||
],
|
],
|
||||||
paint: {
|
paint: {
|
||||||
'fill-color': ['coalesce', ['get', 'color'], '#10b981'],
|
'fill-color': [
|
||||||
'fill-opacity': 0.25,
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#fef08a',
|
||||||
|
['coalesce', ['get', 'color'], '#10b981']
|
||||||
|
],
|
||||||
|
'fill-opacity': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 0.8,
|
||||||
|
0.25
|
||||||
|
],
|
||||||
'fill-antialias': false,
|
'fill-antialias': false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -441,8 +449,16 @@ const _unified_management_zones_line = {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
source: 'management_zones',
|
source: 'management_zones',
|
||||||
paint: {
|
paint: {
|
||||||
'line-color': ['coalesce', ['get', 'color'], '#10b981'],
|
'line-color': [
|
||||||
'line-width': 2,
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
|
['coalesce', ['get', 'color'], '#10b981']
|
||||||
|
],
|
||||||
|
'line-width': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 4,
|
||||||
|
2
|
||||||
|
],
|
||||||
'line-dasharray': [3, 2],
|
'line-dasharray': [3, 2],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -502,7 +518,7 @@ const _unified_locations_outline = {
|
||||||
paint: {
|
paint: {
|
||||||
'line-color': [
|
'line-color': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], '#ffeb3b',
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
['any', ['==', ['get', 'thematic'], 'publicbuildings'], ['==', ['get', 'thematic'], 'buildings']],
|
['any', ['==', ['get', 'thematic'], 'publicbuildings'], ['==', ['get', 'thematic'], 'buildings']],
|
||||||
[
|
[
|
||||||
'match',
|
'match',
|
||||||
|
|
@ -521,7 +537,7 @@ const _unified_locations_outline = {
|
||||||
],
|
],
|
||||||
'line-width': [
|
'line-width': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], 3,
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 4,
|
||||||
['any', ['==', ['get', 'thematic'], 'publicbuildings'], ['==', ['get', 'thematic'], 'buildings']], 2,
|
['any', ['==', ['get', 'thematic'], 'publicbuildings'], ['==', ['get', 'thematic'], 'buildings']], 2,
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
|
|
@ -549,6 +565,7 @@ const _unified_locations_circle = {
|
||||||
// Colour by building usage_type or intersection status
|
// Colour by building usage_type or intersection status
|
||||||
'circle-color': [
|
'circle-color': [
|
||||||
'case',
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
['any', ['==', ['get', 'thematic'], 'publicbuildings'], ['==', ['get', 'thematic'], 'buildings']],
|
['any', ['==', ['get', 'thematic'], 'publicbuildings'], ['==', ['get', 'thematic'], 'buildings']],
|
||||||
[
|
[
|
||||||
'match',
|
'match',
|
||||||
|
|
@ -576,10 +593,14 @@ const _unified_locations_circle = {
|
||||||
],
|
],
|
||||||
'circle-stroke-color': [
|
'circle-stroke-color': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], '#ffeb3b',
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
'#ffffff'
|
'#ffffff'
|
||||||
],
|
],
|
||||||
'circle-stroke-width': 1.5,
|
'circle-stroke-width': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 3,
|
||||||
|
1.5
|
||||||
|
],
|
||||||
'circle-opacity': 0.85,
|
'circle-opacity': 0.85,
|
||||||
},
|
},
|
||||||
minzoom: 7,
|
minzoom: 7,
|
||||||
|
|
@ -604,7 +625,7 @@ const _unified_locations_radar_outline = {
|
||||||
paint: {
|
paint: {
|
||||||
'icon-color': [
|
'icon-color': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], '#ffeb3b',
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
'#ffffff'
|
'#ffffff'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -628,6 +649,9 @@ const _unified_locations_radar = {
|
||||||
},
|
},
|
||||||
paint: {
|
paint: {
|
||||||
'icon-color': [
|
'icon-color': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3bbf',
|
||||||
|
[
|
||||||
'match', ['get', 'status'],
|
'match', ['get', 'status'],
|
||||||
'active', '#0094ff',
|
'active', '#0094ff',
|
||||||
'in_preparation', '#f59f00',
|
'in_preparation', '#f59f00',
|
||||||
|
|
@ -637,6 +661,7 @@ const _unified_locations_radar = {
|
||||||
'archived', '#6c757d',
|
'archived', '#6c757d',
|
||||||
'#0094ff'
|
'#0094ff'
|
||||||
]
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
minzoom: 7,
|
minzoom: 7,
|
||||||
};
|
};
|
||||||
|
|
@ -957,7 +982,7 @@ const _unified_assets_symbol = {
|
||||||
['==', ['get', 'asset_type'], 'naturegreensurface'], 0,
|
['==', ['get', 'asset_type'], 'naturegreensurface'], 0,
|
||||||
['==', ['get', 'asset_type'], 'itsbollardsystem'], 0,
|
['==', ['get', 'asset_type'], 'itsbollardsystem'], 0,
|
||||||
['match', ['geometry-type'], ['LineString', 'MultiLineString'], true, false], 0,
|
['match', ['geometry-type'], ['LineString', 'MultiLineString'], true, false], 0,
|
||||||
['boolean', ['feature-state', 'highlighted'], false], 1,
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 1,
|
||||||
0.85
|
0.85
|
||||||
],
|
],
|
||||||
'text-color': '#333333',
|
'text-color': '#333333',
|
||||||
|
|
@ -988,14 +1013,19 @@ const _unified_sign_poles_circle = {
|
||||||
'circle-opacity': 0.8,
|
'circle-opacity': 0.8,
|
||||||
'circle-stroke-color': [
|
'circle-stroke-color': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], '#ffeb3b',
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
'#333333'
|
'#333333'
|
||||||
],
|
],
|
||||||
'circle-stroke-width': [
|
'circle-stroke-width': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
3 * UNIFIED_SIGN_SYMBOL_SCALE,
|
||||||
|
[
|
||||||
'interpolate', ['linear'], ['zoom'],
|
'interpolate', ['linear'], ['zoom'],
|
||||||
8, 0,
|
8, 0,
|
||||||
13, 1 * UNIFIED_SIGN_SYMBOL_SCALE
|
13, 1 * UNIFIED_SIGN_SYMBOL_SCALE
|
||||||
]
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
minzoom: 8,
|
minzoom: 8,
|
||||||
};
|
};
|
||||||
|
|
@ -1014,8 +1044,17 @@ const _unified_sign_panels_circles = {
|
||||||
17, 10 * UNIFIED_SIGN_SYMBOL_SCALE
|
17, 10 * UNIFIED_SIGN_SYMBOL_SCALE
|
||||||
],
|
],
|
||||||
'circle-color': '#0022ff',
|
'circle-color': '#0022ff',
|
||||||
'circle-stroke-color': '#0011aa',
|
'circle-stroke-color': [
|
||||||
'circle-stroke-width': 1 * UNIFIED_SIGN_SYMBOL_SCALE,
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
|
'#0011aa'
|
||||||
|
],
|
||||||
|
'circle-stroke-width': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
2.5 * UNIFIED_SIGN_SYMBOL_SCALE,
|
||||||
|
1 * UNIFIED_SIGN_SYMBOL_SCALE
|
||||||
|
],
|
||||||
'circle-opacity': 0.8
|
'circle-opacity': 0.8
|
||||||
},
|
},
|
||||||
maxzoom: 17,
|
maxzoom: 17,
|
||||||
|
|
@ -1147,6 +1186,81 @@ const _unified_assets_line = (typeof AssetSymbology !== 'undefined' && AssetSymb
|
||||||
minzoom: 8,
|
minzoom: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ─── Layer 4a — point assets selection halo (circle behind point assets) ──────
|
||||||
|
const _unified_assets_point_selection = (typeof AssetSymbology !== 'undefined' && AssetSymbology.getAssetsPointSelectionLayer)
|
||||||
|
? AssetSymbology.getAssetsPointSelectionLayer('assets')
|
||||||
|
: {
|
||||||
|
id: 'assets-point-selection',
|
||||||
|
type: 'circle',
|
||||||
|
source: 'assets',
|
||||||
|
filter: ['any',
|
||||||
|
['==', ['geometry-type'], 'Point'],
|
||||||
|
['==', ['geometry-type'], 'MultiPoint']
|
||||||
|
],
|
||||||
|
paint: {
|
||||||
|
'circle-radius': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
[
|
||||||
|
'case',
|
||||||
|
['any', ['==', ['get', 'asset_type'], 'naturetree'], ['==', ['get', 'asset_type'], 'natureshrub'], ['==', ['get', 'thematic'], 'nature']],
|
||||||
|
[
|
||||||
|
'interpolate', ['linear'], ['zoom'],
|
||||||
|
8, 4,
|
||||||
|
11, 6,
|
||||||
|
13, 8,
|
||||||
|
15, 11,
|
||||||
|
17, 14,
|
||||||
|
19, 17,
|
||||||
|
22, 21
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'interpolate', ['linear'], ['zoom'],
|
||||||
|
8, 8,
|
||||||
|
11, 12,
|
||||||
|
13, 15,
|
||||||
|
15, 18,
|
||||||
|
17, 22,
|
||||||
|
19, 26,
|
||||||
|
22, 32
|
||||||
|
]
|
||||||
|
],
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'circle-color': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
'#fef08a',
|
||||||
|
'transparent'
|
||||||
|
],
|
||||||
|
'circle-opacity': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
0.85,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'circle-stroke-color': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
'#ca8a04',
|
||||||
|
'transparent'
|
||||||
|
],
|
||||||
|
'circle-stroke-width': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
2.5,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'circle-stroke-opacity': [
|
||||||
|
'case',
|
||||||
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]],
|
||||||
|
0.95,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
},
|
||||||
|
minzoom: 8,
|
||||||
|
};
|
||||||
|
|
||||||
// ─── Layer 4b — road assets circles (point roadway/sidewalk assets) ──────────
|
// ─── Layer 4b — road assets circles (point roadway/sidewalk assets) ──────────
|
||||||
const _unified_assets_point = {
|
const _unified_assets_point = {
|
||||||
id: 'assets-point',
|
id: 'assets-point',
|
||||||
|
|
@ -1171,17 +1285,17 @@ const _unified_assets_point = {
|
||||||
],
|
],
|
||||||
'circle-stroke-color': [
|
'circle-stroke-color': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], '#ffeb3b',
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
'#ffffff'
|
'#ffffff'
|
||||||
],
|
],
|
||||||
'circle-stroke-width': [
|
'circle-stroke-width': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], 2,
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 3,
|
||||||
0
|
0
|
||||||
],
|
],
|
||||||
'circle-opacity': [
|
'circle-opacity': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], 1.0,
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 1.0,
|
||||||
0.85
|
0.85
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -1202,14 +1316,14 @@ const _unified_assets_polygon_outline = (typeof AssetSymbology !== 'undefined' &
|
||||||
paint: {
|
paint: {
|
||||||
'line-color': [
|
'line-color': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], '#ffeb3b',
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], '#ffeb3b',
|
||||||
['==', ['get', 'thematic'], 'parking'],
|
['==', ['get', 'thematic'], 'parking'],
|
||||||
(typeof AssetSymbology !== 'undefined' ? AssetSymbology.getParkingColorExpr() : '#0d6efd'),
|
(typeof AssetSymbology !== 'undefined' ? AssetSymbology.getParkingColorExpr() : '#0d6efd'),
|
||||||
THEMATIC_COLOR_EXPR
|
THEMATIC_COLOR_EXPR
|
||||||
],
|
],
|
||||||
'line-width': [
|
'line-width': [
|
||||||
'case',
|
'case',
|
||||||
['boolean', ['feature-state', 'highlighted'], false], 4,
|
['any', ['boolean', ['feature-state', 'highlighted'], false], ['boolean', ['feature-state', 'selected'], false]], 4,
|
||||||
2
|
2
|
||||||
],
|
],
|
||||||
'line-opacity': 0.9,
|
'line-opacity': 0.9,
|
||||||
|
|
@ -1233,9 +1347,10 @@ const UNIFIED_LAYERS = [
|
||||||
_unified_locations_circle, // 4. circles
|
_unified_locations_circle, // 4. circles
|
||||||
_unified_locations_radar_outline,
|
_unified_locations_radar_outline,
|
||||||
_unified_locations_radar,
|
_unified_locations_radar,
|
||||||
|
_unified_assets_point_selection,// 4a. point asset selection halo (behind symbols)
|
||||||
_unified_assets_point, // 4b. road assets circles
|
_unified_assets_point, // 4b. road assets circles
|
||||||
_unified_sign_poles_circle,
|
_unified_sign_poles_circle,
|
||||||
_unified_assets_symbol,
|
_unified_assets_symbol, // 5. asset symbols (on top of halo)
|
||||||
_unified_sign_panels_circles,
|
_unified_sign_panels_circles,
|
||||||
_unified_sign_poles_orientation,
|
_unified_sign_poles_orientation,
|
||||||
_unified_sign_poles_vertical,
|
_unified_sign_poles_vertical,
|
||||||
|
|
|
||||||
|
|
@ -1636,7 +1636,7 @@
|
||||||
<script src="{% static 'common/base_script.js' %}"></script>
|
<script src="{% static 'common/base_script.js' %}"></script>
|
||||||
<script src="{% static 'common/base_map.js' %}"></script>
|
<script src="{% static 'common/base_map.js' %}"></script>
|
||||||
<script src="{% static 'assets/sign_panels_shared.js' %}?v=20260703c"></script>
|
<script src="{% static 'assets/sign_panels_shared.js' %}?v=20260703c"></script>
|
||||||
<script src="{% static 'assets/asset_symbology.js' %}?v=20261012_tree_scale"></script>
|
<script src="{% static 'assets/asset_symbology.js' %}?v=20261012_point_select"></script>
|
||||||
<script src="{% static 'assets/unified_map_layers.js' %}?v=20261012_tree_scale"></script>
|
<script src="{% static 'assets/unified_map_layers.js' %}?v=20261012_point_select"></script>
|
||||||
<script src="{% static 'assets/unified_index.js' %}?v=20261012_tree_scale"></script>
|
<script src="{% static 'assets/unified_index.js' %}?v=20261012_point_select"></script>
|
||||||
{% endblock script %}
|
{% endblock script %}
|
||||||
Loading…
Reference in a new issue