Skip to content

Commit

Permalink
fix(ESRI Dynamic): raster layers in ESRI Dynamic geocore layers now l…
Browse files Browse the repository at this point in the history
…oad (#2670)

Closes #2598
  • Loading branch information
DamonU2 authored Jan 6, 2025
1 parent 7c8c489 commit 58543d5
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,19 +268,22 @@ export function commonProcessFeatureInfoConfig(
const queryable = (layerMetadata.capabilities as string).includes('Query');
if (layerConfig.source.featureInfo) {
// if queryable flag is undefined, set it accordingly to what is specified in the metadata
if (layerConfig.source.featureInfo.queryable === undefined) layerConfig.source.featureInfo.queryable = queryable;
if (layerConfig.source.featureInfo.queryable === undefined && layerMetadata.fields?.length)
layerConfig.source.featureInfo.queryable = queryable;
// else the queryable flag comes from the user config.
else if (layerConfig.source.featureInfo.queryable && !layerMetadata.fields && layerMetadata.type !== 'Group Layer') {
else if (layerConfig.source.featureInfo.queryable && layerMetadata.type !== 'Group Layer') {
layerConfig.layerStatus = 'error';
throw new Error(
`The config whose layer path is ${layerPath} cannot set a layer as queryable because it does not have field definitions`
);
}
} else layerConfig.source.featureInfo = layerConfig.isMetadataLayerGroup ? { queryable: false } : { queryable };
} else
layerConfig.source.featureInfo =
layerConfig.isMetadataLayerGroup || !layerMetadata.fields?.length ? { queryable: false } : { queryable };
MapEventProcessor.setMapLayerQueryable(layer.mapId, layerPath, layerConfig.source.featureInfo.queryable);

// dynamic group layer doesn't have fields definition
if (layerMetadata.type !== 'Group Layer') {
if (layerMetadata.type !== 'Group Layer' && layerMetadata.fields) {
// Process undefined outfields or aliasFields
if (!layerConfig.source.featureInfo.outfields?.length) {
if (!layerConfig.source.featureInfo.outfields) layerConfig.source.featureInfo.outfields = [];
Expand Down Expand Up @@ -371,6 +374,7 @@ export async function commonProcessLayerMetadata<
if (queryUrl) {
if (layerConfig.geoviewLayerConfig.geoviewLayerType !== CONST_LAYER_TYPES.ESRI_IMAGE)
queryUrl = queryUrl.endsWith('/') ? `${queryUrl}${layerConfig.layerId}` : `${queryUrl}/${layerConfig.layerId}`;

try {
const { data } = await axios.get<TypeJsonObject>(`${queryUrl}?f=json`);
if (data?.error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,12 @@ export class EsriDynamic extends AbstractGeoViewRaster {
// Create the source
const source = new ImageArcGISRest(sourceOptions);

// Raster layer queries do not accept any layerDefs
if (this.metadata?.layers[0].type === 'Raster Layer') {
const params = source.getParams();
source.updateParams({ ...params, layerDefs: '' });
}

// GV Time to request an OpenLayers layer!
const requestResult = this.emitLayerRequesting({ config: layerConfig, source });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ import {
TypeFeatureInfoEntry,
rangeDomainType,
codedValueType,
TypeLayerStyleConfig,
TypeLayerStyleConfigInfo,
} from '@/geo/map/map-schema-types';
import { esriGetFieldType, esriGetFieldDomain } from '../utils';
import { AbstractGVRaster } from './abstract-gv-raster';
import { TypeOutfieldsType } from '@/api/config/types/map-schema-types';
import { TypeJsonObject } from '@/api/config/types/config-types';
import { getLegendStyles } from '@/geo/utils/renderer/geoview-renderer';
import { CONST_LAYER_TYPES } from '../../geoview-layers/abstract-geoview-layers';
import { TypeLegend } from '@/core/stores/store-interface-and-intial-values/layer-state';
import { TypeEsriImageLayerLegend } from './gv-esri-image';

type TypeFieldOfTheSameValue = { value: string | number | Date; nbOccurence: number };
type TypeQueryTree = { fieldValue: string | number | Date; nextField: TypeQueryTree }[];
Expand Down Expand Up @@ -656,6 +662,84 @@ export class GVEsriDynamic extends AbstractGVRaster {
}
}

/**
* Overrides the fetching of the legend for an Esri Dynamic layer.
* @returns {Promise<TypeLegend | null>} The legend of the layer or null.
*/
override async getLegend(): Promise<TypeLegend | null> {
const layerConfig = this.getLayerConfig();
// Only raster layers need the alternate code
if (layerConfig.getLayerMetadata()?.type !== 'Raster Layer') return super.getLegend();

try {
if (!layerConfig) return null;
const legendUrl = `${layerConfig.geoviewLayerConfig.metadataAccessPath}/legend?f=json`;
const response = await fetch(legendUrl);
const legendJson: TypeEsriImageLayerLegend = await response.json();

let legendInfo;
if (legendJson.layers && legendJson.layers.length === 1) {
legendInfo = legendJson.layers[0].legend;
} else if (legendJson.layers.length) {
const layerInfo = legendJson.layers.find((layer) => layer.layerId.toString() === layerConfig.layerId);
if (layerInfo) legendInfo = layerInfo.legend;
}

if (!legendInfo) {
const legend: TypeLegend = {
type: CONST_LAYER_TYPES.ESRI_IMAGE,
styleConfig: this.getStyle(layerConfig.layerPath),
legend: null,
};

return legend;
}

const uniqueValueStyleInfo: TypeLayerStyleConfigInfo[] = [];
legendInfo.forEach((info) => {
const styleInfo: TypeLayerStyleConfigInfo = {
label: info.label,
visible: layerConfig.initialSettings.states?.visible || true,
values: info.label.split(','),
settings: {
type: 'iconSymbol',
mimeType: info.contentType,
src: info.imageData,
width: info.width,
height: info.height,
},
};
uniqueValueStyleInfo.push(styleInfo);
});

const styleSettings: TypeLayerStyleSettings = {
type: 'uniqueValue',
fields: ['default'],
hasDefault: false,
info: uniqueValueStyleInfo,
};

const styleConfig: TypeLayerStyleConfig = {
Point: styleSettings,
};

// TODO: Refactor - Find a better place to set the style than in a getter or rename this function like another TODO suggests
// Set the style
this.setStyle(layerConfig.layerPath, styleConfig);

const legend: TypeLegend = {
type: CONST_LAYER_TYPES.ESRI_IMAGE,
styleConfig,
legend: await getLegendStyles(this.getStyle(layerConfig.layerPath)),
};

return legend;
} catch (error) {
logger.logError(`Get Legend for ${layerConfig.layerPath} error`, error);
return null;
}
}

/**
* Overrides when the layer gets in loaded status.
*/
Expand Down Expand Up @@ -714,7 +798,9 @@ export class GVEsriDynamic extends AbstractGVRaster {
)}`;
});

olLayer?.getSource()!.updateParams({ layerDefs: `{"${layerConfig.layerId}": "${filterValueToUse}"}` });
// Raster layer queries do not accept any layerDefs
const layerDefs = layerConfig.getLayerMetadata()?.type === 'Raster Layer' ? '' : `{"${layerConfig.layerId}": "${filterValueToUse}"}`;
olLayer?.getSource()!.updateParams({ layerDefs });
olLayer?.changed();

// Emit event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ export class GVEsriImage extends AbstractGVRaster {
}
}

interface TypeEsriImageLayerLegend {
// Exported for use in ESRI Dynamic raster layers
export interface TypeEsriImageLayerLegend {
layers: {
layerId: number | string;
layerName: string;
Expand Down
17 changes: 17 additions & 0 deletions packages/geoview-core/src/geo/utils/projection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export abstract class Projection {
CRS84: 'CRS:84', // Supporting CRS:84 which is equivalent to 4326 except it's long-lat, whereas the 4326 standard is lat-long.
CSRS: 'EPSG:4617',
CSRS98: 'EPSG:4140',
3400: 'EPSG:3400',
};

// Incremental number when creating custom WKTs on the fly
Expand Down Expand Up @@ -473,6 +474,21 @@ function init102190Projection(): void {
if (projection) Projection.PROJECTIONS['102190'] = projection;
}

/**
* Initializes the EPSG:3400 projection
*/
function init3400Projection(): void {
proj4.defs(
Projection.PROJECTION_NAMES[3400],
'+proj=tmerc +lat_0=0 +lon_0=-115 +k=0.9992 +x_0=500000 +y_0=0 +datum=NAD83 +units=m +no_defs +type=crs'
);
register(proj4);

const projection = olGetProjection(Projection.PROJECTION_NAMES[3400]);

if (projection) Projection.PROJECTIONS['3400'] = projection;
}

// Initialize the supported projections
initCRS84Projection();
init4326Projection();
Expand All @@ -486,4 +502,5 @@ init4269Projection();
init102100Projection();
init102184Projection();
init102190Projection();
init3400Projection();
logger.logInfo('Projections initialized');
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,6 @@ async function getPointStyleSubRoutine(
export async function getLegendStyles(styleConfig: TypeLayerStyleConfig | undefined): Promise<TypeVectorLayerStyles> {
try {
if (!styleConfig) return {};

const legendStyles: TypeVectorLayerStyles = {};
if (styleConfig.Point) {
// ======================================================================================================================
Expand Down

0 comments on commit 58543d5

Please sign in to comment.