Skip to content
Closed
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
Expand Up @@ -10,6 +10,16 @@
"labeled": true
}
},
"footerBar": {
"tabs": {
"core": [
"legend",
"layers",
"details",
"time-slider"
]
}
},
"theme": "geo.ca",
"components": ["north-arrow", "overview-map"],
"corePackages": [],
Expand Down
25 changes: 23 additions & 2 deletions packages/geoview-custom-legend/default-config-custom-legend.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
{
"legend": [
{
"symbolUrl": "/path/to/city-icon.png",
"legendTitle": "Cities",
"description": "Major metropolitan areas"
},
{
"symbolUrl": "/path/to/river-icon.png",
"legendTitle": "Rivers",
"description": "Major waterways"
},
{
"symbolUrl": "/path/to/mountain-icon.png",
"legendTitle": "Mountains",
"description": "High-altitude regions"
}
],
"id": "custom-legend",
"enabled": true,
"isOpen": false,
"legendList": [],
"footerBar": {
"tabs": {
"core": ["custom-legend"]
}
},
"isOpen": true,
"version": "1.0"
}
129 changes: 122 additions & 7 deletions packages/geoview-custom-legend/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
"type": "object",
"properties": {
"id": {
"type": "string"
"type": "string",
"enum": ["custom-legend"]
},
"enabled": {
"type": "boolean"
"type": "boolean",
"default": true
},
"isOpen": {
"type": "boolean"
"type": "boolean",
"default": false
},
"legendList": {
"type": "array",
Expand All @@ -25,15 +28,127 @@
"type": "string"
},
"visibility": {
"type": "boolean"
"type": "boolean",
"default": true
},
"infoSection": {
"oneOf": [
{
"type": "object",
"properties": {
"infoType": {
"type": "string",
"enum": ["title"]
},
"content": {
"type": "string"
},
"export": {
"type": "boolean",
"default": true
}
},
"required": ["infoType", "content"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"infoType": {
"type": "string",
"enum": ["image"]
},
"content": {
"type": "string"
},
"export": {
"type": "boolean",
"default": true
}
},
"required": ["infoType", "content"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"infoType": {
"type": "string",
"enum": ["unboundLayer"]
},
"content": {
"type": "string"
},
"layerName": {
"type": "string"
},
"coverIcon": {
"type": "string"
},
"description": {
"type": "string",
"default": ""
},
"symbologyStack": {
"type": "array",
"items": {
"type": "object",
"properties": {
"image": {
"type": "string"
},
"text": {
"type": "string"
}
},
"required": ["image", "text"],
"additionalProperties": false
},
"minItems": 1
},
"symbologyRenderStyle": {
"type": "string",
"enum": ["icons", "images"]
},
"symbologyExpanded": {
"type": "boolean",
"default": false
},
"export": {
"type": "boolean",
"default": true
}
},
"required": ["infoType", "content", "layerName", "symbologyStack", "symbologyRenderStyle"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"infoType": {
"type": "string",
"enum": ["text"]
},
"content": {
"type": "string"
},
"export": {
"type": "boolean",
"default": true
}
},
"required": ["infoType", "content"],
"additionalProperties": false
}
]
}
},
"required": ["legendTitle", "layerId"]
"required": ["legendTitle", "infoSection"]
}
},
"version": {
"type": "string"
}
},
"required": ["id", "legendList"]
}
"required": ["id", "legendList", "version"]
}
91 changes: 51 additions & 40 deletions packages/geoview-custom-legend/src/custom-legend.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,74 @@
/* eslint-disable react/no-array-index-key */
/* eslint-disable react/jsx-no-useless-fragment */
import { useMapStoreActions, useMapVisibleLayers } from 'geoview-core/src/core/stores/store-interface-and-intial-values/map-state';
import { Extent } from 'geoview-core/src/api/config/types/map-schema-types';
import { getSxClasses } from './custom-legend-style';
import { InfoSection } from './infosection';

interface CustomLegendPanelProps {
mapId: string;
config: TypeLegendProps;
config: {
legend: { symbolUrl: string; legendTitle: string; description: string | null }[];
};
}

interface LegendItem {
legendTitle: string;
symbolUrl: string;
description?: string;
}

type LegendListItems = LegendItem[];

