Skip to content

Commit

Permalink
feat: create unified jsonlegend util and sync with print-legend
Browse files Browse the repository at this point in the history
  • Loading branch information
Grammostola committed Feb 22, 2024
1 parent 8e9f2ba commit d7078db
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 15 deletions.
48 changes: 33 additions & 15 deletions src/controls/print/print-legend.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ImageArcGISRest, ImageWMS } from 'ol/source';
import { Component } from '../../ui';
import { isHidden, renderSvgIcon } from '../../utils/legendmaker';
import ImageLayerLegendRules from '../../utils/jsonlegends';

/**
* More information: https://developers.arcgis.com/rest/services-reference/enterprise/legend-map-service-.htm
Expand Down Expand Up @@ -56,7 +57,7 @@ const LayerRow = function LayerRow(options) {
* @param {"image/png"|"application/json"} format
* @returns {string|null}
*/
const getWMSLegendUrl = (aLayer, format) => {
/* const getWMSLegendUrl = (aLayer, format) => {
const url = getOneUrl(aLayer);
const layerName = aLayer.get('name');
const style = viewer.getStyle(aLayer.get('styleName'));
Expand All @@ -67,7 +68,7 @@ const LayerRow = function LayerRow(options) {
return `${style[0][0].icon.src}?format=${format}`;
}
return `${url}?SERVICE=WMS&layer=${layerName}&format=${format}&version=1.1.1&request=getLegendGraphic&scale=401&legend_options=dpi:300`;
};
}; */

/**
* Returns the JSON-encoded legend from the ArcGIS Legend Map Service
Expand All @@ -78,7 +79,7 @@ const LayerRow = function LayerRow(options) {
* @param {number} dpi
* @returns {Promise<ArcGISLegendResponse>}
*/
const getAGSLegendJSON = async (aLayer, dpi = 150) => {
/* const getAGSLegendJSON = async (aLayer, dpi = 150) => {
// rewrite the URL if needed
const mapServerUrl = getOneUrl(aLayer).replace(/\/arcgis(\/rest)?\/services\/([^/]+\/[^/]+)\/MapServer\/WMSServer/, '/arcgis/rest/services/$2/MapServer');
const url = `${mapServerUrl}/legend?f=json&dpi=${dpi}`;
Expand All @@ -89,13 +90,13 @@ const LayerRow = function LayerRow(options) {
console.warn(e);
return null;
}
};
}; */

/**
* @param {string|null} url
* @returns {Promise<null|any>}
*/
const getLegendGraphicJSON = async (url) => {
/* const getLegendGraphicJSON = async (url) => {
try {
if (!url) {
return null;
Expand All @@ -106,7 +107,7 @@ const LayerRow = function LayerRow(options) {
console.warn(e);
return null;
}
};
}; */

/**
* @param {string} title
Expand Down Expand Up @@ -188,10 +189,18 @@ const LayerRow = function LayerRow(options) {
* @returns {Promise<string>}
*/
const getWMSJSONContent = async (title) => {
const getLegendGraphicUrl = getWMSLegendUrl(layer, 'image/png');
const json = await getLegendGraphicJSON(getWMSLegendUrl(layer, 'application/json'));
// onst getLegendGraphicUrl = getWMSLegendUrl(layer, 'image/png');
const maxResolution = viewer.getResolutions()[viewer.getResolutions().length - 1];
const getLegendGraphicUrl = layer.getSource().getLegendUrl(maxResolution, {
legend_options: 'dpi:300'
});
// const json = await getLegendGraphicJSON(getWMSLegendUrl(layer, 'application/json'));
const rules = await ImageLayerLegendRules({
layer,
viewer
});

if (!json) {
if (!rules) {
return `
<div class="flex row">
<div class="padding-x-small grow no-select overflow-hidden">${title}</div>
Expand All @@ -200,17 +209,17 @@ const LayerRow = function LayerRow(options) {
<img src="${getLegendGraphicUrl}" alt="${title}" />
</div>`;
}
if (json.Legend[0].rules.length <= 1) {
if (rules.length <= 1) {
const icon = `<img class="cover" src="${getLegendGraphicUrl}" alt="${title}"/>`;
return getTitleWithIcon(title, icon);
}

const rules = json.Legend[0].rules.map((rule, index) => {
const listItems = rules.map((rule, index) => {
const ruleImageUrl = `${getLegendGraphicUrl}&rule=${rule.name}`;
const rowTitle = rule.title ? rule.title : index + 1;
return getListItem(rowTitle, ruleImageUrl, true);
});
return getTitleWithChildren(title, rules);
return getTitleWithChildren(title, listItems);
};

/**
Expand All @@ -221,11 +230,20 @@ const LayerRow = function LayerRow(options) {
* @returns {Promise<string>}
*/
const getAGSJSONContent = async (title, id) => {
const json = await getAGSLegendJSON(layer);
if (!json) {
// const json = await getAGSLegendJSON(layer);
// const layersDetails = json.layers;
const layersDetails = await ImageLayerLegendRules({
layer,
viewer,
legendOpts: {
dpi: 200
}
});

if (layersDetails.length === 0) {
return getTitleWithIcon(title, '');
}
const legendLayer = json.layers.find((l) => +l.layerId === +id || l.layerName === id);
const legendLayer = layersDetails.find((l) => +l.layerId === +id || l.layerName === id);
if (!legendLayer) {
return getTitleWithIcon(title, '');
}
Expand Down
55 changes: 55 additions & 0 deletions src/utils/jsonlegends.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { ImageArcGISRest, ImageWMS } from 'ol/source';

function getOneUrl(aLayer) {
const source = aLayer.getSource();
if ((source instanceof ImageWMS || source instanceof ImageArcGISRest) && typeof source.getUrl === 'function') {
return source.getUrl();
} else if (typeof source.getUrls === 'function') {
return source.getUrls()[0];
}
return null;
}

async function fetchJsonLegend({
url,
serverVendor
}) {
const reply = await fetch(url);
const json = await reply.json();
if (serverVendor === 'arcgis') return json?.layers;
else if (serverVendor === 'geoserver') return json.Legend[0]?.rules;
return [];
}
async function getJsonLegendDetails({ layer, viewer, legendOpts }) {
const mapSource = viewer.getMapSource();
const sourceName = layer.get('sourceName');
let serverVendor = mapSource[sourceName].type?.toLowerCase();
if (!serverVendor) serverVendor = 'geoserver'; // make similar assumption as before
let url;

if (serverVendor === 'arcgis') {
let mapServerUrlString = getOneUrl(layer);
if (layer.get('type') === 'WMS') {
const urlParts = mapServerUrlString.split('services');
mapServerUrlString = `${urlParts[0]}rest/services${urlParts[1].split('/WMSServer')[0]}`;
}
mapServerUrlString += '/legend';
url = new URL(mapServerUrlString);
url.searchParams.append('f', 'json');
url.searchParams.append('dpi', legendOpts?.dpi || 150);
} else if (serverVendor === 'geoserver') {
const maxResolution = viewer.getResolutions()[viewer.getResolutions().length - 1];
url = layer.getSource().getLegendUrl(maxResolution, {
FORMAT: 'application/json',
...legendOpts
});
}
if (url) {
return fetchJsonLegend({
url,
serverVendor
});
} return [];
}

export default getJsonLegendDetails;

0 comments on commit d7078db

Please sign in to comment.