Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1119 scale dependency indicator #2758

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"map": {
"interaction": "dynamic",
"viewSettings": {
"projection": 3978
},
"basemapOptions": {
"basemapId": "transport",
"shaded": false,
"labeled": true
},
"listOfGeoviewLayerConfig": [
{
"geoviewLayerId": "wmsLYR1",
"geoviewLayerName": "earthquakes",
"metadataAccessPath": "https://maps-cartes.services.geo.ca/server_serveur/rest/services/NRCan/earthquakes_en/MapServer/",
"geoviewLayerType": "esriDynamic",
"listOfLayerEntryConfig": [
{
"layerId": "0",
"layerName": "Limited by Scale - Earthquakes 1980 - 1990, by Magnitude",
"maxScale": 10000000
}
]
},
{
"geoviewLayerId": "89d44ba6-7236-48ed-afab-f25a98c846ef",
"geoviewLayerType": "geoCore",
"listOfLayerEntryConfig": [
{
"layerId": "pub:WHSE_IMAGERY_AND_BASE_MAPS.MOT_CULVERTS_SP",
"layerName": "Limited by Service - BC Minitstry of Transportation Culverts"
}
]
},
{
"geoviewLayerId": "uniqueValueId",
"geoviewLayerName": "uniqueValue",
"metadataAccessPath": "https://maps-cartes.ec.gc.ca/arcgis/rest/services/CESI/MapServer/",
"geoviewLayerType": "esriDynamic",
"listOfLayerEntryConfig": [
{
"layerId": "4",
"layerName": "Limited by Zoom - Water Quality",
"entryType": "group",
"initialSettings": {
"minZoom": 5
},
"listOfLayerEntryConfig": [
{
"layerId": "5",
"initialSettings": {
"minZoom": 7
}
},
{
"layerId": "6"
},
{
"layerId": "7"
}
]
}
]
}
]
},
"components": ["overview-map"],
"footerBar": {
"tabs": {
"core": ["legend", "layers", "details", "data-table"]
}
},
"corePackages": [],
"theme": "geo.ca"
}
17 changes: 16 additions & 1 deletion packages/geoview-core/public/configs/navigator/15-xyz-tile.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,22 @@
"initialSettings": { "minZoom": 3, "maxZoom": 8 }
}
]
}
},
{
"geoviewLayerId": "xyzTilesLYR2",
"geoviewLayerName": "GNOSIS_Blue_Marble",
"metadataAccessPath": "https://maps.gnosis.earth/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad",
"geoviewLayerType": "xyzTiles",
"listOfLayerEntryConfig": [
{
"layerId": "blueMarble",
"layerName": "GNOSIS Blue Marble",
"source": {
"dataAccessPath": "https://maps.gnosis.earth/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad/{z}/{y}/{x}.jpg"
}
}
]
}
]
},
"components": ["overview-map"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,26 @@
"listOfGeoviewLayerConfig": [
{
"geoviewLayerId": "vectorTilesLYR1",
"geoviewLayerName": "new basemap",
"geoviewLayerName": "CBCT - French Basemap",
"geoviewLayerType": "vectorTiles",
"metadataAccessPath": "https://tiles.arcgis.com/tiles/HsjBaDykC1mjhXz9/arcgis/rest/services/CBMT_CBCT_3978_V_OSM/VectorTileServer/",
"listOfLayerEntryConfig": [
{
"layerId": "CBMT_CBCT_3978_V_OSM",
"styleUrl": "https://nrcan-rncan.maps.arcgis.com/sharing/rest/content/items/88ad9e2ef6e040a19472985e6606a2f9/resources/styles/root.json",
"initialSettings": { "minZoom": 3, "maxZoom": 18 }
}
]
},
{
"geoviewLayerId": "vectorTilesLYR2",
"geoviewLayerName": "CBMT - English Basemap",
"geoviewLayerType": "vectorTiles",
"metadataAccessPath": "https://tiles.arcgis.com/tiles/HsjBaDykC1mjhXz9/arcgis/rest/services/CBMT_CBCT_3978_V_OSM/VectorTileServer/",
"listOfLayerEntryConfig": [
{
"layerId": "CBMT_CBCT_3978_V_OSM",
"styleUrl": "https://nrcan-rncan.maps.arcgis.com/sharing/rest/content/items/708e92c1f00941e3af3dd3c092ae4a0a/resources/styles/root.json",
"initialSettings": { "minZoom": 3, "maxZoom": 18 }
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ <h1><strong>Configurations Navigator</strong></h1>
<option value="./configs/navigator/03-projection-WM.json">Basemap WM</option>
<option value="./configs/navigator/04-restrict-zoom.json">Restricted zoom [4, 8]</option>
<option value="./configs/navigator/05-zoom-layer.json">Zoom on layer extent</option>
<option value="./configs/navigator/05-layer-zoom-levels.json">Layer Max and Min Zoom Settings</option>
<option value="./configs/navigator/06-basic-footer.json">Basic map with footer</option>
<option value="./configs/navigator/07-basic-appbar.json">Basic map with app bar</option>
<option value="./configs/navigator/26-package-area-of-interest.json">Package Area of interest</option>
Expand Down
9 changes: 6 additions & 3 deletions packages/geoview-core/public/templates/sandbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,10 @@ <h4 id="HLCONF1">Sanbox Map</h4>
try {
// get config and test if JSON is valid
const configArea = document.getElementById('configGeoview');
const configJSON = JSON.parse(configArea.value.replaceAll(`'`, `"`));
const regexExp = /(?<!\\)'/g
const configJSON = JSON.parse(configArea.value.replaceAll(regexExp, `"`).replaceAll('\\', '\\\\'));

const validConfig = cgpv.api.config.createMapConfig(document.getElementById('configGeoview').value.replaceAll("'", '"'), 'en');
const validConfig = cgpv.api.config.createMapConfig(document.getElementById('configGeoview').value.replaceAll(regexExp, '"'), 'en');

// set class and message
message.classList.add('config-json-valid');
Expand Down Expand Up @@ -244,7 +245,9 @@ <h4 id="HLCONF1">Sanbox Map</h4>
// TODO: the delete has a timeout so we need to wait before trying to recreate the map...
// TO.DOCONT: this should be cleaner
setTimeout(() => {
cgpv.api.createMapFromConfig('sandboxMap', document.getElementById('configGeoview').value.replaceAll("'", '"'))
// Regex expression to cature all single quotes (') except those preceded by a backslash (\)
const regexExp = /(?<!\\)'/g
cgpv.api.createMapFromConfig('sandboxMap', document.getElementById('configGeoview').value.replaceAll(regexExp, '"'))
.then(() => listenToLegendLayerSetChanges('sandboxMap-state', 'sandboxMap'));
}, 1500);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const CV_CONST_LEAF_LAYER_SCHEMA_PATH: Record<LayerTypesKey, string> = {
IMAGE_STATIC: 'https://cgpv/schema#/definitions/ImageStaticLayerEntryConfig',
GEOPACKAGE: 'https://cgpv/schema#/definitions/VectorLayerEntryConfig',
XYZ_TILES: 'https://cgpv/schema#/definitions/TileLayerEntryConfig',
VECTOR_TILES: 'Thttps://cgpv/schema#/definitions/TileLayerEntryConfig',
VECTOR_TILES: 'https://cgpv/schema#/definitions/TileLayerEntryConfig',
OGC_FEATURE: 'https://cgpv/schema#/definitions/VectorLayerEntryConfig',
CSV: 'https://cgpv/schema#/definitions/VectorLayerEntryConfig',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ export class LegendEventProcessor extends AbstractEventProcessor {
layerName,
layerStatus: legendResultSetEntry.layerStatus,
legendQueryStatus: legendResultSetEntry.legendQueryStatus,
maxZoom: layerConfig.initialSettings.maxZoom,
minZoom: layerConfig.initialSettings.minZoom,
type: layerConfig.entryType as TypeGeoviewLayerType,
canToggle: legendResultSetEntry.data?.type !== CONST_LAYER_TYPES.ESRI_IMAGE,
opacity: layerConfig.initialSettings?.states?.opacity ? layerConfig.initialSettings.states.opacity : 1,
Expand Down Expand Up @@ -328,6 +330,8 @@ export class LegendEventProcessor extends AbstractEventProcessor {
layerName,
layerStatus: legendResultSetEntry.layerStatus,
legendQueryStatus: legendResultSetEntry.legendQueryStatus,
maxZoom: layerConfig.initialSettings.maxZoom,
minZoom: layerConfig.initialSettings.minZoom,
styleConfig: legendResultSetEntry.data?.styleConfig,
type: legendResultSetEntry.data?.type || (layerConfig.entryType as TypeGeoviewLayerType),
canToggle: legendResultSetEntry.data?.type !== CONST_LAYER_TYPES.ESRI_IMAGE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,23 @@ export class MapEventProcessor extends AbstractEventProcessor {
if (getAppCrosshairsActive(mapId)) this.getMapViewer(mapId).emitMapSingleClick(clickCoordinates);
}

static setZoom(mapId: string, zoom: number): void {
static setLayerInVisibleRange(mapId: string, layerPath: string, inVisibleRange: boolean): void {
const { orderedLayerInfo } = this.getMapStateProtected(mapId);
const orderedLayer = orderedLayerInfo.find((layer) => layer.layerPath === layerPath);

if (orderedLayer && orderedLayer.inVisibleRange !== inVisibleRange) {
orderedLayer.inVisibleRange = inVisibleRange;
this.setOrderedLayerInfoWithNoOrderChangeState(mapId, orderedLayerInfo);
}
}

static setZoom(mapId: string, zoom: number, orderedLayerInfo?: TypeOrderedLayerInfo[]): void {
// Save in store
this.getMapStateProtected(mapId).setterActions.setZoom(zoom);

if (orderedLayerInfo) {
this.setOrderedLayerInfoWithNoOrderChangeState(mapId, orderedLayerInfo);
}
}

static setIsMouseInsideMap(mapId: string, inside: boolean): void {
Expand Down Expand Up @@ -588,16 +602,17 @@ export class MapEventProcessor extends AbstractEventProcessor {

static getMapLegendCollapsedFromOrderedLayerInfo(mapId: string, layerPath: string): boolean {
// Get legend status of a layer
const info = this.getMapStateProtected(mapId).orderedLayerInfo;
const pathInfo = info.find((item) => item.layerPath === layerPath);
return pathInfo?.legendCollapsed !== false;
return this.findMapLayerFromOrderedInfo(mapId, layerPath)?.legendCollapsed !== false;
}

static getMapVisibilityFromOrderedLayerInfo(mapId: string, layerPath: string): boolean {
// Get visibility of a layer
const info = this.getMapStateProtected(mapId).orderedLayerInfo;
const pathInfo = info.find((item) => item.layerPath === layerPath);
return pathInfo?.visible !== false;
return this.findMapLayerFromOrderedInfo(mapId, layerPath)?.visible !== false;
}

static getMapInVisibleRangeFromOrderedLayerInfo(mapId: string, layerPath: string): boolean {
// Get inVisibleRange of a layer
return this.findMapLayerFromOrderedInfo(mapId, layerPath)?.inVisibleRange !== false;
}

static addHighlightedFeature(mapId: string, feature: TypeFeatureInfoEntry): void {
Expand Down
4 changes: 2 additions & 2 deletions packages/geoview-core/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ export async function initMapDivFromFunctionCall(mapDiv: HTMLElement, mapConfig:

// Create a data-config attribute and set config value on the div
const att = document.createAttribute(url ? 'data-config-url' : 'data-config');
// Clean apostrophes in the config
att.value = mapConfig.replaceAll("'", "\\'");
// Clean apostrophes in the config if not escaped already
att.value = mapConfig.replaceAll(/(?<!\\)'/g, "\\'");
mapDiv.setAttributeNode(att);

// Set the geoview-map class on the div so that this class name is standard for all maps (either created via init or via func call)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export const getSxClasses = (theme: Theme): SxStyles => ({
fontSize: theme.palette.geoViewFontSize.lg,
fontWeight: '600',
},

'& .MuiListItem-root': {
height: '100%',
'& .MuiListItemButton-root': {
Expand Down Expand Up @@ -93,4 +92,17 @@ export const getSxClasses = (theme: Theme): SxStyles => ({
layersInstructionsBody: {
fontSize: theme.palette.geoViewFontSize.default,
},
outOfRange: {
'.layer-panel &.MuiListItemButton-root': {
backgroundColor: `${theme.palette.grey[200]} !important`,
'& .MuiListItemText-primary': {
color: `${theme.palette.grey[600]} !important`,
fontStyle: 'italic',
},
'& .MuiListItemText-secondary': {
color: theme.palette.grey[500],
fontStyle: 'italic',
},
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import { useTranslation } from 'react-i18next';
import _ from 'lodash';
import { animated } from '@react-spring/web';
import { Theme } from '@mui/material/styles';
import { useTheme } from '@mui/material/styles';
import { getSxClasses } from '../../common/layer-list-style';
import {
Collapse,
IconButton,
Expand Down Expand Up @@ -30,6 +31,7 @@
useMapStoreActions,
useSelectorLayerLegendCollapsed,
useSelectorLayerVisibility,
useSelectorLayerInVisibleRange,
} from '@/core/stores/store-interface-and-intial-values/map-state';
import { DeleteUndoButton } from './delete-undo-button';
import { LayersList } from './layers-list';
Expand All @@ -56,6 +58,9 @@

const { t } = useTranslation<string>();

const theme = useTheme();
const sxClasses = useMemo(() => getSxClasses(theme), [theme]);

// Get store states
const { setSelectedLayerPath, setSelectedLayerSortingArrowId } = useLayerStoreActions();
const { setOrToggleLayerVisibility, setLegendCollapsed, reorderLayer } = useMapStoreActions();
Expand All @@ -70,6 +75,7 @@
useDataTableStoreActions();

const isVisible = useSelectorLayerVisibility(layer.layerPath);
const inVisibleRange = useSelectorLayerInVisibleRange(layer.layerPath);
const legendExpanded = !useSelectorLayerLegendCollapsed(layer.layerPath);

// TODO: I think we should favor using this pattern here, with the store, instead of working with the whole 'layer' object from the props
Expand Down Expand Up @@ -250,7 +256,7 @@
sx={{
marginLeft: '0.4rem',
height: '1.5rem',
backgroundColor: (theme: Theme) => theme.palette.geoViewColor.bgColor.dark[300],
backgroundColor: theme.palette.geoViewColor.bgColor.dark[300],
}}
variant="middle"
flexItem
Expand Down Expand Up @@ -280,7 +286,7 @@
);
}
return null;
}, [

Check warning on line 289 in packages/geoview-core/src/core/components/layers/left-panel/single-layer.tsx

View workflow job for this annotation

GitHub Actions / Build demo files / build-geoview

React Hook useMemo has a missing dependency: 'theme.palette.geoViewColor.bgColor.dark'. Either include it or remove the dependency array
displayState,
handleIconButtonDownKeyDown,
handleIconButtonUpKeyDown,
Expand Down Expand Up @@ -446,7 +452,8 @@
<ListItemButton
selected={layerIsSelected || (layerChildIsSelected && !legendExpanded)}
tabIndex={-1}
sx={{ minHeight: '4.51rem' }}
sx={{ minHeight: '4.51rem', ...(!inVisibleRange && sxClasses.outOfRange) }}
className={!inVisibleRange ? 'out-of-range' : ''}
>
<LayerIcon layer={layer} />
<ListItemText
Expand Down
2 changes: 2 additions & 0 deletions packages/geoview-core/src/core/components/layers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface TypeLegendLayer {
layerAttribution?: string[];
layerName: string;
legendQueryStatus: string;
maxZoom?: number;
minZoom?: number;
type?: TypeGeoviewLayerType;
styleConfig?: TypeLayerStyleConfig | null;
layerStatus?: TypeLayerStatus;
Expand Down
15 changes: 12 additions & 3 deletions packages/geoview-core/src/core/components/legend/legend-layer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { useTranslation } from 'react-i18next';
import { useTheme } from '@mui/material';
import { Box, ListItem, Tooltip, ListItemText, IconButton, KeyboardArrowDownIcon, KeyboardArrowUpIcon } from '@/ui';
import { TypeLegendLayer } from '@/core/components/layers/types';
import { useMapStoreActions, useSelectorLayerLegendCollapsed, useSelectorLayerStatus, useSelectorLayerVisibility } from '@/core/stores/';
import {
useMapStoreActions,
useSelectorLayerLegendCollapsed,
useSelectorLayerStatus,
useSelectorLayerVisibility,
useSelectorLayerInVisibleRange,
} from '@/core/stores/';
import { useLightBox } from '@/core/components/common';
import { LayerIcon } from '@/core/components/common/layer-icon';
import { SecondaryControls } from './legend-layer-ctrl';
Expand All @@ -19,6 +25,7 @@ interface LegendLayerHeaderProps {
layer: TypeLegendLayer;
isCollapsed: boolean;
isVisible: boolean;
inVisibleRange: boolean;
tooltip: string;
onExpandClick: (event: React.MouseEvent) => void;
}
Expand All @@ -32,8 +39,8 @@ const styles = {

// Extracted Header Component
const LegendLayerHeader = memo(
({ layer, isCollapsed, isVisible, tooltip, onExpandClick }: LegendLayerHeaderProps): JSX.Element => (
<ListItem key={layer.layerName} divider onClick={onExpandClick}>
({ layer, isCollapsed, isVisible, inVisibleRange, tooltip, onExpandClick }: LegendLayerHeaderProps): JSX.Element => (
<ListItem key={layer.layerName} divider onClick={onExpandClick} className={!inVisibleRange ? 'outOfRange' : ''}>
<LayerIcon layer={layer} />
<Tooltip title={layer.layerName} placement="top">
<ListItemText
Expand Down Expand Up @@ -69,6 +76,7 @@ export function LegendLayer({ layer }: LegendLayerProps): JSX.Element {
const { setLegendCollapsed } = useMapStoreActions();
const isVisible = useSelectorLayerVisibility(layer.layerPath);
const isCollapsed = useSelectorLayerLegendCollapsed(layer.layerPath);
const inVisibleRange = useSelectorLayerInVisibleRange(layer.layerPath);
const layerStatus = useSelectorLayerStatus(layer.layerPath);

// TODO: Check - Probably don't do that as it creates a new layer object and new items and new children, etc causing multiple re-renderings
Expand Down Expand Up @@ -99,6 +107,7 @@ export function LegendLayer({ layer }: LegendLayerProps): JSX.Element {
layer={currentLayer}
isCollapsed={isCollapsed}
isVisible={isVisible}
inVisibleRange={inVisibleRange}
tooltip={t('layers.toggleCollapse') as string}
onExpandClick={handleExpandGroupClick}
/>
Expand Down
Loading
Loading