type TypeLegendProps = {
isOpen: boolean;
legendList: LegendListItems;
version: string;
};

export function CustomLegendPanel(props: CustomLegendPanelProps): JSX.Element {
const { mapId, config } = props;
const legendList = config.legendList as LegendListItems;

const { cgpv } = window;
const { api, ui } = cgpv;

const myMap = api.maps[mapId];
const { Card, Box } = ui.elements;

const theme = ui.useTheme();
const sxClasses = getSxClasses(theme);

const { highlightBBox } = useMapStoreActions();
const visibleLayers = useMapVisibleLayers() as string[];

return (
<Box sx={sxClasses.legendCard}>
{legendList.map((legendItem: LegendItem, index) => {
return (
<Card
tabIndex={0}
className="legendCardItem"
// eslint-disable-next-line react/no-array-index-key
key={index}
title={legendItem.legendTitle}
contentCard={
// eslint-disable-next-line react/jsx-no-useless-fragment
<>
{typeof legendItem.symbolUrl === 'string' && (
<div className="legend-item-container">
{/* eslint-disable-next-line react/no-array-index-key */}
<Box component="img" key={index} src={legendItem.symbolUrl} alt="" className="legendSymbol" />
<div className="legend-text">
<span className="legend-title">{legendItem.legendTitle}</span>
{legendItem.description && <span className="legend-description">{legendItem.description}</span>}
</div>
</div>
{config.legend.map((item, index) => (
<Card
tabIndex={0}
className="legendCardItem"
key={index}
title={item.legendTitle}
contentCard={
<div className="legend-item-container">
<Box component="img" src={item.symbolUrl} alt="" className="legendSymbol" />
<div className="legend-text">
<InfoSection
infoType="legend"
section={{
title: item.legendTitle,
symbols: [],
content: null,
}}
/>
{item.description && (
<InfoSection
infoType="description"
section={{
title: '',
symbols: [],
content: item.description,
}}
/>
)}
</>
</div>
</div>
}
onClick={() => {
// Example usage of highlightBBox with visible layers
if (visibleLayers.includes(item.legendTitle)) {
const extent: Extent = myMap.getView().calculateExtent();
highlightBBox(extent);
}
/>
);
})}
}}
/>
))}
</Box>
);
}
5 changes: 3 additions & 2 deletions packages/geoview-custom-legend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class CustomLegendPanelPlugin extends AppBarPlugin {
}

override onCreateContentProps(): TypePanelProps {
// Panel props
// Panel props for the footerBar
return {
title: 'CustomLegend.title',
icon: <LegendIcon />,
Expand All @@ -68,7 +68,8 @@ class CustomLegendPanelPlugin extends AppBarPlugin {
}

override onCreateContent = (): JSX.Element => {
return <CustomLegendPanel mapId={this.pluginProps.mapId} config={this.configObj || {}} />;
// Pass the configuration to the CustomLegendPanel
return <CustomLegendPanel mapId={this.pluginProps.mapId} config={this.configObj} />;
};

/**
Expand Down
33 changes: 33 additions & 0 deletions packages/geoview-custom-legend/src/infosection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable react/no-unused-prop-types */
/* eslint-disable react/function-component-definition */
import { LegendSection, StyleOptions } from './types/legend';

interface InfoSectionProps {
infoType: 'legend' | 'title' | 'description';
section: LegendSection;
styleOptions?: StyleOptions;
}

export function InfoSection(props: InfoSectionProps): JSX.Element {
const { infoType, section } = props;

const { cgpv } = window;
const { react } = cgpv;
const { Fragment } = react;

return (
<Fragment>
{infoType === 'legend' && (
<div className="info-section">
<h3>{section.title}</h3>
{/* Render symbols if any */}
</div>
)}
{infoType === 'description' && (
<div className="info-section">
<p>{section.content}</p>
</div>
)}
</Fragment>
);
}
20 changes: 20 additions & 0 deletions packages/geoview-custom-legend/src/types/legend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export interface LegendSymbol {
image: string;
label: string;
description?: string;
}

export interface LegendSection {
title: string;
description?: string;
symbols: LegendSymbol[];
}

export interface StyleOptions {
symbolSize?: number;
spacing?: number;
layout?: 'vertical' | 'horizontal';
containerClass?: string;
symbolClass?: string;
labelClass?: string;
}
Loading