@camptocamp/ogc-client
Advanced tools
Comparing version 1.1.1-dev.77cdfe1 to 1.1.1-dev.7cb62b7
@@ -7,2 +7,3 @@ import { | ||
parseBaseCollectionInfo, | ||
parseFullStyleInfo, | ||
parseCollectionParameters, | ||
@@ -12,2 +13,3 @@ parseCollections, | ||
parseEndpointInfo, | ||
parseBasicStyleInfo, | ||
parseTileMatrixSets | ||
@@ -45,2 +47,3 @@ } from "./info.js"; | ||
tileMatrixSetsFull_; | ||
styles_; | ||
get root() { | ||
@@ -104,2 +107,16 @@ if (!this.root_) { | ||
} | ||
get styles() { | ||
if (!this.styles_) { | ||
this.styles_ = this.root.then(async (root) => { | ||
if (!await this.hasStyles) | ||
return void 0; | ||
return fetchLink( | ||
root, | ||
["styles", "http://www.opengis.net/def/rel/ogc/1.0/styles"], | ||
this.baseUrl | ||
); | ||
}); | ||
} | ||
return this.styles_; | ||
} | ||
/** | ||
@@ -201,2 +218,28 @@ * A Promise which resolves to the endpoint information. | ||
} | ||
async getStyleMetadataDocument(styleId, collectionId) { | ||
const doc = collectionId ? await this.getCollectionDocument(collectionId) : await this.root; | ||
const stylesLinkJson = getLinkUrl( | ||
doc, | ||
["styles", "http://www.opengis.net/def/rel/ogc/1.0/styles"], | ||
this.baseUrl, | ||
"application/json" | ||
); | ||
const stylesLink = getLinkUrl( | ||
doc, | ||
["styles", "http://www.opengis.net/def/rel/ogc/1.0/styles"], | ||
this.baseUrl | ||
); | ||
const styleData = await fetchDocument( | ||
stylesLinkJson ?? stylesLink | ||
); | ||
if (!styleData.styles.some((style) => style.id === styleId)) { | ||
throw new EndpointError(`Style not found: "${styleId}".`); | ||
} | ||
const styleDoc = styleData?.styles?.find((style) => style.id === styleId); | ||
if (hasLinks(styleDoc, ["describedby"])) { | ||
return fetchLink(styleDoc, "describedby", this.baseUrl); | ||
} else { | ||
return styleDoc; | ||
} | ||
} | ||
/** | ||
@@ -440,2 +483,67 @@ * Returns a promise resolving to a document describing the specified collection. | ||
} | ||
/** | ||
* A Promise which resolves to an array of all style items. This includes the supported style formats. | ||
* @param collectionId - Optional unique identifier for the collection. | ||
*/ | ||
async allStyles(collectionId) { | ||
const doc = collectionId ? await this.getCollectionDocument(collectionId) : await this.root; | ||
const stylesLink = getLinkUrl( | ||
doc, | ||
["styles", "http://www.opengis.net/def/rel/ogc/1.0/styles"], | ||
this.baseUrl | ||
); | ||
if (!stylesLink) { | ||
throw new EndpointError( | ||
'Could not get styles: there is no relation of type "styles"' | ||
); | ||
} | ||
const styleData = await fetchDocument(stylesLink); | ||
return styleData.styles.map(parseBasicStyleInfo); | ||
} | ||
/** | ||
* Returns a promise resolving to a document describing the style. Looks for a relation of type | ||
* "describedby" to fetch metadata. If no relation is found, only basic info will be returned. | ||
* @param styleId - The style identifier | ||
* @param collectionId - Optional unique identifier for the collection. | ||
*/ | ||
async getStyle(styleId, collectionId) { | ||
const metadataDoc = await this.getStyleMetadataDocument( | ||
styleId, | ||
collectionId | ||
); | ||
if (!metadataDoc?.stylesheets) { | ||
return parseBasicStyleInfo(metadataDoc); | ||
} | ||
return parseFullStyleInfo(metadataDoc); | ||
} | ||
/** | ||
* Returns a promise resolving to a stylesheet URL for a given style and type. | ||
* @param styleId - The style identifier | ||
* @param mimeType - Stylesheet MIME type | ||
* @param collectionId - Optional unique identifier for the collection. | ||
*/ | ||
async getStylesheetUrl(styleId, mimeType, collectionId) { | ||
const stylesDoc = await this.getStyleMetadataDocument( | ||
styleId, | ||
collectionId | ||
); | ||
if (stylesDoc.stylesheets) { | ||
const urlFromMetadata = stylesDoc?.stylesheets?.find( | ||
(s) => s.link.type === mimeType && s.link.rel === "stylesheet" | ||
)?.link?.href; | ||
return urlFromMetadata; | ||
} | ||
const urlFromStyle = getLinkUrl( | ||
stylesDoc, | ||
"stylesheet", | ||
this.baseUrl, | ||
mimeType | ||
); | ||
if (!urlFromStyle) { | ||
throw new EndpointError( | ||
"Could not find stylesheet URL for given style ID and type." | ||
); | ||
} | ||
return urlFromStyle; | ||
} | ||
} | ||
@@ -442,0 +550,0 @@ export { |
@@ -68,2 +68,4 @@ import { | ||
"http://www.opengis.net/spec/ogcapi-styles-1/0.0/conf/core" | ||
) > -1 || conformance.indexOf( | ||
"http://www.opengis.net/spec/ogcapi-styles-1/1.0/conf/core" | ||
) > -1; | ||
@@ -147,2 +149,22 @@ } | ||
} | ||
function parseBasicStyleInfo(doc) { | ||
const formats = doc.links.filter((link) => link.rel === "stylesheet").map((link) => link.type).filter((type) => type !== "text/html"); | ||
return { | ||
formats, | ||
id: doc.id, | ||
...doc.title && { title: doc.title } | ||
}; | ||
} | ||
function parseStylesAsList() { | ||
return (doc) => doc?.styles?.map((style) => style.id); | ||
} | ||
function parseFullStyleInfo(doc) { | ||
const { stylesheets, links, ...props } = doc; | ||
const stylesheetFormats = stylesheets?.filter((stylesheet) => stylesheet.link.rel === "stylesheet")?.map((stylesheet) => stylesheet.link.type); | ||
return { | ||
...stylesheetFormats && { stylesheetFormats }, | ||
...stylesheets && { stylesheets }, | ||
...props | ||
}; | ||
} | ||
export { | ||
@@ -154,2 +176,3 @@ checkHasFeatures, | ||
parseBaseCollectionInfo, | ||
parseBasicStyleInfo, | ||
parseCollectionParameters, | ||
@@ -159,4 +182,6 @@ parseCollections, | ||
parseEndpointInfo, | ||
parseFullStyleInfo, | ||
parseStylesAsList, | ||
parseTileMatrixSets | ||
}; | ||
//# sourceMappingURL=info.js.map |
@@ -54,9 +54,13 @@ import { EndpointError } from "../shared/errors.js"; | ||
} | ||
function getLinks(doc, relType) { | ||
return doc.links?.filter( | ||
function getLinks(doc, relType, mimeType) { | ||
const links = doc.links?.filter( | ||
(link) => Array.isArray(relType) ? relType.indexOf(link.rel) > -1 : link.rel === relType | ||
) || []; | ||
if (mimeType) { | ||
return links.filter((link) => link.type === mimeType); | ||
} | ||
return links; | ||
} | ||
function getLinkUrl(doc, relType, baseUrl) { | ||
const link = getLinks(doc, relType)[0]; | ||
function getLinkUrl(doc, relType, baseUrl, mimeType) { | ||
const link = getLinks(doc, relType, mimeType)[0]; | ||
if (!link) | ||
@@ -63,0 +67,0 @@ return null; |
@@ -96,2 +96,6 @@ import { | ||
).map(getElementText); | ||
const keywords = serviceVersion.startsWith("1.0") ? getElementText(findChildElement(featureTypeEl, "Keywords")).split(",").map((keyword) => keyword.trim()) : findChildrenElement( | ||
findChildElement(featureTypeEl, "Keywords"), | ||
"Keyword" | ||
).map(getElementText).filter((v, i, arr) => arr.indexOf(v) === i); | ||
return { | ||
@@ -106,3 +110,4 @@ name: getElementText(findChildElement(featureTypeEl, "Name")), | ||
outputFormats: outputFormats.length > 0 ? outputFormats : defaultOutputFormats, | ||
latLonBoundingBox: serviceVersion.startsWith("1.0") ? parseBBox100() : parseBBox() | ||
latLonBoundingBox: serviceVersion.startsWith("1.0") ? parseBBox100() : parseBBox(), | ||
keywords | ||
}; | ||
@@ -109,0 +114,0 @@ } |
@@ -96,3 +96,4 @@ import { | ||
otherCrs: featureType.otherCrs, | ||
outputFormats: featureType.outputFormats | ||
outputFormats: featureType.outputFormats, | ||
keywords: featureType.keywords | ||
}; | ||
@@ -99,0 +100,0 @@ } |
@@ -14,3 +14,4 @@ import { | ||
outputFormats, | ||
latLonBoundingBox: boundingBox | ||
latLonBoundingBox: boundingBox, | ||
keywords | ||
} = featureType; | ||
@@ -52,3 +53,4 @@ const hitsAttr = serviceVersion.startsWith("2.0") ? "numberMatched" : "numberOfFeatures"; | ||
...geometryType && { geometryType }, | ||
...!Number.isNaN(objectCount) && { objectCount } | ||
...!Number.isNaN(objectCount) && { objectCount }, | ||
...keywords && { keywords } | ||
}; | ||
@@ -55,0 +57,0 @@ } |
@@ -22,4 +22,19 @@ import { | ||
} | ||
function readOutputFormatsFromCapabilities(capabilitiesDoc) { | ||
const capability = findChildElement( | ||
getRootElement(capabilitiesDoc), | ||
"Capability" | ||
); | ||
const getMap = findChildElement( | ||
findChildElement(capability, "Request"), | ||
"GetMap" | ||
); | ||
const outputFormats = findChildrenElement(getMap, "Format").map( | ||
getElementText | ||
); | ||
return outputFormats; | ||
} | ||
function readInfoFromCapabilities(capabilitiesDoc) { | ||
const service = findChildElement(getRootElement(capabilitiesDoc), "Service"); | ||
const formats = readOutputFormatsFromCapabilities(capabilitiesDoc); | ||
const keywords = findChildrenElement( | ||
@@ -33,2 +48,3 @@ findChildElement(service, "KeywordList"), | ||
abstract: getElementText(findChildElement(service, "Abstract")), | ||
outputFormats: formats, | ||
fees: getElementText(findChildElement(service, "Fees")), | ||
@@ -80,2 +96,8 @@ constraints: getElementText(findChildElement(service, "AccessConstraints")), | ||
boundingBoxes = Object.keys(boundingBoxes).length > 0 || inheritedBoundingBoxes === null ? boundingBoxes : inheritedBoundingBoxes; | ||
const queryable = layerEl.attributes.queryable === "1" || layerEl.attributes.queryable === "true" ? true : false; | ||
const opaque = layerEl.attributes.opaque === "1" || layerEl.attributes.opaque === "true" ? true : false; | ||
const keywords = findChildrenElement( | ||
findChildElement(layerEl, "KeywordList"), | ||
"Keyword" | ||
).map(getElementText).filter((v, i, arr) => arr.indexOf(v) === i); | ||
const children = findChildrenElement(layerEl, "Layer").map( | ||
@@ -92,2 +114,5 @@ (layer) => parseLayer(layer, version, availableCrs, styles, attribution, boundingBoxes) | ||
boundingBoxes, | ||
keywords, | ||
queryable, | ||
opaque, | ||
...children.length && { children } | ||
@@ -101,5 +126,7 @@ }; | ||
); | ||
const abstract = getElementText(findChildElement(styleEl, "Abstract")); | ||
return { | ||
name: getElementText(findChildElement(styleEl, "Name")), | ||
title: getElementText(findChildElement(styleEl, "Title")), | ||
...abstract && { abstract }, | ||
...legendUrl && { legendUrl } | ||
@@ -130,4 +157,5 @@ }; | ||
readLayersFromCapabilities, | ||
readOutputFormatsFromCapabilities, | ||
readVersionFromCapabilities | ||
}; | ||
//# sourceMappingURL=capabilities.js.map |
@@ -143,5 +143,7 @@ import { | ||
); | ||
const abstract = getElementText(findChildElement(element2, "Abstract")); | ||
const style = { | ||
title: getElementText(findChildElement(element2, "Title")), | ||
name: getElementText(findChildElement(element2, "Identifier")), | ||
...abstract && { abstract }, | ||
...legendUrl && { legendUrl } | ||
@@ -148,0 +150,0 @@ }; |
{ | ||
"name": "@camptocamp/ogc-client", | ||
"version": "1.1.1-dev.77cdfe1", | ||
"version": "1.1.1-dev.7cb62b7", | ||
"description": "A pure JS library for interacting with geospatial services.", | ||
@@ -16,3 +16,4 @@ "main": "./dist/dist-node.js", | ||
"dependencies": { | ||
"@rgrove/parse-xml": "^4.1.0" | ||
"@rgrove/parse-xml": "^4.1.0", | ||
"node-fetch": "^3.3.1" | ||
}, | ||
@@ -35,3 +36,2 @@ "devDependencies": { | ||
"mitt": "^3.0.0", | ||
"node-fetch": "^3.3.1", | ||
"ol": "^8.2.0", | ||
@@ -65,3 +65,3 @@ "prettier": "2.8.8", | ||
"lint:fix": "npm run lint -- --fix", | ||
"build": "npm run build:worker && npm run build:node && npm run build:browser", | ||
"build": "rm -rf dist && npm run build:worker && npm run build:node && npm run build:browser", | ||
"build:browser": "esbuild $(find ./src -name \"*.ts\" -type f -not -path '*worker/index.ts' -not -path '*.spec.ts') --outdir=./dist --platform=neutral --format=esm --sourcemap", | ||
@@ -68,0 +68,0 @@ "build:node": "vite build --config vite.node-config.js", |
@@ -7,2 +7,3 @@ import { | ||
parseBaseCollectionInfo, | ||
parseFullStyleInfo, | ||
parseCollectionParameters, | ||
@@ -12,2 +13,3 @@ parseCollections, | ||
parseEndpointInfo, | ||
parseBasicStyleInfo, | ||
parseTileMatrixSets, | ||
@@ -21,2 +23,6 @@ } from './info.js'; | ||
OgcApiEndpointInfo, | ||
OgcApiStyleMetadata, | ||
OgcApiStylesDocument, | ||
OgcStyleBrief, | ||
OgcStyleFull, | ||
TileMatrixSet, | ||
@@ -51,2 +57,3 @@ } from './model.js'; | ||
private tileMatrixSetsFull_: Promise<TileMatrixSet[]>; | ||
private styles_: Promise<OgcApiStylesDocument>; | ||
@@ -114,2 +121,16 @@ private get root(): Promise<OgcApiDocument> { | ||
private get styles(): Promise<OgcApiStylesDocument> { | ||
if (!this.styles_) { | ||
this.styles_ = this.root.then(async (root) => { | ||
if (!(await this.hasStyles)) return undefined; | ||
return fetchLink( | ||
root, | ||
['styles', 'http://www.opengis.net/def/rel/ogc/1.0/styles'], | ||
this.baseUrl | ||
) as unknown as OgcApiStylesDocument; | ||
}); | ||
} | ||
return this.styles_; | ||
} | ||
/** | ||
@@ -257,2 +278,36 @@ * Creates a new OGC API endpoint. | ||
private async getStyleMetadataDocument( | ||
styleId: string, | ||
collectionId?: string | ||
): Promise<OgcApiDocument> { | ||
const doc = collectionId | ||
? await this.getCollectionDocument(collectionId) | ||
: await this.root; | ||
const stylesLinkJson = getLinkUrl( | ||
doc as OgcApiDocument, | ||
['styles', 'http://www.opengis.net/def/rel/ogc/1.0/styles'], | ||
this.baseUrl, | ||
'application/json' | ||
); | ||
const stylesLink = getLinkUrl( | ||
doc as OgcApiDocument, | ||
['styles', 'http://www.opengis.net/def/rel/ogc/1.0/styles'], | ||
this.baseUrl | ||
); | ||
const styleData = (await fetchDocument( | ||
stylesLinkJson ?? stylesLink | ||
)) as OgcApiStylesDocument; | ||
if (!styleData.styles.some((style) => style.id === styleId)) { | ||
throw new EndpointError(`Style not found: "${styleId}".`); | ||
} | ||
const styleDoc = styleData?.styles?.find((style) => style.id === styleId); | ||
if (hasLinks(styleDoc as OgcApiDocument, ['describedby'])) { | ||
return fetchLink(styleDoc as OgcApiDocument, 'describedby', this.baseUrl); | ||
} else { | ||
// fallback: return style document | ||
return styleDoc as OgcApiDocument; | ||
} | ||
} | ||
/** | ||
@@ -569,2 +624,84 @@ * Returns a promise resolving to a document describing the specified collection. | ||
} | ||
/** | ||
* A Promise which resolves to an array of all style items. This includes the supported style formats. | ||
* @param collectionId - Optional unique identifier for the collection. | ||
*/ | ||
async allStyles(collectionId?: string): Promise<OgcStyleBrief[]> { | ||
const doc = collectionId | ||
? await this.getCollectionDocument(collectionId) | ||
: await this.root; | ||
const stylesLink = getLinkUrl( | ||
doc as OgcApiDocument, | ||
['styles', 'http://www.opengis.net/def/rel/ogc/1.0/styles'], | ||
this.baseUrl | ||
); | ||
if (!stylesLink) { | ||
throw new EndpointError( | ||
'Could not get styles: there is no relation of type "styles"' | ||
); | ||
} | ||
const styleData = (await fetchDocument(stylesLink)) as OgcApiStylesDocument; | ||
return styleData.styles.map(parseBasicStyleInfo); | ||
} | ||
/** | ||
* Returns a promise resolving to a document describing the style. Looks for a relation of type | ||
* "describedby" to fetch metadata. If no relation is found, only basic info will be returned. | ||
* @param styleId - The style identifier | ||
* @param collectionId - Optional unique identifier for the collection. | ||
*/ | ||
async getStyle( | ||
styleId: string, | ||
collectionId?: string | ||
): Promise<OgcStyleFull | OgcStyleBrief> { | ||
const metadataDoc = await this.getStyleMetadataDocument( | ||
styleId, | ||
collectionId | ||
); | ||
if (!metadataDoc?.stylesheets) { | ||
return parseBasicStyleInfo(metadataDoc as OgcApiStyleMetadata); | ||
} | ||
return parseFullStyleInfo(metadataDoc as OgcApiStyleMetadata); | ||
} | ||
/** | ||
* Returns a promise resolving to a stylesheet URL for a given style and type. | ||
* @param styleId - The style identifier | ||
* @param mimeType - Stylesheet MIME type | ||
* @param collectionId - Optional unique identifier for the collection. | ||
*/ | ||
async getStylesheetUrl( | ||
styleId: string, | ||
mimeType: string, | ||
collectionId?: string | ||
): Promise<string> { | ||
const stylesDoc = await this.getStyleMetadataDocument( | ||
styleId, | ||
collectionId | ||
); | ||
if (stylesDoc.stylesheets) { | ||
const urlFromMetadata = ( | ||
stylesDoc as OgcApiStyleMetadata | ||
)?.stylesheets?.find( | ||
(s) => s.link.type === mimeType && s.link.rel === 'stylesheet' | ||
)?.link?.href; | ||
return urlFromMetadata; | ||
} | ||
const urlFromStyle = getLinkUrl( | ||
stylesDoc, | ||
'stylesheet', | ||
this.baseUrl, | ||
mimeType | ||
); | ||
if (!urlFromStyle) { | ||
throw new EndpointError( | ||
'Could not find stylesheet URL for given style ID and type.' | ||
); | ||
} | ||
return urlFromStyle; | ||
} | ||
} |
@@ -9,2 +9,6 @@ import { | ||
OgcApiEndpointInfo, | ||
OgcApiStyleMetadata, | ||
OgcApiStylesDocument, | ||
OgcStyleBrief, | ||
OgcStyleFull, | ||
TileMatrixSet, | ||
@@ -109,2 +113,5 @@ } from './model.js'; | ||
'http://www.opengis.net/spec/ogcapi-styles-1/0.0/conf/core' | ||
) > -1 || | ||
conformance.indexOf( | ||
'http://www.opengis.net/spec/ogcapi-styles-1/1.0/conf/core' | ||
) > -1 | ||
@@ -222,1 +229,31 @@ ); | ||
} | ||
export function parseBasicStyleInfo(doc: OgcApiStyleMetadata): OgcStyleBrief { | ||
const formats = doc.links | ||
.filter((link) => link.rel === 'stylesheet') | ||
.map((link) => link.type) | ||
.filter((type) => type !== 'text/html'); | ||
return { | ||
formats, | ||
id: doc.id, | ||
...(doc.title && { title: doc.title }), | ||
}; | ||
} | ||
export function parseStylesAsList(): (doc: OgcApiStylesDocument) => string[] { | ||
return (doc: OgcApiStylesDocument) => | ||
doc?.styles?.map((style) => style.id as string); | ||
} | ||
export function parseFullStyleInfo(doc: OgcApiStyleMetadata): OgcStyleFull { | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const { stylesheets, links, ...props } = doc; | ||
const stylesheetFormats = stylesheets | ||
?.filter((stylesheet) => stylesheet.link.rel === 'stylesheet') | ||
?.map((stylesheet) => stylesheet.link.type); | ||
return { | ||
...(stylesheetFormats && { stylesheetFormats }), | ||
...(stylesheets && { stylesheets }), | ||
...props, | ||
} as OgcStyleFull; | ||
} |
@@ -80,5 +80,6 @@ import { OgcApiDocument, OgcApiDocumentLink } from './model.js'; | ||
doc: OgcApiDocument, | ||
relType: string | string[] | ||
relType: string | string[], | ||
mimeType?: string | ||
): OgcApiDocumentLink[] { | ||
return ( | ||
const links = | ||
doc.links?.filter((link) => | ||
@@ -88,4 +89,7 @@ Array.isArray(relType) | ||
: link.rel === relType | ||
) || [] | ||
); | ||
) || []; | ||
if (mimeType) { | ||
return links.filter((link) => link.type === mimeType); | ||
} | ||
return links; | ||
} | ||
@@ -96,5 +100,6 @@ | ||
relType: string | string[], | ||
baseUrl?: string | ||
baseUrl?: string, | ||
mimeType?: string | ||
): string | null { | ||
const link = getLinks(doc, relType)[0]; | ||
const link = getLinks(doc, relType, mimeType)[0]; | ||
if (!link) return null; | ||
@@ -101,0 +106,0 @@ return new URL(link.href, baseUrl || window.location.toString()).toString(); |
@@ -176,1 +176,59 @@ import { Geometry } from 'geojson'; | ||
} | ||
export type StyleItem = { | ||
title: string; | ||
id: string; | ||
links?: OgcApiDocumentLink[]; | ||
formats?: string[]; | ||
}; | ||
export type OgcStyleFull = { | ||
stylesheetFormats: string[]; | ||
} & OgcApiStyleMetadata; | ||
export type OgcStyleBrief = { | ||
id: string; | ||
title?: string; | ||
formats?: string[]; | ||
}; | ||
export type OgcApiStylesDocument = { | ||
styles: StyleItem[]; | ||
links: OgcApiDocumentLink[]; | ||
}; | ||
export type OgcApiStyleRecord = { | ||
title: string; | ||
id: string; | ||
}; | ||
export type OgcApiStylesheet = { | ||
link: OgcApiDocumentLink; | ||
title?: string; | ||
version?: string; | ||
specification?: string; | ||
native?: boolean; | ||
}; | ||
export type OgcApiStyleMetadata = { | ||
id: string; | ||
title?: string; | ||
description?: string; | ||
keywords?: string[]; | ||
pointOfContact?: string; | ||
license?: string; | ||
created?: string; | ||
updated?: string; | ||
scope?: 'style'; | ||
version?: string; | ||
stylesheets?: OgcApiStylesheet[]; | ||
layers?: { | ||
id: string; | ||
description?: string; | ||
dataType?: 'vector' | 'map' | 'coverage' | 'model'; | ||
geometryType?: 'points' | 'lines' | 'polygons' | 'solids' | 'any'; | ||
propertiesSchema?: any; // https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/schemas/v3.0/schema.json#/definitions/Schema | ||
sampleData?: OgcApiDocumentLink; | ||
}[]; | ||
links?: OgcApiDocumentLink[]; | ||
}; |
@@ -15,2 +15,6 @@ /** | ||
keywords: string[]; | ||
/** | ||
* Can contain the list of outputFormats from a WFS GetCapabilities, | ||
* or the list of 'Formats' from a WMS GetCapabilities | ||
*/ | ||
outputFormats?: MimeType[]; | ||
@@ -33,2 +37,3 @@ }; | ||
title: string; | ||
abstract?: string; | ||
/** | ||
@@ -35,0 +40,0 @@ * May not be defined; a GetLegendGraphic operation should work in any case |
@@ -38,2 +38,3 @@ import { parseXmlString } from '../shared/xml-utils.js'; | ||
defaultCrs: 'EPSG:2154', | ||
keywords: ['features', 'rpg2010'], | ||
latLonBoundingBox: [ | ||
@@ -57,2 +58,3 @@ -1.9540704007796161, 42.73286181824404, 1.496463327812538, | ||
defaultCrs: 'EPSG:2154', | ||
keywords: ['features', 'comptages_routiers_l'], | ||
latLonBoundingBox: [ | ||
@@ -77,2 +79,3 @@ -0.4906009184568518, 45.175543885638376, 0.9778719979726385, | ||
defaultCrs: 'EPSG:2154', | ||
keywords: ['features', 'hierarchisation_l'], | ||
latLonBoundingBox: [ | ||
@@ -137,2 +140,3 @@ -0.4832134559131876, 45.18037755571674, 0.9725372441782966, | ||
defaultCrs: 'EPSG:2154', | ||
keywords: ['domaine_public_hdf_com', 'domaine', 'public'], | ||
latLonBoundingBox: [ | ||
@@ -139,0 +143,0 @@ 1.3472171890368316, 48.82764887581316, 4.285589467078578, |
@@ -161,2 +161,12 @@ import { | ||
const keywords = serviceVersion.startsWith('1.0') | ||
? getElementText(findChildElement(featureTypeEl, 'Keywords')) | ||
.split(',') | ||
.map((keyword) => keyword.trim()) | ||
: findChildrenElement( | ||
findChildElement(featureTypeEl, 'Keywords'), | ||
'Keyword' | ||
) | ||
.map(getElementText) | ||
.filter((v, i, arr) => arr.indexOf(v) === i); | ||
return { | ||
@@ -175,3 +185,4 @@ name: getElementText(findChildElement(featureTypeEl, 'Name')), | ||
: parseBBox(), | ||
keywords: keywords, | ||
}; | ||
} |
@@ -134,2 +134,3 @@ // @ts-expect-error ts-migrate(7016) | ||
defaultCrs: 'EPSG:2154', | ||
keywords: ['features', 'hierarchisation_l'], | ||
otherCrs: ['EPSG:32615', 'EPSG:32616', 'EPSG:32617', 'EPSG:32618'], | ||
@@ -174,2 +175,3 @@ outputFormats: [ | ||
defaultCrs: 'EPSG:2154', | ||
keywords: ['features', 'hierarchisation_l'], | ||
otherCrs: ['EPSG:32615', 'EPSG:32616', 'EPSG:32617', 'EPSG:32618'], | ||
@@ -176,0 +178,0 @@ outputFormats: [ |
@@ -127,2 +127,3 @@ import { | ||
outputFormats: featureType.outputFormats, | ||
keywords: featureType.keywords, | ||
} as WfsFeatureTypeSummary; | ||
@@ -129,0 +130,0 @@ } |
@@ -33,2 +33,3 @@ import { | ||
latLonBoundingBox: boundingBox, | ||
keywords, | ||
} = featureType; | ||
@@ -81,2 +82,3 @@ | ||
...(!Number.isNaN(objectCount) && { objectCount }), | ||
...(keywords && { keywords }), | ||
}; | ||
@@ -83,0 +85,0 @@ } |
@@ -13,2 +13,3 @@ import { BoundingBox, CrsCode, MimeType } from '../shared/models.js'; | ||
latLonBoundingBox?: BoundingBox; | ||
keywords?: string[]; | ||
}; | ||
@@ -48,2 +49,3 @@ | ||
outputFormats: MimeType[]; | ||
keywords?: string[]; | ||
}; | ||
@@ -78,2 +80,3 @@ | ||
objectCount?: number; | ||
keywords?: string[]; | ||
}; | ||
@@ -80,0 +83,0 @@ |
@@ -56,3 +56,14 @@ import { | ||
}, | ||
keywords: [ | ||
'Géologie', | ||
'BRGM', | ||
'INSPIRE:ViewService', | ||
'infoMapAccessService', | ||
'WMS 1.1.1', | ||
'WMS 1.3.0', | ||
'SLD 1.1.0', | ||
], | ||
name: 'GEOSERVICES_GEOLOGIE', | ||
queryable: false, | ||
opaque: false, | ||
styles: [ | ||
@@ -80,3 +91,6 @@ { | ||
}, | ||
keywords: [], | ||
name: 'GEOLOGIE', | ||
queryable: false, | ||
opaque: false, | ||
styles, | ||
@@ -122,3 +136,6 @@ title: 'Cartes géologiques', | ||
}, | ||
keywords: ['Geologie', 'INSPIRE:Geology', 'Geology'], | ||
name: 'SCAN_F_GEOL1M', | ||
queryable: false, | ||
opaque: false, | ||
styles: [ | ||
@@ -173,3 +190,6 @@ { | ||
}, | ||
keywords: ['Geologie', 'INSPIRE:Geology', 'Geology'], | ||
name: 'SCAN_F_GEOL250', | ||
queryable: true, | ||
opaque: true, | ||
styles, | ||
@@ -211,3 +231,6 @@ title: 'Carte géologique image de la France au 1/250000', | ||
}, | ||
keywords: ['Geologie', 'INSPIRE:Geology', 'Geology'], | ||
name: 'SCAN_D_GEOL50', | ||
queryable: true, | ||
opaque: true, | ||
styles, | ||
@@ -237,3 +260,6 @@ title: 'Carte géologique image de la France au 1/50 000e', | ||
}, | ||
keywords: [], | ||
name: 'INHERIT_BBOX', | ||
queryable: false, | ||
opaque: false, | ||
styles: [ | ||
@@ -270,2 +296,12 @@ { | ||
title: 'GéoServices : géologie, hydrogéologie et gravimétrie', | ||
outputFormats: [ | ||
'image/png', | ||
'image/gif', | ||
'image/jpeg', | ||
'image/ecw', | ||
'image/tiff', | ||
'image/png; mode=8bit', | ||
'application/x-pdf', | ||
'image/svg+xml', | ||
], | ||
keywords: [ | ||
@@ -272,0 +308,0 @@ 'Géologie', |
@@ -43,2 +43,19 @@ import { | ||
export function readOutputFormatsFromCapabilities( | ||
capabilitiesDoc: XmlDocument | ||
) { | ||
const capability = findChildElement( | ||
getRootElement(capabilitiesDoc), | ||
'Capability' | ||
); | ||
const getMap = findChildElement( | ||
findChildElement(capability, 'Request'), | ||
'GetMap' | ||
); | ||
const outputFormats = findChildrenElement(getMap, 'Format').map( | ||
getElementText | ||
); | ||
return outputFormats; | ||
} | ||
/** | ||
@@ -53,2 +70,3 @@ * Will read service-related info from the capabilities doc | ||
const service = findChildElement(getRootElement(capabilitiesDoc), 'Service'); | ||
const formats = readOutputFormatsFromCapabilities(capabilitiesDoc); | ||
const keywords = findChildrenElement( | ||
@@ -65,2 +83,3 @@ findChildElement(service, 'KeywordList'), | ||
abstract: getElementText(findChildElement(service, 'Abstract')), | ||
outputFormats: formats, | ||
fees: getElementText(findChildElement(service, 'Fees')), | ||
@@ -138,2 +157,20 @@ constraints: getElementText(findChildElement(service, 'AccessConstraints')), | ||
: inheritedBoundingBoxes; | ||
const queryable = | ||
layerEl.attributes.queryable === '1' || | ||
layerEl.attributes.queryable === 'true' | ||
? true | ||
: false; | ||
const opaque = | ||
layerEl.attributes.opaque === '1' || layerEl.attributes.opaque === 'true' | ||
? true | ||
: false; | ||
const keywords = findChildrenElement( | ||
findChildElement(layerEl, 'KeywordList'), | ||
'Keyword' | ||
) | ||
.map(getElementText) | ||
.filter((v, i, arr) => arr.indexOf(v) === i); | ||
const children = findChildrenElement(layerEl, 'Layer').map((layer) => | ||
@@ -150,2 +187,5 @@ parseLayer(layer, version, availableCrs, styles, attribution, boundingBoxes) | ||
boundingBoxes, | ||
keywords, | ||
queryable, | ||
opaque, | ||
...(children.length && { children }), | ||
@@ -160,5 +200,7 @@ }; | ||
); | ||
const abstract = getElementText(findChildElement(styleEl, 'Abstract')); | ||
return { | ||
name: getElementText(findChildElement(styleEl, 'Name')), | ||
title: getElementText(findChildElement(styleEl, 'Title')), | ||
...(abstract && { abstract }), | ||
...(legendUrl && { legendUrl }), | ||
@@ -165,0 +207,0 @@ }; |
@@ -134,3 +134,6 @@ // @ts-expect-error ts-migrate(7016) | ||
}, | ||
keywords: [], | ||
name: 'GEOLOGIE', | ||
queryable: false, | ||
opaque: false, | ||
styles: [ | ||
@@ -178,2 +181,12 @@ { | ||
title: 'GéoServices : géologie, hydrogéologie et gravimétrie', | ||
outputFormats: [ | ||
'image/png', | ||
'image/gif', | ||
'image/jpeg', | ||
'image/ecw', | ||
'image/tiff', | ||
'image/png; mode=8bit', | ||
'application/x-pdf', | ||
'image/svg+xml', | ||
], | ||
keywords: [ | ||
@@ -180,0 +193,0 @@ 'Géologie', |
@@ -35,3 +35,6 @@ import { BoundingBox, CrsCode, LayerStyle } from '../shared/models.js'; | ||
boundingBoxes: Record<CrsCode, BoundingBox>; | ||
queryable: boolean; | ||
opaque: boolean; | ||
attribution?: WmsLayerAttribution; | ||
keywords?: string[]; | ||
/** | ||
@@ -38,0 +41,0 @@ * Not defined if the layer is a leaf in the tree |
@@ -555,2 +555,4 @@ import { | ||
title: 'Thick And Red', | ||
abstract: | ||
'Specify this style if you want your maps to have thick red coastlines.', | ||
}, | ||
@@ -733,2 +735,3 @@ ], | ||
title: 'Données Brutes', | ||
abstract: 'Données brutes sans changement de palette', | ||
}, | ||
@@ -735,0 +738,0 @@ ], |
@@ -171,5 +171,7 @@ import type { BoundingBox, LayerStyle } from '../shared/models.js'; | ||
); | ||
const abstract = getElementText(findChildElement(element, 'Abstract')); | ||
const style: LayerStyle = { | ||
title: getElementText(findChildElement(element, 'Title')), | ||
name: getElementText(findChildElement(element, 'Identifier')), | ||
...(abstract && { abstract }), | ||
...(legendUrl && { legendUrl }), | ||
@@ -176,0 +178,0 @@ }; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
1281422
24
192
21325
4
+ Addednode-fetch@^3.3.1
+ Addeddata-uri-to-buffer@4.0.1(transitive)
+ Addedfetch-blob@3.2.0(transitive)
+ Addedformdata-polyfill@4.0.10(transitive)
+ Addednode-domexception@1.0.0(transitive)
+ Addednode-fetch@3.3.2(transitive)
+ Addedweb-streams-polyfill@3.3.3(transitive)