@itwin/map-layers-formats 5.13.0-dev.9 → 5.14.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -1
- package/lib/cjs/ArcGisFeature/ArcGisFeatureProvider.d.ts.map +1 -1
- package/lib/cjs/ArcGisFeature/ArcGisFeatureProvider.js +9 -6
- package/lib/cjs/ArcGisFeature/ArcGisFeatureProvider.js.map +1 -1
- package/lib/cjs/Feature/FeatureInfoReader.d.ts.map +1 -1
- package/lib/cjs/Feature/FeatureInfoReader.js +5 -2
- package/lib/cjs/Feature/FeatureInfoReader.js.map +1 -1
- package/lib/cjs/GoogleMaps/GoogleMapsImageryProvider.d.ts.map +1 -1
- package/lib/cjs/GoogleMaps/GoogleMapsImageryProvider.js +8 -5
- package/lib/cjs/GoogleMaps/GoogleMapsImageryProvider.js.map +1 -1
- package/lib/cjs/OgcApiFeatures/OgcApiFeaturesFormat.d.ts.map +1 -1
- package/lib/cjs/OgcApiFeatures/OgcApiFeaturesFormat.js +39 -3
- package/lib/cjs/OgcApiFeatures/OgcApiFeaturesFormat.js.map +1 -1
- package/lib/cjs/OgcApiFeatures/OgcApiFeaturesProvider.d.ts.map +1 -1
- package/lib/cjs/OgcApiFeatures/OgcApiFeaturesProvider.js +26 -17
- package/lib/cjs/OgcApiFeatures/OgcApiFeaturesProvider.js.map +1 -1
- package/lib/esm/ArcGisFeature/ArcGisFeatureProvider.d.ts.map +1 -1
- package/lib/esm/ArcGisFeature/ArcGisFeatureProvider.js +10 -7
- package/lib/esm/ArcGisFeature/ArcGisFeatureProvider.js.map +1 -1
- package/lib/esm/Feature/FeatureInfoReader.d.ts.map +1 -1
- package/lib/esm/Feature/FeatureInfoReader.js +5 -2
- package/lib/esm/Feature/FeatureInfoReader.js.map +1 -1
- package/lib/esm/GoogleMaps/GoogleMapsImageryProvider.d.ts.map +1 -1
- package/lib/esm/GoogleMaps/GoogleMapsImageryProvider.js +8 -5
- package/lib/esm/GoogleMaps/GoogleMapsImageryProvider.js.map +1 -1
- package/lib/esm/OgcApiFeatures/OgcApiFeaturesFormat.d.ts.map +1 -1
- package/lib/esm/OgcApiFeatures/OgcApiFeaturesFormat.js +40 -4
- package/lib/esm/OgcApiFeatures/OgcApiFeaturesFormat.js.map +1 -1
- package/lib/esm/OgcApiFeatures/OgcApiFeaturesProvider.d.ts.map +1 -1
- package/lib/esm/OgcApiFeatures/OgcApiFeaturesProvider.js +27 -18
- package/lib/esm/OgcApiFeatures/OgcApiFeaturesProvider.js.map +1 -1
- package/package.json +12 -12
|
@@ -21,9 +21,33 @@ class OgcApiFeaturesMapLayerFormat extends core_frontend_1.ImageryMapLayerFormat
|
|
|
21
21
|
method: "GET",
|
|
22
22
|
headers,
|
|
23
23
|
};
|
|
24
|
+
// Classify HTTP failures before parsing JSON, using the final response URL to enforce origin trust after redirects.
|
|
25
|
+
const classifyResponseFailure = (httpResponse, requestedUrl) => {
|
|
26
|
+
if (httpResponse.ok)
|
|
27
|
+
return undefined;
|
|
28
|
+
if (httpResponse.status === 401 || httpResponse.status === 403) {
|
|
29
|
+
const challengedUrl = httpResponse.url || requestedUrl;
|
|
30
|
+
if (!core_frontend_1.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(challengedUrl, source.url)) {
|
|
31
|
+
let blockedOrigin;
|
|
32
|
+
try {
|
|
33
|
+
blockedOrigin = new URL(challengedUrl).origin;
|
|
34
|
+
}
|
|
35
|
+
catch { /* non-hierarchical URL */ }
|
|
36
|
+
return { status: core_frontend_1.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
|
|
37
|
+
}
|
|
38
|
+
return { status: (userName && password) ? core_frontend_1.MapLayerSourceStatus.InvalidCredentials : core_frontend_1.MapLayerSourceStatus.RequireAuth };
|
|
39
|
+
}
|
|
40
|
+
return { status: core_frontend_1.MapLayerSourceStatus.InvalidUrl };
|
|
41
|
+
};
|
|
24
42
|
let url = (0, core_frontend_1.appendQueryParams)(source.url, source.savedQueryParams);
|
|
25
43
|
url = (0, core_frontend_1.appendQueryParams)(url, source.unsavedQueryParams);
|
|
26
|
-
|
|
44
|
+
const allowLandingCredentials = core_frontend_1.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, source.url);
|
|
45
|
+
if (headers && allowLandingCredentials)
|
|
46
|
+
core_frontend_1.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(url, source.url);
|
|
47
|
+
let response = await fetch(url, allowLandingCredentials ? opts : { method: "GET" });
|
|
48
|
+
const landingFailure = classifyResponseFailure(response, url);
|
|
49
|
+
if (landingFailure)
|
|
50
|
+
return landingFailure;
|
|
27
51
|
let json = await response.json();
|
|
28
52
|
if (!json) {
|
|
29
53
|
return { status };
|
|
@@ -70,9 +94,21 @@ class OgcApiFeaturesMapLayerFormat extends core_frontend_1.ImageryMapLayerFormat
|
|
|
70
94
|
else if (Array.isArray(json.links)) {
|
|
71
95
|
// This might be the main landing page
|
|
72
96
|
const collectionsLink = json.links.find((link) => link.rel.includes("data") && link.type === "application/json");
|
|
73
|
-
|
|
97
|
+
// Landing-page links are allowed to be relative, so resolve them against the URL the landing document
|
|
98
|
+
// was actually served from (which may differ from the requested one if the request was redirected)
|
|
99
|
+
// before appending query parameters or evaluating trust.
|
|
100
|
+
let collectionsUrl = new URL(collectionsLink.href, response.url || url).toString();
|
|
101
|
+
collectionsUrl = (0, core_frontend_1.appendQueryParams)(collectionsUrl, source.savedQueryParams);
|
|
74
102
|
collectionsUrl = (0, core_frontend_1.appendQueryParams)(collectionsUrl, source.unsavedQueryParams);
|
|
75
|
-
|
|
103
|
+
// The collections link is advertised by the server-controlled landing document, so the trust
|
|
104
|
+
// decision is applied to it independently of the source URL.
|
|
105
|
+
const allowCreds = core_frontend_1.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(collectionsUrl, source.url);
|
|
106
|
+
if (headers && allowCreds)
|
|
107
|
+
core_frontend_1.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(collectionsUrl, source.url);
|
|
108
|
+
response = await fetch(collectionsUrl, allowCreds ? opts : { method: "GET" });
|
|
109
|
+
const collectionsFailure = classifyResponseFailure(response, collectionsUrl);
|
|
110
|
+
if (collectionsFailure)
|
|
111
|
+
return collectionsFailure;
|
|
76
112
|
json = await response.json();
|
|
77
113
|
if (Array.isArray(json.collections)) {
|
|
78
114
|
subLayers = createCollectionsList(json);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OgcApiFeaturesFormat.js","sourceRoot":"","sources":["../../../src/OgcApiFeatures/OgcApiFeaturesFormat.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { ImageMapLayerSettings, MapSubLayerProps } from \"@itwin/core-common\";\r\nimport { appendQueryParams, ImageryMapLayerFormat, MapLayerImageryProvider, MapLayerSourceStatus, MapLayerSourceValidation, setBasicAuthorization, ValidateSourceArgs } from \"@itwin/core-frontend\";\r\nimport { OgcApiFeaturesProvider } from \"./OgcApiFeaturesProvider.js\";\r\n\r\n/** @internal */\r\nexport class OgcApiFeaturesMapLayerFormat extends ImageryMapLayerFormat {\r\n public static override formatId = \"OgcApiFeatures\";\r\n public static override createImageryProvider(settings: ImageMapLayerSettings): MapLayerImageryProvider | undefined { return new OgcApiFeaturesProvider(settings); }\r\n\r\n public static override async validate(args: ValidateSourceArgs): Promise<MapLayerSourceValidation> {\r\n\r\n const {source} = args;\r\n const { userName, password } = source;\r\n let status = MapLayerSourceStatus.InvalidUrl;\r\n try {\r\n\r\n let headers: Headers | undefined;\r\n if (userName && password) {\r\n headers = new Headers();\r\n setBasicAuthorization(headers, userName, password);\r\n }\r\n const opts: RequestInit = {\r\n method: \"GET\",\r\n headers,\r\n };\r\n\r\n let url = appendQueryParams(source.url, source.savedQueryParams);\r\n url = appendQueryParams(url, source.unsavedQueryParams);\r\n let response = await fetch(url, opts);\r\n let json = await response.json();\r\n if (!json) {\r\n return { status };\r\n }\r\n\r\n const createCollectionsList = (data: any) => {\r\n let array: MapSubLayerProps[] | undefined;\r\n for (const collection of data.collections) {\r\n if (collection.itemType === \"feature\") {\r\n const subLayerProps = {\r\n id: collection.id,\r\n name: collection.id,\r\n title: collection.title,\r\n visible: true,\r\n parent: undefined,\r\n children: undefined,\r\n };\r\n if (array)\r\n array.push(subLayerProps);\r\n else\r\n array = [subLayerProps];\r\n }\r\n }\r\n return array;\r\n };\r\n\r\n let subLayers: MapSubLayerProps[] | undefined;\r\n if (Array.isArray(json.collections)) {\r\n subLayers = createCollectionsList(json);\r\n status = MapLayerSourceStatus.Valid;\r\n } else if (json.itemType === \"feature\" || json.type === \"FeatureCollection\") {\r\n // We expect one of the following URL:\r\n // http://server/collections/<collectionName>\r\n // http://server/collections/<collectionName>/items\r\n subLayers = [{\r\n id: json.id,\r\n name: json.id,\r\n title: json.title,\r\n visible: true,\r\n parent: undefined,\r\n children: undefined,\r\n }];\r\n status = MapLayerSourceStatus.Valid;\r\n } else if (Array.isArray(json.links)) {\r\n // This might be the main landing page\r\n const collectionsLink = json.links.find((link: any)=> link.rel.includes(\"data\") && link.type === \"application/json\");\r\n let collectionsUrl = appendQueryParams(collectionsLink.href, source.savedQueryParams);\r\n collectionsUrl = appendQueryParams(collectionsUrl, source.unsavedQueryParams);\r\n response = await fetch(collectionsUrl, opts);\r\n json = await response.json();\r\n if (Array.isArray(json.collections)) {\r\n subLayers = createCollectionsList(json);\r\n status = MapLayerSourceStatus.Valid;\r\n }\r\n\r\n }\r\n\r\n return { status, subLayers };\r\n\r\n } catch (err: any) {\r\n status = MapLayerSourceStatus.InvalidUrl;\r\n if (err?.status === 401) {\r\n status = ((userName && password) ? MapLayerSourceStatus.InvalidCredentials : MapLayerSourceStatus.RequireAuth);\r\n }\r\n return { status};\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"OgcApiFeaturesFormat.js","sourceRoot":"","sources":["../../../src/OgcApiFeatures/OgcApiFeaturesFormat.ts"],"names":[],"mappings":";;;AAKA,wDAA+M;AAC/M,2EAAqE;AAErE,gBAAgB;AAChB,MAAa,4BAA6B,SAAQ,qCAAqB;IAC9D,MAAM,CAAU,QAAQ,GAAG,gBAAgB,CAAC;IAC5C,MAAM,CAAU,qBAAqB,CAAC,QAA+B,IAAyC,OAAO,IAAI,kDAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE5J,MAAM,CAAU,KAAK,CAAC,QAAQ,CAAC,IAAwB;QAE5D,MAAM,EAAC,MAAM,EAAC,GAAG,IAAI,CAAC;QACtB,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QACtC,IAAI,MAAM,GAAG,oCAAoB,CAAC,UAAU,CAAC;QAC7C,IAAI,CAAC;YAEH,IAAI,OAA4B,CAAC;YACjC,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;gBACzB,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAA,qCAAqB,EAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,IAAI,GAAgB;gBACxB,MAAM,EAAE,KAAK;gBACb,OAAO;aACR,CAAC;YAEF,oHAAoH;YACpH,MAAM,uBAAuB,GAAG,CAAC,YAAsB,EAAE,YAAoB,EAAwC,EAAE;gBACrH,IAAI,YAAY,CAAC,EAAE;oBACjB,OAAO,SAAS,CAAC;gBAEnB,IAAI,YAAY,CAAC,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC/D,MAAM,aAAa,GAAG,YAAY,CAAC,GAAG,IAAI,YAAY,CAAC;oBACvD,IAAI,CAAC,yBAAS,CAAC,sBAAsB,CAAC,2BAA2B,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7F,IAAI,aAAiC,CAAC;wBACtC,IAAI,CAAC;4BAAC,aAAa,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC;wBAAC,CAAC;wBAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;wBAC3F,OAAO,EAAE,MAAM,EAAE,oCAAoB,CAAC,eAAe,EAAE,aAAa,EAAE,CAAC;oBACzE,CAAC;oBAED,OAAO,EAAE,MAAM,EAAE,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,oCAAoB,CAAC,kBAAkB,CAAC,CAAC,CAAC,oCAAoB,CAAC,WAAW,EAAE,CAAC;gBACzH,CAAC;gBAED,OAAO,EAAE,MAAM,EAAE,oCAAoB,CAAC,UAAU,EAAE,CAAC;YACrD,CAAC,CAAC;YAEF,IAAI,GAAG,GAAG,IAAA,iCAAiB,EAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACjE,GAAG,GAAG,IAAA,iCAAiB,EAAC,GAAG,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACxD,MAAM,uBAAuB,GAAG,yBAAS,CAAC,sBAAsB,CAAC,2BAA2B,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9G,IAAI,OAAO,IAAI,uBAAuB;gBACpC,yBAAS,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAE1E,IAAI,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACpF,MAAM,cAAc,GAAG,uBAAuB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAC9D,IAAI,cAAc;gBAChB,OAAO,cAAc,CAAC;YAExB,IAAI,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,CAAC;YAED,MAAM,qBAAqB,GAAG,CAAC,IAAS,EAAE,EAAE;gBAC1C,IAAI,KAAqC,CAAC;gBAC1C,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBAC1C,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;wBACtC,MAAM,aAAa,GAAG;4BACpB,EAAE,EAAE,UAAU,CAAC,EAAE;4BACjB,IAAI,EAAE,UAAU,CAAC,EAAE;4BACnB,KAAK,EAAE,UAAU,CAAC,KAAK;4BACvB,OAAO,EAAE,IAAI;4BACb,MAAM,EAAE,SAAS;4BACjB,QAAQ,EAAE,SAAS;yBACpB,CAAC;wBACF,IAAI,KAAK;4BACP,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;;4BAE1B,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC,CAAC;YAEF,IAAI,SAAyC,CAAC;YAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpC,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,GAAG,oCAAoB,CAAC,KAAK,CAAC;YACtC,CAAC;iBAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;gBAC5E,sCAAsC;gBACtC,6CAA6C;gBAC7C,mDAAmD;gBACnD,SAAS,GAAG,CAAC;wBACX,EAAE,EAAE,IAAI,CAAC,EAAE;wBACX,IAAI,EAAE,IAAI,CAAC,EAAE;wBACb,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,SAAS;wBACjB,QAAQ,EAAE,SAAS;qBACpB,CAAC,CAAC;gBACH,MAAM,GAAG,oCAAoB,CAAC,KAAK,CAAC;YACtC,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrC,sCAAsC;gBACtC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;gBACrH,sGAAsG;gBACtG,mGAAmG;gBACnG,yDAAyD;gBACzD,IAAI,cAAc,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACnF,cAAc,GAAG,IAAA,iCAAiB,EAAC,cAAc,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBAC5E,cAAc,GAAG,IAAA,iCAAiB,EAAC,cAAc,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;gBAE9E,6FAA6F;gBAC7F,6DAA6D;gBAC7D,MAAM,UAAU,GAAG,yBAAS,CAAC,sBAAsB,CAAC,2BAA2B,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5G,IAAI,OAAO,IAAI,UAAU;oBACvB,yBAAS,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;gBAErF,QAAQ,GAAG,MAAM,KAAK,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC9E,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAC7E,IAAI,kBAAkB;oBACpB,OAAO,kBAAkB,CAAC;gBAE5B,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;oBACpC,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;oBACxC,MAAM,GAAG,oCAAoB,CAAC,KAAK,CAAC;gBACtC,CAAC;YAEH,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAE/B,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,GAAG,oCAAoB,CAAC,UAAU,CAAC;YACzC,IAAI,GAAG,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;gBACxB,MAAM,GAAG,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,oCAAoB,CAAC,kBAAkB,CAAC,CAAC,CAAC,oCAAoB,CAAC,WAAW,CAAC,CAAC;YACjH,CAAC;YACD,OAAO,EAAE,MAAM,EAAC,CAAC;QACnB,CAAC;IACH,CAAC;;AApIH,oEAqIC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { ImageMapLayerSettings, MapSubLayerProps } from \"@itwin/core-common\";\r\nimport { appendQueryParams, ImageryMapLayerFormat, IModelApp, MapLayerImageryProvider, MapLayerSourceStatus, MapLayerSourceValidation, setBasicAuthorization, ValidateSourceArgs } from \"@itwin/core-frontend\";\r\nimport { OgcApiFeaturesProvider } from \"./OgcApiFeaturesProvider.js\";\r\n\r\n/** @internal */\r\nexport class OgcApiFeaturesMapLayerFormat extends ImageryMapLayerFormat {\r\n public static override formatId = \"OgcApiFeatures\";\r\n public static override createImageryProvider(settings: ImageMapLayerSettings): MapLayerImageryProvider | undefined { return new OgcApiFeaturesProvider(settings); }\r\n\r\n public static override async validate(args: ValidateSourceArgs): Promise<MapLayerSourceValidation> {\r\n\r\n const {source} = args;\r\n const { userName, password } = source;\r\n let status = MapLayerSourceStatus.InvalidUrl;\r\n try {\r\n\r\n let headers: Headers | undefined;\r\n if (userName && password) {\r\n headers = new Headers();\r\n setBasicAuthorization(headers, userName, password);\r\n }\r\n const opts: RequestInit = {\r\n method: \"GET\",\r\n headers,\r\n };\r\n\r\n // Classify HTTP failures before parsing JSON, using the final response URL to enforce origin trust after redirects.\r\n const classifyResponseFailure = (httpResponse: Response, requestedUrl: string): MapLayerSourceValidation | undefined => {\r\n if (httpResponse.ok)\r\n return undefined;\r\n\r\n if (httpResponse.status === 401 || httpResponse.status === 403) {\r\n const challengedUrl = httpResponse.url || requestedUrl;\r\n if (!IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(challengedUrl, source.url)) {\r\n let blockedOrigin: string | undefined;\r\n try { blockedOrigin = new URL(challengedUrl).origin; } catch { /* non-hierarchical URL */ }\r\n return { status: MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };\r\n }\r\n\r\n return { status: (userName && password) ? MapLayerSourceStatus.InvalidCredentials : MapLayerSourceStatus.RequireAuth };\r\n }\r\n\r\n return { status: MapLayerSourceStatus.InvalidUrl };\r\n };\r\n\r\n let url = appendQueryParams(source.url, source.savedQueryParams);\r\n url = appendQueryParams(url, source.unsavedQueryParams);\r\n const allowLandingCredentials = IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, source.url);\r\n if (headers && allowLandingCredentials)\r\n IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(url, source.url);\r\n\r\n let response = await fetch(url, allowLandingCredentials ? opts : { method: \"GET\" });\r\n const landingFailure = classifyResponseFailure(response, url);\r\n if (landingFailure)\r\n return landingFailure;\r\n\r\n let json = await response.json();\r\n if (!json) {\r\n return { status };\r\n }\r\n\r\n const createCollectionsList = (data: any) => {\r\n let array: MapSubLayerProps[] | undefined;\r\n for (const collection of data.collections) {\r\n if (collection.itemType === \"feature\") {\r\n const subLayerProps = {\r\n id: collection.id,\r\n name: collection.id,\r\n title: collection.title,\r\n visible: true,\r\n parent: undefined,\r\n children: undefined,\r\n };\r\n if (array)\r\n array.push(subLayerProps);\r\n else\r\n array = [subLayerProps];\r\n }\r\n }\r\n return array;\r\n };\r\n\r\n let subLayers: MapSubLayerProps[] | undefined;\r\n if (Array.isArray(json.collections)) {\r\n subLayers = createCollectionsList(json);\r\n status = MapLayerSourceStatus.Valid;\r\n } else if (json.itemType === \"feature\" || json.type === \"FeatureCollection\") {\r\n // We expect one of the following URL:\r\n // http://server/collections/<collectionName>\r\n // http://server/collections/<collectionName>/items\r\n subLayers = [{\r\n id: json.id,\r\n name: json.id,\r\n title: json.title,\r\n visible: true,\r\n parent: undefined,\r\n children: undefined,\r\n }];\r\n status = MapLayerSourceStatus.Valid;\r\n } else if (Array.isArray(json.links)) {\r\n // This might be the main landing page\r\n const collectionsLink = json.links.find((link: any)=> link.rel.includes(\"data\") && link.type === \"application/json\");\r\n // Landing-page links are allowed to be relative, so resolve them against the URL the landing document\r\n // was actually served from (which may differ from the requested one if the request was redirected)\r\n // before appending query parameters or evaluating trust.\r\n let collectionsUrl = new URL(collectionsLink.href, response.url || url).toString();\r\n collectionsUrl = appendQueryParams(collectionsUrl, source.savedQueryParams);\r\n collectionsUrl = appendQueryParams(collectionsUrl, source.unsavedQueryParams);\r\n\r\n // The collections link is advertised by the server-controlled landing document, so the trust\r\n // decision is applied to it independently of the source URL.\r\n const allowCreds = IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(collectionsUrl, source.url);\r\n if (headers && allowCreds)\r\n IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(collectionsUrl, source.url);\r\n\r\n response = await fetch(collectionsUrl, allowCreds ? opts : { method: \"GET\" });\r\n const collectionsFailure = classifyResponseFailure(response, collectionsUrl);\r\n if (collectionsFailure)\r\n return collectionsFailure;\r\n\r\n json = await response.json();\r\n if (Array.isArray(json.collections)) {\r\n subLayers = createCollectionsList(json);\r\n status = MapLayerSourceStatus.Valid;\r\n }\r\n\r\n }\r\n\r\n return { status, subLayers };\r\n\r\n } catch (err: any) {\r\n status = MapLayerSourceStatus.InvalidUrl;\r\n if (err?.status === 401) {\r\n status = ((userName && password) ? MapLayerSourceStatus.InvalidCredentials : MapLayerSourceStatus.RequireAuth);\r\n }\r\n return { status};\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OgcApiFeaturesProvider.d.ts","sourceRoot":"","sources":["../../../src/OgcApiFeatures/OgcApiFeaturesProvider.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAY,qBAAqB,EAAE,WAAW,EAA8C,MAAM,oBAAoB,CAAC;AAC5I,OAAO,EAA2B,SAAS,EAAE,kBAAkB,EAAqB,qBAAqB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,EAAe,MAAM,sBAAsB,CAAC;AAI3M,OAAO,EAAqF,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAGlJ,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAM9D;;EAEE;AACF,qBAAa,mBAAoB,YAAW,uBAAuB;IAEjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAQtC;IACF,OAAO,CAAC,WAAW,CAAU;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAKtC;IACF,OAAO,CAAC,WAAW,CAAU;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAKtC;IACF,OAAO,CAAC,WAAW,CAA0D;gBAE1D,WAAW,CAAC,EAAE,cAAc;IA4BlC,UAAU;IAKhB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU;CAUtD;AACD,gBAAgB;AAChB,qBAAa,sBAAuB,SAAQ,uBAAuB;IAGjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAGxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,cAAc,CAAiD;IACvE,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkD;IAC5E,OAAO,CAAC,WAAW,CAAM;IAElB,WAAW,EAAE,GAAG,CAAC;IACxB,OAAO,CAAC,WAAW,CAAsC;gBAE7C,QAAQ,EAAE,qBAAqB;IAI3C,IAAoB,sBAAsB,YAAkB;IAC5D,IAAoB,gBAAgB,IAAI,MAAM,CAA6E;IAC3H,IAAW,UAAU,IAAI,OAAO,CAA6E;IAEvF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"OgcApiFeaturesProvider.d.ts","sourceRoot":"","sources":["../../../src/OgcApiFeatures/OgcApiFeaturesProvider.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAY,qBAAqB,EAAE,WAAW,EAA8C,MAAM,oBAAoB,CAAC;AAC5I,OAAO,EAA2B,SAAS,EAAE,kBAAkB,EAAqB,qBAAqB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,EAAe,MAAM,sBAAsB,CAAC;AAI3M,OAAO,EAAqF,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAGlJ,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAM9D;;EAEE;AACF,qBAAa,mBAAoB,YAAW,uBAAuB;IAEjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAQtC;IACF,OAAO,CAAC,WAAW,CAAU;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAKtC;IACF,OAAO,CAAC,WAAW,CAAU;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAKtC;IACF,OAAO,CAAC,WAAW,CAA0D;gBAE1D,WAAW,CAAC,EAAE,cAAc;IA4BlC,UAAU;IAKhB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU;CAUtD;AACD,gBAAgB;AAChB,qBAAa,sBAAuB,SAAQ,uBAAuB;IAGjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAGxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,cAAc,CAAiD;IACvE,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkD;IAC5E,OAAO,CAAC,WAAW,CAAM;IAElB,WAAW,EAAE,GAAG,CAAC;IACxB,OAAO,CAAC,WAAW,CAAsC;gBAE7C,QAAQ,EAAE,qBAAqB;IAI3C,IAAoB,sBAAsB,YAAkB;IAC5D,IAAoB,gBAAgB,IAAI,MAAM,CAA6E;IAC3H,IAAW,UAAU,IAAI,OAAO,CAA6E;IAEvF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YA+HnC,aAAa;YAOb,aAAa;YAQb,UAAU;YAuCV,eAAe;IA+D7B,IAAoB,QAAQ,IAAI,MAAM,CAAgB;IAGzC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAItF,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB;IAUnG,gCAAgC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IA2BhE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAkFhH,OAAO,CAAC,4BAA4B;IAad,cAAc,CAAC,YAAY,EAAE,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAuC1M"}
|
|
@@ -119,7 +119,7 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
119
119
|
if (this._settings.subLayers && this._settings.subLayers.length > 0) {
|
|
120
120
|
layerId = this._settings.subLayers[0].id;
|
|
121
121
|
}
|
|
122
|
-
const readCollectionsPage = (data) => {
|
|
122
|
+
const readCollectionsPage = (data, baseUrl) => {
|
|
123
123
|
const collection = data.collections.find((col) => col.id === layerId);
|
|
124
124
|
const collectionLinks = collection?.links;
|
|
125
125
|
if (!collectionLinks) {
|
|
@@ -128,7 +128,7 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
128
128
|
throw new Error(msg);
|
|
129
129
|
}
|
|
130
130
|
const collectionLink = collectionLinks.find((link) => link.rel.includes("collection") && link.type === "application/json");
|
|
131
|
-
this._collectionUrl = collectionLink.href;
|
|
131
|
+
this._collectionUrl = new URL(collectionLink.href, baseUrl).toString();
|
|
132
132
|
};
|
|
133
133
|
const layerIdMismatch = () => {
|
|
134
134
|
const msg = `Collection metadata and sub-layers id mismatch`;
|
|
@@ -136,17 +136,20 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
136
136
|
throw new Error(msg);
|
|
137
137
|
};
|
|
138
138
|
let collectionMetadata;
|
|
139
|
-
let
|
|
139
|
+
let collectionResponseUrl = this._settings.url;
|
|
140
|
+
const { json: initialJson, responseUrl: initialResponseUrl } = await this.fetchMetadata(this._settings.url);
|
|
141
|
+
let json = initialJson;
|
|
140
142
|
if (json?.type === "FeatureCollection") {
|
|
141
143
|
// We landed on the items page, we need to look for the collection metadata url
|
|
142
144
|
if (Array.isArray(json.links)) {
|
|
143
145
|
const collectionLink = json.links.find((link) => link.rel.includes("collection") && link.type === "application/json");
|
|
144
|
-
this._collectionUrl = collectionLink.href;
|
|
146
|
+
this._collectionUrl = new URL(collectionLink.href, initialResponseUrl).toString();
|
|
145
147
|
}
|
|
146
148
|
}
|
|
147
149
|
else if (json.itemType === "feature") {
|
|
148
150
|
// We landed on a specific collection page.
|
|
149
151
|
collectionMetadata = json;
|
|
152
|
+
collectionResponseUrl = initialResponseUrl;
|
|
150
153
|
// Check if the collection id matches at least one sub-layer
|
|
151
154
|
if (this._settings.subLayers && this._settings.subLayers.length > 0) {
|
|
152
155
|
const subLayer = this._settings.subLayers.find((s) => s.id === collectionMetadata.id);
|
|
@@ -161,7 +164,7 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
161
164
|
else if (Array.isArray(json.collections)) {
|
|
162
165
|
// We landed in the "Collections" page
|
|
163
166
|
// Find to find the specified layer id among the available collections
|
|
164
|
-
readCollectionsPage(json);
|
|
167
|
+
readCollectionsPage(json, initialResponseUrl);
|
|
165
168
|
}
|
|
166
169
|
else if (Array.isArray(json.links)) {
|
|
167
170
|
// This might be the main landing page
|
|
@@ -171,14 +174,17 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
171
174
|
core_bentley_1.Logger.logError(loggerCategory, "Could not find collections link");
|
|
172
175
|
throw new core_common_1.ServerError(core_bentley_1.IModelStatus.ValidationFailed, "");
|
|
173
176
|
}
|
|
174
|
-
|
|
177
|
+
const collectionsHref = new URL(collectionsLink.href, initialResponseUrl).toString();
|
|
178
|
+
const collectionsResult = await this.fetchMetadata(collectionsHref);
|
|
179
|
+
json = collectionsResult.json;
|
|
175
180
|
if (Array.isArray(json.collections)) {
|
|
176
|
-
readCollectionsPage(json);
|
|
181
|
+
readCollectionsPage(json, collectionsResult.responseUrl);
|
|
177
182
|
}
|
|
178
183
|
}
|
|
179
184
|
// Read collection metadata
|
|
180
|
-
if (!collectionMetadata)
|
|
181
|
-
collectionMetadata = await this.fetchMetadata(this._collectionUrl);
|
|
185
|
+
if (!collectionMetadata) {
|
|
186
|
+
({ json: collectionMetadata, responseUrl: collectionResponseUrl } = await this.fetchMetadata(this._collectionUrl));
|
|
187
|
+
}
|
|
182
188
|
if (layerId !== undefined && layerId !== collectionMetadata.id) {
|
|
183
189
|
layerIdMismatch();
|
|
184
190
|
}
|
|
@@ -195,10 +201,10 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
195
201
|
if (Array.isArray(collectionMetadata?.links)) {
|
|
196
202
|
// Items links (Mandatory)
|
|
197
203
|
const itemsLink = collectionMetadata.links.find((link) => link.rel.includes("items") && link.type === "application/geo+json");
|
|
198
|
-
itemsHref = itemsLink.href;
|
|
204
|
+
itemsHref = new URL(itemsLink.href, collectionResponseUrl).toString();
|
|
199
205
|
// Queryables link (Optional)
|
|
200
206
|
const queryablesLink = collectionMetadata.links.find((link) => link.rel.includes("queryables") && link.type === "application/schema+json");
|
|
201
|
-
queryablesHref = queryablesLink.href;
|
|
207
|
+
queryablesHref = queryablesLink ? new URL(queryablesLink.href, collectionResponseUrl).toString() : undefined;
|
|
202
208
|
}
|
|
203
209
|
if (itemsHref)
|
|
204
210
|
this._itemsUrl = itemsHref;
|
|
@@ -208,7 +214,7 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
208
214
|
throw new Error(msg);
|
|
209
215
|
}
|
|
210
216
|
if (queryablesHref)
|
|
211
|
-
this._queryables = await this.fetchMetadata(queryablesHref);
|
|
217
|
+
this._queryables = (await this.fetchMetadata(queryablesHref)).json;
|
|
212
218
|
if (!this._forceTileMode) {
|
|
213
219
|
const status = await this.fetchAllItems();
|
|
214
220
|
if (status) {
|
|
@@ -220,7 +226,8 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
220
226
|
async fetchMetadata(url) {
|
|
221
227
|
const tmpUrl = this.appendCustomParams(url);
|
|
222
228
|
const response = await this.makeRequest(tmpUrl);
|
|
223
|
-
|
|
229
|
+
const json = await response.json();
|
|
230
|
+
return { json, responseUrl: response.url || tmpUrl };
|
|
224
231
|
}
|
|
225
232
|
async fetchAllItems() {
|
|
226
233
|
const urlObj = new URL(this._itemsUrl);
|
|
@@ -238,11 +245,13 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
238
245
|
let response = await this.makeTileRequest(tmpUrl, timeout);
|
|
239
246
|
let json = await response.json();
|
|
240
247
|
data = json;
|
|
241
|
-
// Follow "next" link if any
|
|
248
|
+
// Follow "next" link if any, resolving each href against the URL that served it
|
|
249
|
+
let pageResponseUrl = response.url || tmpUrl;
|
|
242
250
|
let nextLink = json.links?.find((link) => link.rel === "next");
|
|
243
251
|
while (nextLink && (Date.now() - fetchBegin) < timeout && success) {
|
|
244
|
-
tmpUrl = this.appendCustomParams(nextLink.href);
|
|
252
|
+
tmpUrl = this.appendCustomParams(new URL(nextLink.href, pageResponseUrl).toString());
|
|
245
253
|
response = await this.makeTileRequest(tmpUrl, this._staticModeFetchTimeout);
|
|
254
|
+
pageResponseUrl = response.url || tmpUrl;
|
|
246
255
|
json = await response.json();
|
|
247
256
|
if (json?.features)
|
|
248
257
|
data.features = this._staticData?.features ? [...this._staticData.features, ...json.features] : json.features;
|
|
@@ -424,13 +433,13 @@ class OgcApiFeaturesProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
|
424
433
|
this.drawTileDebugInfo(row, column, zoomLevel, ctx);
|
|
425
434
|
}
|
|
426
435
|
catch (e) {
|
|
427
|
-
core_bentley_1.Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${e}`);
|
|
436
|
+
core_bentley_1.Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${core_bentley_1.BentleyError.getErrorMessage(e)}`);
|
|
428
437
|
}
|
|
429
438
|
try {
|
|
430
439
|
return this.createImageSourceFromDataURL(canvas.toDataURL("image/png"), core_common_1.ImageSourceFormat.Png);
|
|
431
440
|
}
|
|
432
441
|
catch (e) {
|
|
433
|
-
core_bentley_1.Logger.logError(loggerCategory, `Exception occurred while rendering tile (${zoomLevel}/${row}/${column}) : ${e}
|
|
442
|
+
core_bentley_1.Logger.logError(loggerCategory, `Exception occurred while rendering tile (${zoomLevel}/${row}/${column}) : ${core_bentley_1.BentleyError.getErrorMessage(e)}`);
|
|
434
443
|
}
|
|
435
444
|
return undefined;
|
|
436
445
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OgcApiFeaturesProvider.js","sourceRoot":"","sources":["../../../src/OgcApiFeatures/OgcApiFeaturesProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { base64StringToUint8Array, expectDefined, IModelStatus, Logger } from \"@itwin/core-bentley\";\r\nimport { Cartographic, ColorDef, ImageMapLayerSettings, ImageSource, ImageSourceFormat, ServerError, SubLayerId } from \"@itwin/core-common\";\r\nimport { FeatureGraphicsRenderer, HitDetail, ImageryMapTileTree, MapCartoRectangle, MapFeatureInfoOptions, MapLayerFeatureInfo, MapLayerImageryProvider, QuadId, WGS84Extent } from \"@itwin/core-frontend\";\r\nimport { Matrix4d, Point3d, Range2d } from \"@itwin/core-geometry\";\r\nimport Geojson from \"geojson\";\r\nimport { ArcGisSymbologyCanvasRenderer } from \"../ArcGisFeature/ArcGisSymbologyRenderer.js\";\r\nimport { EsriPMS, EsriPMSProps, EsriRenderer, EsriSFS, EsriSFSProps, EsriSLS, EsriSLSProps, EsriSymbol } from \"../ArcGisFeature/EsriSymbology.js\";\r\nimport { DefaultMarkerIcon } from \"../Feature/DefaultMarkerIcon.js\";\r\nimport { FeatureCanvasRenderer } from \"../Feature/FeatureCanvasRenderer.js\";\r\nimport { FeatureDefaultSymbology } from \"../Feature/FeatureSymbology.js\";\r\nimport { RandomMapColor } from \"../Feature/RandomMapColor.js\";\r\nimport { OgcApiFeaturesReader } from \"./OgcApiFeaturesReader.js\";\r\n\r\nconst loggerCategory = \"MapLayersFormats.OgcApiFeatures\";\r\nconst dataUrlHeaderToken = \"base64,\";\r\n\r\n/** Provide tiles from a ESRI ArcGIS Feature service\r\n* @internal\r\n*/\r\nexport class DefaultOgcSymbology implements FeatureDefaultSymbology {\r\n\r\n private static readonly _defaultPMSProps: Omit<EsriPMSProps, \"imageData\" | \"contentType\"> = {\r\n type: \"esriPMS\",\r\n url: \"\",\r\n width: 16,\r\n height: 24,\r\n // We want the anchor point to be the bottom of the push pin, so apply offset on the y-axis (anchor point is already in the center of the icon)\r\n xoffset: 0,\r\n yoffset: -12,\r\n };\r\n private _defaultPMS: EsriPMS;\r\n\r\n private static readonly _defaultSLSProps: EsriSLSProps = {\r\n type: \"esriSLS\",\r\n color: [0, 0, 255, 255],\r\n width: 1,\r\n style: \"esriSLSSolid\",\r\n };\r\n private _defaultSLS: EsriSLS;\r\n\r\n private static readonly _defaultSFSProps: EsriSFSProps = {\r\n type: \"esriSFS\",\r\n color: [0, 0, 255, 255], // blue fill\r\n style: \"esriSFSSolid\",\r\n outline: DefaultOgcSymbology._defaultSLSProps,\r\n };\r\n private _defaultSFS = EsriSFS.fromJSON(DefaultOgcSymbology._defaultSFSProps);\r\n\r\n public constructor(randomColor?: RandomMapColor) {\r\n const color = randomColor ? randomColor.getColorDef() : ColorDef.blue;\r\n this._defaultPMS = EsriPMS.fromJSON( {\r\n ...DefaultMarkerIcon.getContent(color),\r\n type: \"esriPMS\",\r\n url: \"\",\r\n width: 16,\r\n height: 24,\r\n xoffset: 0,\r\n yoffset: -12,\r\n });\r\n\r\n const randomColors = color.colors;\r\n const newSLSProps = {\r\n ...DefaultOgcSymbology._defaultSLSProps,\r\n color: [randomColors.r, randomColors.g, randomColors.b, 255],\r\n };\r\n this._defaultSLS = EsriSLS.fromJSON(newSLSProps);\r\n this._defaultSFS = EsriSFS.fromJSON({\r\n ...DefaultOgcSymbology._defaultSFSProps,\r\n color: [randomColors.r, randomColors.g, randomColors.b, 255],\r\n outline: {\r\n ...DefaultOgcSymbology._defaultSLSProps,\r\n color: [0, 0, 0, 255],\r\n },\r\n });\r\n }\r\n\r\n public async initialize() {\r\n // Marker image need to be loaded upfront;\r\n await this._defaultPMS.loadImage();\r\n }\r\n\r\n public getSymbology(geometryType: string): EsriSymbol {\r\n if (geometryType === \"LineString\"|| geometryType === \"MultiLineString\" )\r\n return this._defaultSLS;\r\n else if (geometryType === \"Polygon\"|| geometryType === \"MultiPolygon\" )\r\n return this._defaultSFS;\r\n else if (geometryType === \"Point\"|| geometryType === \"MultiPoint\" )\r\n return this._defaultPMS;\r\n\r\n throw new Error(`Could not get default symbology for geometry type ${geometryType}`);\r\n }\r\n}\r\n/** @internal */\r\nexport class OgcApiFeaturesProvider extends MapLayerImageryProvider {\r\n\r\n // Debug flags, should always be committed to FALSE !\r\n private readonly _drawDebugInfo = false;\r\n /// ////////////////////////////\r\n\r\n private readonly _limitParamMaxValue = 10000; // This is documented in OGC Features specification; a single items request never returns more than 10 000 items\r\n private readonly _tiledModeMinLod = 14;\r\n private readonly _staticModeFetchTimeout = 10000;\r\n private readonly _tileModeFetchTimeout = 10000;\r\n private readonly _forceTileMode = false;\r\n private _spatialIdx: any;\r\n private _defaultSymbol = new DefaultOgcSymbology(new RandomMapColor());\r\n private _renderer: EsriRenderer|undefined;\r\n private _collectionUrl = \"\";\r\n private _itemsUrl = \"\";\r\n private readonly _itemsCrs = \"http://www.opengis.net/def/crs/OGC/1.3/CRS84\"; // Fixed fow now\r\n private _queryables: any;\r\n\r\n public serviceJson: any;\r\n private _staticData: Geojson.FeatureCollection|undefined;\r\n\r\n constructor(settings: ImageMapLayerSettings) {\r\n super(settings, true);\r\n }\r\n\r\n public override get supportsMapFeatureInfo() { return true;}\r\n public override get minimumZoomLevel(): number { return this.staticMode ? super.minimumZoomLevel : this._tiledModeMinLod; }\r\n public get staticMode(): boolean { return !!(this._spatialIdx && this._staticData && !this._forceTileMode); }\r\n\r\n public override async initialize(): Promise<void> {\r\n\r\n this._collectionUrl = this._settings.url;\r\n let layerId: SubLayerId|undefined;\r\n\r\n // OGC Feature service request can only serve data for a single feature\r\n // so if multiple sub-layer ids are specified, we pick the first one.\r\n if (this._settings.subLayers && this._settings.subLayers.length > 0) {\r\n layerId = this._settings.subLayers[0].id;\r\n }\r\n\r\n const readCollectionsPage = (data: any) => {\r\n const collection = data.collections.find((col: any)=> col.id === layerId);\r\n const collectionLinks = collection?.links;\r\n if (!collectionLinks) {\r\n const msg = `Missing layer id or matching collection could not be found`;\r\n Logger.logError(loggerCategory, msg);\r\n throw new Error(msg);\r\n }\r\n const collectionLink = collectionLinks.find((link: any)=> link.rel.includes(\"collection\") && link.type === \"application/json\",\r\n );\r\n this._collectionUrl = collectionLink.href;\r\n };\r\n\r\n const layerIdMismatch = () => {\r\n const msg = `Collection metadata and sub-layers id mismatch`;\r\n Logger.logError(loggerCategory, msg);\r\n throw new Error(msg);\r\n };\r\n let collectionMetadata: any;\r\n let json = await this.fetchMetadata(this._settings.url);\r\n if (json?.type === \"FeatureCollection\") {\r\n // We landed on the items page, we need to look for the collection metadata url\r\n if (Array.isArray(json.links)) {\r\n const collectionLink = json.links.find((link: any)=> link.rel.includes(\"collection\") && link.type === \"application/json\");\r\n this._collectionUrl = collectionLink.href;\r\n }\r\n } else if (json.itemType === \"feature\") {\r\n // We landed on a specific collection page.\r\n collectionMetadata = json;\r\n\r\n // Check if the collection id matches at least one sub-layer\r\n if (this._settings.subLayers && this._settings.subLayers.length > 0) {\r\n const subLayer = this._settings.subLayers.find((s)=>s.id === collectionMetadata.id);\r\n if (subLayer)\r\n layerId = subLayer.id;\r\n } else {\r\n // No sub-layers were specified, defaults to collection id.\r\n layerId = collectionMetadata.id;\r\n }\r\n\r\n } else if (Array.isArray(json.collections)) {\r\n // We landed in the \"Collections\" page\r\n // Find to find the specified layer id among the available collections\r\n readCollectionsPage(json);\r\n } else if (Array.isArray(json.links)) {\r\n // This might be the main landing page\r\n // We need to find the the \"Collections\" page\r\n const collectionsLink = json.links.find((link: any)=> link.rel.includes(\"data\") && link.type === \"application/json\");\r\n if (!collectionsLink) {\r\n Logger.logError(loggerCategory, \"Could not find collections link\");\r\n throw new ServerError(IModelStatus.ValidationFailed, \"\");\r\n }\r\n\r\n json = await this.fetchMetadata(collectionsLink.href);\r\n if (Array.isArray(json.collections)) {\r\n readCollectionsPage(json);\r\n }\r\n }\r\n\r\n // Read collection metadata\r\n if (!collectionMetadata)\r\n collectionMetadata = await this.fetchMetadata(this._collectionUrl);\r\n\r\n if (layerId !== undefined && layerId !== collectionMetadata.id) {\r\n layerIdMismatch();\r\n }\r\n\r\n // Read cartographic range\r\n if (Array.isArray(collectionMetadata?.extent?.spatial?.bbox)\r\n && collectionMetadata.extent.spatial.bbox.length > 0\r\n && collectionMetadata.extent.spatial.crs === this._itemsCrs\r\n ) {\r\n const firstBbox = collectionMetadata.extent.spatial?.bbox[0];\r\n this.cartoRange = MapCartoRectangle.fromDegrees(firstBbox[0], firstBbox[1], firstBbox[2], firstBbox[3]);\r\n }\r\n\r\n // Read important links\r\n let queryablesHref: string|undefined;\r\n let itemsHref: string|undefined;\r\n if (Array.isArray(collectionMetadata?.links)) {\r\n // Items links (Mandatory)\r\n const itemsLink = collectionMetadata.links.find((link: any)=> link.rel.includes(\"items\") && link.type === \"application/geo+json\");\r\n itemsHref = itemsLink.href;\r\n\r\n // Queryables link (Optional)\r\n const queryablesLink = collectionMetadata.links.find((link: any)=> link.rel.includes(\"queryables\") && link.type === \"application/schema+json\");\r\n queryablesHref = queryablesLink.href;\r\n\r\n }\r\n\r\n if (itemsHref)\r\n this._itemsUrl = itemsHref;\r\n else {\r\n const msg = \"Unable to find items link on collection\";\r\n Logger.logError(loggerCategory, msg);\r\n throw new Error(msg);\r\n }\r\n if (queryablesHref)\r\n this._queryables = await this.fetchMetadata(queryablesHref);\r\n\r\n if (!this._forceTileMode) {\r\n const status = await this.fetchAllItems();\r\n if (status) {\r\n await this.indexStaticData();\r\n }\r\n }\r\n\r\n await this._defaultSymbol.initialize(); // images must be loaded upfront\r\n }\r\n\r\n private async fetchMetadata(url: string): Promise<any> {\r\n const tmpUrl = this.appendCustomParams(url);\r\n const response = await this.makeRequest(tmpUrl);\r\n return response.json();\r\n }\r\n\r\n private async fetchAllItems() {\r\n const urlObj = new URL(this._itemsUrl);\r\n urlObj.searchParams.append(\"limit\", `${this._limitParamMaxValue}`);\r\n const url = this.appendCustomParams(urlObj.toString());\r\n this._staticData = await this.fetchItems(url, this._staticModeFetchTimeout);\r\n return this._staticData ? true : false;\r\n }\r\n\r\n private async fetchItems(url: string, timeout: number) {\r\n let data: any;\r\n let success = true;\r\n try {\r\n const fetchBegin = Date.now();\r\n let tmpUrl = this.appendCustomParams(url);\r\n let response = await this.makeTileRequest(tmpUrl, timeout);\r\n let json = await response.json();\r\n data = json;\r\n // Follow \"next\" link if any\r\n let nextLink = json.links?.find((link: any)=>link.rel === \"next\");\r\n while (nextLink && (Date.now() - fetchBegin) < timeout && success) {\r\n tmpUrl = this.appendCustomParams(nextLink.href);\r\n response = await this.makeTileRequest(tmpUrl, this._staticModeFetchTimeout);\r\n json = await response.json();\r\n if (json?.features)\r\n data.features = this._staticData?.features ? [...this._staticData.features, ...json.features] : json.features;\r\n else\r\n success = false;\r\n nextLink = json.links?.find((link: any)=>link.rel === \"next\");\r\n }\r\n if (Date.now() - fetchBegin >= this._staticModeFetchTimeout) {\r\n // We ran out of time, let switch to tile mode\r\n success = false;\r\n }\r\n } catch (e) {\r\n success = false;\r\n if (e instanceof DOMException && e.name === \"AbortError\") {\r\n Logger.logInfo(loggerCategory, \"Request to fetch all features time out, switching to tile mode.\");\r\n } else {\r\n Logger.logError(loggerCategory, \"Unknown error occurred when fetching OgcApiFeatures data.\");\r\n }\r\n }\r\n return success ? data : undefined;\r\n }\r\n\r\n // Read features range and build in-memory spatial index\r\n private async indexStaticData() {\r\n // UGLY IMPORT:\r\n // flatbush only provides ECM modules, and since mocha is not very good with ECM modules,\r\n // we need to have this special import, until we replace mocha with something else.\r\n const flatbush = (await import(\"flatbush\")).default;\r\n let success = true;\r\n try {\r\n const datasetRange = new Range2d();\r\n const buildPositionRange = (coords: Geojson.Position, range: Range2d) => range.extendXY(coords[0], coords[1]);\r\n const buildPositionArrayRange = (coords: Geojson.Position[], range: Range2d) => coords.forEach((position) => buildPositionRange(position, range) );\r\n const buildDoublePositionRange = (coords: Geojson.Position[][], range: Range2d) => coords.forEach((position) => buildPositionArrayRange(position, range) );\r\n const buildTriplePositionRange = (coords: Geojson.Position[][][], range: Range2d) => coords.forEach((position) => buildDoublePositionRange(position, range) );\r\n\r\n const readGeomRange = (geom: Geojson.Geometry, range: Range2d) => {\r\n if (geom.type === \"Point\")\r\n buildPositionRange(geom.coordinates, range);\r\n else if (geom.type === \"LineString\" || geom.type === \"MultiPoint\")\r\n buildPositionArrayRange(geom.coordinates, range);\r\n else if (geom.type === \"Polygon\" || geom.type === \"MultiLineString\")\r\n buildDoublePositionRange(geom.coordinates, range);\r\n else if (geom.type === \"MultiPolygon\" )\r\n buildTriplePositionRange(geom.coordinates, range);\r\n };\r\n\r\n if (this._staticData && Array.isArray(this._staticData.features)) {\r\n this._spatialIdx = new flatbush(this._staticData.features.length);\r\n this._staticData.features.forEach((feature: Geojson.Feature) => {\r\n try {\r\n if (feature.geometry.type === \"LineString\"\r\n || feature.geometry.type === \"MultiLineString\"\r\n || feature.geometry.type === \"Point\"\r\n || feature.geometry.type === \"MultiPoint\"\r\n || feature.geometry.type === \"Polygon\"\r\n || feature.geometry.type === \"MultiPolygon\"\r\n ) {\r\n readGeomRange(feature.geometry, datasetRange);\r\n this._spatialIdx?.add(datasetRange.xLow, datasetRange.yLow, datasetRange.xHigh,datasetRange. yHigh);\r\n datasetRange.setNull();\r\n } else if (feature.geometry.type === \"GeometryCollection\") {\r\n feature.geometry.geometries.forEach((geom) => {\r\n readGeomRange(geom, datasetRange);\r\n this._spatialIdx?.add(datasetRange.xLow, datasetRange.yLow, datasetRange.xHigh,datasetRange. yHigh);\r\n });\r\n datasetRange.setNull();\r\n }\r\n } catch (e: any) {\r\n Logger.logInfo(loggerCategory, `Unknown error occurred indexing feature: ${e.message}`);\r\n success = false;\r\n }\r\n });\r\n\r\n if (success) {\r\n this._spatialIdx.finish();\r\n }\r\n }\r\n\r\n } catch {\r\n Logger.logError(loggerCategory, \"Unknown error occurred when index static data\");\r\n success = false;\r\n }\r\n return success;\r\n }\r\n\r\n public override get tileSize(): number { return 512; }\r\n\r\n // We don't use this method inside this provider (see constructFeatureUrl), but since this is an abstract method, we need to define something\r\n public async constructUrl(_row: number, _column: number, _zoomLevel: number): Promise<string> {\r\n return \"\";\r\n }\r\n\r\n public drawTileDebugInfo(row: number, column: number, zoomLevel: number, context: CanvasRenderingContext2D) {\r\n context.fillStyle = \"cyan\";\r\n context.strokeRect(0, 0, this.tileSize, this.tileSize);\r\n context.font = \"30px Arial\";\r\n context.lineWidth = 5;\r\n context.fillText(`${zoomLevel}-${row}-${column}`, 10, 50);\r\n }\r\n\r\n // Compute transform that provides coordinates in the canvas coordinate system (pixels, origin = top-left)\r\n // from coordinate in world\r\n public computeTileWorld2CanvasTransform(row: number, column: number, zoomLevel: number) {\r\n\r\n const tileExtentWorld4326 = this.getEPSG4326Extent(row, column, zoomLevel);\r\n const worldTileWidth = tileExtentWorld4326.longitudeRight - tileExtentWorld4326.longitudeLeft;\r\n const worldTileHeight = tileExtentWorld4326.latitudeTop - tileExtentWorld4326.latitudeBottom;\r\n const canvasTileWidth = this.tileSize;\r\n const canvasTileHeight = this.tileSize;\r\n const world2CanvasRatioX = canvasTileWidth / worldTileWidth;\r\n const world2CanvasRatioY = canvasTileHeight / worldTileHeight;\r\n const worldTileOrigin = Point3d.create(tileExtentWorld4326.longitudeLeft, tileExtentWorld4326.latitudeBottom);\r\n const worldTileExtent = Point3d.create(tileExtentWorld4326.longitudeRight, tileExtentWorld4326.latitudeTop);\r\n const canvasTileOriginOffset = worldTileOrigin.clone();\r\n const canvasTileExtentOffset = worldTileExtent.clone();\r\n canvasTileOriginOffset.x *= world2CanvasRatioX;\r\n canvasTileOriginOffset.y *= world2CanvasRatioY;\r\n canvasTileExtentOffset.x *= world2CanvasRatioX;\r\n canvasTileExtentOffset.y *= world2CanvasRatioY;\r\n const xTranslate = -1 * canvasTileOriginOffset.x;\r\n\r\n // Canvas origin is upper left corner, so we need to flip the y axis\r\n const yTranslate = canvasTileExtentOffset.y; // y-axis flip\r\n const yWorld2CanvasRatio = -1 * world2CanvasRatioY; // y-axis flip\r\n\r\n const matrix = Matrix4d.createTranslationAndScaleXYZ(xTranslate, yTranslate, 0, world2CanvasRatioX, yWorld2CanvasRatio, 1);\r\n return matrix.asTransform;\r\n }\r\n\r\n public override async loadTile(row: number, column: number, zoomLevel: number): Promise<ImageSource | undefined> {\r\n\r\n const extent4326 = this.getEPSG4326Extent(row, column, zoomLevel);\r\n\r\n let data: any;\r\n if (this.staticMode) {\r\n // Static data mode\r\n const filteredData: Geojson.FeatureCollection = {type: \"FeatureCollection\", features: []};\r\n\r\n this._spatialIdx?.search(extent4326.longitudeLeft, extent4326.latitudeBottom, extent4326.longitudeRight, extent4326.latitudeTop,\r\n (index: number) => {\r\n filteredData.features.push(expectDefined(this._staticData).features[index]);\r\n return true;\r\n });\r\n\r\n data = filteredData;\r\n } else {\r\n // Tiled data mode\r\n const extent4326Str = this.getEPSG4326TileExtentString(row, column, zoomLevel, false);\r\n const urlObj = new URL(this._itemsUrl);\r\n urlObj.searchParams.append(\"bbox\", `${extent4326Str}`);\r\n urlObj.searchParams.append(\"bbox-crs\", this._itemsCrs);\r\n urlObj.searchParams.append(\"limit\", `${this._limitParamMaxValue}`);\r\n const url = this.appendCustomParams(urlObj.toString());\r\n\r\n try {\r\n data = await this.fetchItems(url, this._tileModeFetchTimeout);\r\n } catch {\r\n }\r\n if (!data) {\r\n Logger.logError(loggerCategory, \"Could not fetch OgcApiFeatures data.\");\r\n }\r\n }\r\n\r\n if (!data || !Array.isArray(data.features) || data.features.length === 0) {\r\n Logger.logInfo(loggerCategory, `No data to render for tile (${zoomLevel}/${row}/${column}).`);\r\n }\r\n\r\n // Rendering starts here\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.width = this.tileSize;\r\n canvas.height = this.tileSize;\r\n const ctx = canvas.getContext(\"2d\");\r\n if (ctx == null) {\r\n Logger.logError(loggerCategory, \"No canvas context available for loading tile.\");\r\n return undefined;\r\n }\r\n\r\n try {\r\n // Compute transform if CoordinatesQuantization is not supported by service\r\n const transfo = this.computeTileWorld2CanvasTransform(row, column, zoomLevel);\r\n if (!transfo) {\r\n Logger.logError(loggerCategory, `Could not compute data transformation for tile (${zoomLevel}/${row}/${column})`);\r\n }\r\n\r\n // Create the renderer\r\n\r\n // Instead of passing a Transform oject to the render, it should be possible\r\n // instead to set the Transform directly on the Canvas, when I tried the display was incorrect, floating point issue?\r\n // const transfoRow = transfo!.toRows();\r\n // ctx.setTransform(transfoRow[0][0], transfoRow[1][0], transfoRow[0][1], transfoRow[1][1], transfoRow[0][3], transfoRow[1][3]);\r\n const symbRenderer = ArcGisSymbologyCanvasRenderer.create(this._renderer, this._defaultSymbol);\r\n const renderer = new FeatureCanvasRenderer(ctx, symbRenderer, transfo);\r\n\r\n const featureReader = new OgcApiFeaturesReader();\r\n\r\n await featureReader.readAndRender(data, renderer);\r\n if (this._drawDebugInfo)\r\n this.drawTileDebugInfo(row, column, zoomLevel, ctx);\r\n } catch (e) {\r\n Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${e}`);\r\n }\r\n\r\n try {\r\n return this.createImageSourceFromDataURL(canvas.toDataURL(\"image/png\"), ImageSourceFormat.Png);\r\n } catch (e) {\r\n Logger.logError(loggerCategory, `Exception occurred while rendering tile (${zoomLevel}/${row}/${column}) : ${e}.`);\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private createImageSourceFromDataURL(dataUrl: string, format: ImageSourceFormat) {\r\n if (!dataUrl)\r\n return undefined;\r\n\r\n const dataStartPos = dataUrl.indexOf(dataUrlHeaderToken) + dataUrlHeaderToken.length;\r\n\r\n if (dataStartPos < 0)\r\n return undefined;\r\n\r\n const base64Png = dataUrl.substring(dataStartPos);\r\n return new ImageSource(base64StringToUint8Array(base64Png), format);\r\n }\r\n\r\n public override async getFeatureInfo(featureInfos: MapLayerFeatureInfo[], quadId: QuadId, carto: Cartographic, _tree: ImageryMapTileTree, hit: HitDetail, options?: MapFeatureInfoOptions): Promise<void> {\r\n const tileExtent = this.getEPSG4326Extent(quadId.row, quadId.column, quadId.level);\r\n const tilePixelSizeX = (tileExtent.longitudeRight - tileExtent.longitudeLeft) / this.tileSize;\r\n const tilePixelSizeY = (tileExtent.latitudeTop - tileExtent.latitudeBottom) / this.tileSize;\r\n const tolerancePixel = options?.tolerance ?? 7;\r\n const toleranceWorldX = tilePixelSizeX * tolerancePixel;\r\n const toleranceWorldY = tilePixelSizeY * tolerancePixel;\r\n\r\n // Note: We used to pass a single point as the query 'geometry' and leverage the 'distance' parameter, turns\r\n // out that approach was a lot slower on some server compared to using a single envelope.\r\n const bbox: WGS84Extent = {\r\n longitudeLeft: carto.longitudeDegrees - toleranceWorldX, latitudeBottom: carto.latitudeDegrees - toleranceWorldY,\r\n longitudeRight: carto.longitudeDegrees + toleranceWorldX, latitudeTop: carto.latitudeDegrees + toleranceWorldY,\r\n };\r\n\r\n const bboxStr = this.getEPSG4326ExtentString(bbox, false);\r\n const urlObj = new URL(this._itemsUrl);\r\n urlObj.searchParams.append(\"bbox\", `${bboxStr}`);\r\n urlObj.searchParams.append(\"bbox-crs\", this._itemsCrs);\r\n urlObj.searchParams.append(\"limit\", `${this._limitParamMaxValue}`);\r\n const url = this.appendCustomParams(urlObj.toString());\r\n\r\n let data: any;\r\n try {\r\n data = await this.fetchItems(url, this._tileModeFetchTimeout);\r\n } catch {\r\n }\r\n if (!data) {\r\n Logger.logError(loggerCategory, \"Could not fetch OgcApiFeatures data.\");\r\n }\r\n\r\n const featureReader = new OgcApiFeaturesReader();\r\n await featureReader.readFeatureInfo({\r\n collection:data,\r\n layerSettings: this._settings,\r\n queryables: this._queryables,\r\n geomRenderer: new FeatureGraphicsRenderer({viewport: hit.viewport, crs: \"wgs84\"})},\r\n featureInfos );\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"OgcApiFeaturesProvider.js","sourceRoot":"","sources":["../../../src/OgcApiFeatures/OgcApiFeaturesProvider.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F,sDAAkH;AAClH,oDAA4I;AAC5I,wDAA2M;AAC3M,wDAAkE;AAElE,4FAA4F;AAC5F,wEAAkJ;AAClJ,0EAAoE;AACpE,kFAA4E;AAE5E,oEAA8D;AAC9D,uEAAiE;AAEjE,MAAM,cAAc,GAAG,iCAAiC,CAAC;AACzD,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAErC;;EAEE;AACF,MAAa,mBAAmB;IAEtB,MAAM,CAAU,gBAAgB,GAAoD;QAC1F,IAAI,EAAE,SAAS;QACf,GAAG,EAAE,EAAE;QACP,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,EAAE;QACV,+IAA+I;QAC/I,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC,EAAE;KACb,CAAC;IACM,WAAW,CAAU;IAErB,MAAM,CAAU,gBAAgB,GAAiB;QACvD,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC;QACvB,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,cAAc;KACtB,CAAC;IACM,WAAW,CAAU;IAErB,MAAM,CAAU,gBAAgB,GAAiB;QACvD,IAAI,EAAE,SAAS;QACf,KAAK,EAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAI,YAAY;QACxC,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,mBAAmB,CAAC,gBAAgB;KAC9C,CAAC;IACM,WAAW,GAAG,0BAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAE7E,YAAmB,WAA4B;QAC7C,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,sBAAQ,CAAC,IAAI,CAAC;QACtE,IAAI,CAAC,WAAW,GAAG,0BAAO,CAAC,QAAQ,CAAE;YACnC,GAAG,wCAAiB,CAAC,UAAU,CAAC,KAAK,CAAC;YACtC,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,EAAE;YACP,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC,EAAE;SACb,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;QAClC,MAAM,WAAW,GAAG;YAClB,GAAG,mBAAmB,CAAC,gBAAgB;YACvC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC;SAC7D,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,0BAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,CAAC,WAAW,GAAG,0BAAO,CAAC,QAAQ,CAAC;YAClC,GAAG,mBAAmB,CAAC,gBAAgB;YACvC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC;YAC5D,OAAO,EAAE;gBACP,GAAG,mBAAmB,CAAC,gBAAgB;gBACvC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC;aACtB;SACF,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,UAAU;QACrB,0CAA0C;QAC1C,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;IACrC,CAAC;IAEM,YAAY,CAAC,YAAoB;QACtC,IAAI,YAAY,KAAK,YAAY,IAAG,YAAY,KAAK,iBAAiB;YACpE,OAAO,IAAI,CAAC,WAAW,CAAC;aACrB,IAAI,YAAY,KAAK,SAAS,IAAG,YAAY,KAAK,cAAc;YACnE,OAAO,IAAI,CAAC,WAAW,CAAC;aACrB,IAAI,YAAY,KAAK,OAAO,IAAG,YAAY,KAAK,YAAY;YAC/D,OAAO,IAAI,CAAC,WAAW,CAAC;QAE1B,MAAM,IAAI,KAAK,CAAC,qDAAqD,YAAY,EAAE,CAAC,CAAC;IACvF,CAAC;;AAvEH,kDAwEC;AACD,gBAAgB;AAChB,MAAa,sBAAuB,SAAQ,uCAAuB;IAEjE,qDAAqD;IACpC,cAAc,GAAG,KAAK,CAAC;IACxC,gCAAgC;IAEf,mBAAmB,GAAG,KAAK,CAAC,CAAC,gHAAgH;IAC7I,gBAAgB,GAAG,EAAE,CAAC;IACtB,uBAAuB,GAAG,KAAK,CAAC;IAChC,qBAAqB,GAAG,KAAK,CAAC;IAC9B,cAAc,GAAG,KAAK,CAAC;IAChC,WAAW,CAAM;IACjB,cAAc,GAAG,IAAI,mBAAmB,CAAC,IAAI,kCAAc,EAAE,CAAC,CAAC;IAC/D,SAAS,CAAyB;IAClC,cAAc,GAAG,EAAE,CAAC;IACpB,SAAS,GAAG,EAAE,CAAC;IACN,SAAS,GAAG,8CAA8C,CAAC,CAAG,gBAAgB;IACvF,WAAW,CAAM;IAElB,WAAW,CAAM;IAChB,WAAW,CAAsC;IAEzD,YAAY,QAA+B;QACzC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,IAAoB,sBAAsB,KAAK,OAAO,IAAI,CAAC,CAAA,CAAC;IAC5D,IAAoB,gBAAgB,KAAa,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC3H,IAAW,UAAU,KAAc,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAE7F,KAAK,CAAC,UAAU;QAE9B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QACzC,IAAI,OAA6B,CAAC;QAElC,uEAAuE;QACvE,qEAAqE;QACrE,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,CAAC;QAED,MAAM,mBAAmB,GAAG,CAAC,IAAS,EAAE,OAAe,EAAE,EAAE;YACzD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;YAC1E,MAAM,eAAe,GAAG,UAAU,EAAE,KAAK,CAAC;YAC1C,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,MAAM,GAAG,GAAG,4DAA4D,CAAC;gBACzE,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAC5H,CAAC;YACF,IAAI,CAAC,cAAc,GAAI,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC1E,CAAC,CAAC;QAEF,MAAM,eAAe,GAAG,GAAG,EAAE;YAC3B,MAAM,GAAG,GAAG,gDAAgD,CAAC;YAC7D,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,IAAI,kBAAuB,CAAC;QAC5B,IAAI,qBAAqB,GAAW,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QACvD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC5G,IAAI,IAAI,GAAG,WAAW,CAAC;QACvB,IAAI,IAAI,EAAE,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACvC,+EAA+E;YAC/E,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;gBAC1H,IAAI,CAAC,cAAc,GAAI,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC;YACrF,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACvC,2CAA2C;YAC3C,kBAAkB,GAAG,IAAI,CAAC;YAC1B,qBAAqB,GAAG,kBAAkB,CAAC;YAE3C,4DAA4D;YAC5D,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,EAAE,CAAA,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,EAAE,CAAC,CAAC;gBACpF,IAAI,QAAQ;oBACV,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,2DAA2D;gBAC3D,OAAO,GAAG,kBAAkB,CAAC,EAAE,CAAC;YAClC,CAAC;QAEH,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,sCAAsC;YACtC,sEAAsE;YACtE,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;QAChD,CAAC;aAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,sCAAsC;YACtC,6CAA6C;YAC7C,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;YACrH,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;gBACnE,MAAM,IAAI,yBAAW,CAAC,2BAAY,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC;YACrF,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;YACpE,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC;YAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpC,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,qBAAqB,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QACrH,CAAC;QAED,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,kBAAkB,CAAC,EAAE,EAAE,CAAC;YAC/D,eAAe,EAAE,CAAC;QACpB,CAAC;QAED,0BAA0B;QAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;eACzD,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;eACjD,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,SAAS,EACzD,CAAC;YACD,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,UAAU,GAAG,iCAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1G,CAAC;QAED,uBAAuB;QACvB,IAAI,cAAgC,CAAC;QACrC,IAAI,SAA2B,CAAC;QAChC,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC;YAC7C,0BAA0B;YAC1B,MAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,sBAAsB,CAAC,CAAC;YAClI,SAAS,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC,QAAQ,EAAE,CAAC;YAEtE,6BAA6B;YAC7B,MAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,yBAAyB,CAAC,CAAC;YAC/I,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAE/G,CAAC;QAED,IAAI,SAAS;YACX,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;aACxB,CAAC;YACJ,MAAM,GAAG,GAAG,yCAAyC,CAAC;YACtD,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,cAAc;YAChB,IAAI,CAAC,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;QAErE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,gCAAgC;IAC1E,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,GAAW;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,IAAI,MAAM,EAAE,CAAC;IACvD,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACzC,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,GAAW,EAAE,OAAe;QACnD,IAAI,IAAS,CAAC;QACd,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC9B,IAAI,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC3D,IAAI,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,GAAG,IAAI,CAAC;YACZ,gFAAgF;YAChF,IAAI,eAAe,GAAG,QAAQ,CAAC,GAAG,IAAI,MAAM,CAAC;YAC7C,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAA,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;YAClE,OAAO,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,OAAO,IAAI,OAAO,EAAE,CAAC;gBAClE,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACrF,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBAC5E,eAAe,GAAG,QAAQ,CAAC,GAAG,IAAI,MAAM,CAAC;gBACzC,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC7B,IAAI,IAAI,EAAE,QAAQ;oBAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;;oBAE9G,OAAO,GAAG,KAAK,CAAC;gBAClB,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAS,EAAC,EAAE,CAAA,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBAC5D,8CAA8C;gBAC9C,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAG,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,IAAI,CAAC,YAAY,YAAY,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACzD,qBAAM,CAAC,OAAO,CAAC,cAAc,EAAE,iEAAiE,CAAC,CAAC;YACpG,CAAC;iBAAM,CAAC;gBACN,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,2DAA2D,CAAC,CAAC;YAC/F,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACpC,CAAC;IAED,wDAAwD;IAChD,KAAK,CAAC,eAAe;QAC3B,gBAAgB;QAChB,yFAAyF;QACzF,mFAAmF;QACnF,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QACpD,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,uBAAO,EAAE,CAAC;YACnC,MAAM,kBAAkB,GAAG,CAAC,MAAwB,EAAE,KAAc,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9G,MAAM,uBAAuB,GAAG,CAAC,MAA0B,EAAE,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAE,CAAC;YACnJ,MAAM,wBAAwB,GAAG,CAAC,MAA4B,EAAE,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,uBAAuB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAE,CAAC;YAC3J,MAAM,wBAAwB,GAAG,CAAC,MAA8B,EAAE,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAE,CAAC;YAE9J,MAAM,aAAa,GAAG,CAAC,IAAsB,EAAE,KAAc,EAAE,EAAE;gBAC/D,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;oBACvB,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;qBACzC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;oBAC/D,uBAAuB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;qBAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB;oBACjE,wBAAwB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;qBAC/C,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;oBACnC,wBAAwB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC,CAAC;YAEF,IAAI,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjE,IAAI,CAAC,WAAW,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAClE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAwB,EAAE,EAAE;oBAC7D,IAAI,CAAC;wBACH,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;+BACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,iBAAiB;+BAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,OAAO;+BACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;+BACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;+BACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,EACzC,CAAC;4BACD,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;4BAC9C,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,EAAC,YAAY,CAAE,KAAK,CAAC,CAAC;4BACpG,YAAY,CAAC,OAAO,EAAE,CAAC;wBACzB,CAAC;6BAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;4BAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gCAC3C,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;gCAClC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,EAAC,YAAY,CAAE,KAAK,CAAC,CAAC;4BACtG,CAAC,CAAC,CAAC;4BACH,YAAY,CAAC,OAAO,EAAE,CAAC;wBACzB,CAAC;oBACH,CAAC;oBAAC,OAAO,CAAM,EAAG,CAAC;wBACjB,qBAAM,CAAC,OAAO,CAAC,cAAc,EAAE,4CAA4C,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;wBACxF,OAAO,GAAG,KAAK,CAAC;oBAClB,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;gBAC5B,CAAC;YACH,CAAC;QAEH,CAAC;QAAC,MAAM,CAAC;YACP,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,+CAA+C,CAAC,CAAC;YACjF,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAoB,QAAQ,KAAa,OAAO,GAAG,CAAC,CAAC,CAAC;IAEtD,6IAA6I;IACtI,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,OAAe,EAAE,UAAkB;QACzE,OAAO,EAAE,CAAC;IACZ,CAAC;IAEM,iBAAiB,CAAC,GAAW,EAAE,MAAc,EAAE,SAAiB,EAAE,OAAiC;QACxG,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;QAC3B,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;QAC5B,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,SAAS,IAAI,GAAG,IAAI,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,0GAA0G;IAC1G,2BAA2B;IACpB,gCAAgC,CAAC,GAAW,EAAE,MAAc,EAAE,SAAiB;QAEpF,MAAM,mBAAmB,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3E,MAAM,cAAc,GAAG,mBAAmB,CAAC,cAAc,GAAG,mBAAmB,CAAC,aAAa,CAAC;QAC9F,MAAM,eAAe,GAAG,mBAAmB,CAAC,WAAW,GAAG,mBAAmB,CAAC,cAAc,CAAC;QAC7F,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC;QACtC,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC;QACvC,MAAM,kBAAkB,GAAG,eAAe,GAAG,cAAc,CAAC;QAC5D,MAAM,kBAAkB,GAAG,gBAAgB,GAAG,eAAe,CAAC;QAC9D,MAAM,eAAe,GAAG,uBAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAC;QAC9G,MAAM,eAAe,GAAG,uBAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAC5G,MAAM,sBAAsB,GAAG,eAAe,CAAC,KAAK,EAAE,CAAC;QACvD,MAAM,sBAAsB,GAAG,eAAe,CAAC,KAAK,EAAE,CAAC;QACvD,sBAAsB,CAAC,CAAC,IAAI,kBAAkB,CAAC;QAC/C,sBAAsB,CAAC,CAAC,IAAI,kBAAkB,CAAC;QAC/C,sBAAsB,CAAC,CAAC,IAAI,kBAAkB,CAAC;QAC/C,sBAAsB,CAAC,CAAC,IAAI,kBAAkB,CAAC;QAC/C,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC;QAEjD,oEAAoE;QACpE,MAAM,UAAU,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAK,cAAc;QAC/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,cAAc;QAElE,MAAM,MAAM,GAAG,wBAAQ,CAAC,4BAA4B,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;QAC3H,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IAEe,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,MAAc,EAAE,SAAiB;QAE3E,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAElE,IAAI,IAAS,CAAC;QACd,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,mBAAmB;YACnB,MAAM,YAAY,GAA8B,EAAC,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,EAAE,EAAC,CAAC;YAE1F,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,UAAU,CAAC,cAAc,EAAE,UAAU,CAAC,cAAc,EAAE,UAAU,CAAC,WAAW,EAC7H,CAAC,KAAa,EAAE,EAAE;gBAChB,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,4BAAa,EAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC5E,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YAEL,IAAI,GAAG,YAAY,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,kBAAkB;YAClB,MAAM,aAAa,GAAG,IAAI,CAAC,2BAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACtF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,aAAa,EAAE,CAAC,CAAC;YACvD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACvD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;YACnE,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YAEvD,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAChE,CAAC;YAAC,MAAM,CAAC;YACT,CAAC;YACD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,sCAAsC,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzE,qBAAM,CAAC,OAAO,CAAC,cAAc,EAAE,+BAA+B,SAAS,IAAI,GAAG,IAAI,MAAM,IAAI,CAAC,CAAC;QAChG,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7B,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,+CAA+C,CAAC,CAAC;YACjF,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,CAAC;YACH,2EAA2E;YAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,gCAAgC,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YAC9E,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,mDAAmD,SAAS,IAAI,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC;YACpH,CAAC;YAED,sBAAsB;YAEtB,4EAA4E;YAC5E,qHAAqH;YACrH,wCAAwC;YACxC,gIAAgI;YAChI,MAAM,YAAY,GAAG,0DAA6B,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC/F,MAAM,QAAQ,GAAG,IAAI,gDAAqB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;YAEvE,MAAM,aAAa,GAAI,IAAI,8CAAoB,EAAE,CAAC;YAElD,MAAM,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAClD,IAAI,IAAI,CAAC,cAAc;gBACrB,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,0CAA0C,SAAS,IAAI,GAAG,IAAI,MAAM,OAAO,2BAAY,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChJ,CAAC;QAED,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,4BAA4B,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,+BAAiB,CAAC,GAAG,CAAC,CAAC;QACjG,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,4CAA4C,SAAS,IAAI,GAAG,IAAI,MAAM,OAAO,2BAAY,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClJ,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,4BAA4B,CAAC,OAAe,EAAE,MAAyB;QAC7E,IAAI,CAAC,OAAO;YACV,OAAO,SAAS,CAAC;QAEnB,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC;QAErF,IAAI,YAAY,GAAG,CAAC;YAClB,OAAO,SAAS,CAAC;QAEnB,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAClD,OAAO,IAAI,yBAAW,CAAC,IAAA,uCAAwB,EAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;IAEe,KAAK,CAAC,cAAc,CAAC,YAAmC,EAAE,MAAc,EAAE,KAAmB,EAAE,KAAyB,EAAE,GAAc,EAAE,OAA+B;QACvL,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACnF,MAAM,cAAc,GAAG,CAAC,UAAU,CAAC,cAAc,GAAG,UAAU,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9F,MAAM,cAAc,GAAG,CAAC,UAAU,CAAC,WAAW,GAAG,UAAU,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5F,MAAM,cAAc,GAAG,OAAO,EAAE,SAAS,IAAI,CAAC,CAAC;QAC/C,MAAM,eAAe,GAAG,cAAc,GAAG,cAAc,CAAC;QACxD,MAAM,eAAe,GAAG,cAAc,GAAG,cAAc,CAAC;QAExD,4GAA4G;QAC5G,yFAAyF;QACzF,MAAM,IAAI,GAAgB;YACxB,aAAa,EAAE,KAAK,CAAC,gBAAgB,GAAG,eAAe,EAAE,cAAc,EAAE,KAAK,CAAC,eAAe,GAAG,eAAe;YAChH,cAAc,EAAE,KAAK,CAAC,gBAAgB,GAAG,eAAe,EAAE,WAAW,EAAE,KAAK,CAAC,eAAe,GAAG,eAAe;SAC/G,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACvD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEvD,IAAI,IAAS,CAAC;QACd,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;QACT,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,sCAAsC,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,8CAAoB,EAAE,CAAC;QACjD,MAAM,aAAa,CAAC,eAAe,CAAC;YAClC,UAAU,EAAC,IAAI;YACf,aAAa,EAAE,IAAI,CAAC,SAAS;YAC7B,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,YAAY,EAAE,IAAI,uCAAuB,CAAC,EAAC,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAC,CAAC;SAAC,EACpF,YAAY,CAAE,CAAC;IACjB,CAAC;CACF;AApcD,wDAocC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { base64StringToUint8Array, BentleyError, expectDefined, IModelStatus, Logger } from \"@itwin/core-bentley\";\r\nimport { Cartographic, ColorDef, ImageMapLayerSettings, ImageSource, ImageSourceFormat, ServerError, SubLayerId } from \"@itwin/core-common\";\r\nimport { FeatureGraphicsRenderer, HitDetail, ImageryMapTileTree, MapCartoRectangle, MapFeatureInfoOptions, MapLayerFeatureInfo, MapLayerImageryProvider, QuadId, WGS84Extent } from \"@itwin/core-frontend\";\r\nimport { Matrix4d, Point3d, Range2d } from \"@itwin/core-geometry\";\r\nimport Geojson from \"geojson\";\r\nimport { ArcGisSymbologyCanvasRenderer } from \"../ArcGisFeature/ArcGisSymbologyRenderer.js\";\r\nimport { EsriPMS, EsriPMSProps, EsriRenderer, EsriSFS, EsriSFSProps, EsriSLS, EsriSLSProps, EsriSymbol } from \"../ArcGisFeature/EsriSymbology.js\";\r\nimport { DefaultMarkerIcon } from \"../Feature/DefaultMarkerIcon.js\";\r\nimport { FeatureCanvasRenderer } from \"../Feature/FeatureCanvasRenderer.js\";\r\nimport { FeatureDefaultSymbology } from \"../Feature/FeatureSymbology.js\";\r\nimport { RandomMapColor } from \"../Feature/RandomMapColor.js\";\r\nimport { OgcApiFeaturesReader } from \"./OgcApiFeaturesReader.js\";\r\n\r\nconst loggerCategory = \"MapLayersFormats.OgcApiFeatures\";\r\nconst dataUrlHeaderToken = \"base64,\";\r\n\r\n/** Provide tiles from a ESRI ArcGIS Feature service\r\n* @internal\r\n*/\r\nexport class DefaultOgcSymbology implements FeatureDefaultSymbology {\r\n\r\n private static readonly _defaultPMSProps: Omit<EsriPMSProps, \"imageData\" | \"contentType\"> = {\r\n type: \"esriPMS\",\r\n url: \"\",\r\n width: 16,\r\n height: 24,\r\n // We want the anchor point to be the bottom of the push pin, so apply offset on the y-axis (anchor point is already in the center of the icon)\r\n xoffset: 0,\r\n yoffset: -12,\r\n };\r\n private _defaultPMS: EsriPMS;\r\n\r\n private static readonly _defaultSLSProps: EsriSLSProps = {\r\n type: \"esriSLS\",\r\n color: [0, 0, 255, 255],\r\n width: 1,\r\n style: \"esriSLSSolid\",\r\n };\r\n private _defaultSLS: EsriSLS;\r\n\r\n private static readonly _defaultSFSProps: EsriSFSProps = {\r\n type: \"esriSFS\",\r\n color: [0, 0, 255, 255], // blue fill\r\n style: \"esriSFSSolid\",\r\n outline: DefaultOgcSymbology._defaultSLSProps,\r\n };\r\n private _defaultSFS = EsriSFS.fromJSON(DefaultOgcSymbology._defaultSFSProps);\r\n\r\n public constructor(randomColor?: RandomMapColor) {\r\n const color = randomColor ? randomColor.getColorDef() : ColorDef.blue;\r\n this._defaultPMS = EsriPMS.fromJSON( {\r\n ...DefaultMarkerIcon.getContent(color),\r\n type: \"esriPMS\",\r\n url: \"\",\r\n width: 16,\r\n height: 24,\r\n xoffset: 0,\r\n yoffset: -12,\r\n });\r\n\r\n const randomColors = color.colors;\r\n const newSLSProps = {\r\n ...DefaultOgcSymbology._defaultSLSProps,\r\n color: [randomColors.r, randomColors.g, randomColors.b, 255],\r\n };\r\n this._defaultSLS = EsriSLS.fromJSON(newSLSProps);\r\n this._defaultSFS = EsriSFS.fromJSON({\r\n ...DefaultOgcSymbology._defaultSFSProps,\r\n color: [randomColors.r, randomColors.g, randomColors.b, 255],\r\n outline: {\r\n ...DefaultOgcSymbology._defaultSLSProps,\r\n color: [0, 0, 0, 255],\r\n },\r\n });\r\n }\r\n\r\n public async initialize() {\r\n // Marker image need to be loaded upfront;\r\n await this._defaultPMS.loadImage();\r\n }\r\n\r\n public getSymbology(geometryType: string): EsriSymbol {\r\n if (geometryType === \"LineString\"|| geometryType === \"MultiLineString\" )\r\n return this._defaultSLS;\r\n else if (geometryType === \"Polygon\"|| geometryType === \"MultiPolygon\" )\r\n return this._defaultSFS;\r\n else if (geometryType === \"Point\"|| geometryType === \"MultiPoint\" )\r\n return this._defaultPMS;\r\n\r\n throw new Error(`Could not get default symbology for geometry type ${geometryType}`);\r\n }\r\n}\r\n/** @internal */\r\nexport class OgcApiFeaturesProvider extends MapLayerImageryProvider {\r\n\r\n // Debug flags, should always be committed to FALSE !\r\n private readonly _drawDebugInfo = false;\r\n /// ////////////////////////////\r\n\r\n private readonly _limitParamMaxValue = 10000; // This is documented in OGC Features specification; a single items request never returns more than 10 000 items\r\n private readonly _tiledModeMinLod = 14;\r\n private readonly _staticModeFetchTimeout = 10000;\r\n private readonly _tileModeFetchTimeout = 10000;\r\n private readonly _forceTileMode = false;\r\n private _spatialIdx: any;\r\n private _defaultSymbol = new DefaultOgcSymbology(new RandomMapColor());\r\n private _renderer: EsriRenderer|undefined;\r\n private _collectionUrl = \"\";\r\n private _itemsUrl = \"\";\r\n private readonly _itemsCrs = \"http://www.opengis.net/def/crs/OGC/1.3/CRS84\"; // Fixed fow now\r\n private _queryables: any;\r\n\r\n public serviceJson: any;\r\n private _staticData: Geojson.FeatureCollection|undefined;\r\n\r\n constructor(settings: ImageMapLayerSettings) {\r\n super(settings, true);\r\n }\r\n\r\n public override get supportsMapFeatureInfo() { return true;}\r\n public override get minimumZoomLevel(): number { return this.staticMode ? super.minimumZoomLevel : this._tiledModeMinLod; }\r\n public get staticMode(): boolean { return !!(this._spatialIdx && this._staticData && !this._forceTileMode); }\r\n\r\n public override async initialize(): Promise<void> {\r\n\r\n this._collectionUrl = this._settings.url;\r\n let layerId: SubLayerId|undefined;\r\n\r\n // OGC Feature service request can only serve data for a single feature\r\n // so if multiple sub-layer ids are specified, we pick the first one.\r\n if (this._settings.subLayers && this._settings.subLayers.length > 0) {\r\n layerId = this._settings.subLayers[0].id;\r\n }\r\n\r\n const readCollectionsPage = (data: any, baseUrl: string) => {\r\n const collection = data.collections.find((col: any)=> col.id === layerId);\r\n const collectionLinks = collection?.links;\r\n if (!collectionLinks) {\r\n const msg = `Missing layer id or matching collection could not be found`;\r\n Logger.logError(loggerCategory, msg);\r\n throw new Error(msg);\r\n }\r\n const collectionLink = collectionLinks.find((link: any)=> link.rel.includes(\"collection\") && link.type === \"application/json\",\r\n );\r\n this._collectionUrl = new URL(collectionLink.href, baseUrl).toString();\r\n };\r\n\r\n const layerIdMismatch = () => {\r\n const msg = `Collection metadata and sub-layers id mismatch`;\r\n Logger.logError(loggerCategory, msg);\r\n throw new Error(msg);\r\n };\r\n let collectionMetadata: any;\r\n let collectionResponseUrl: string = this._settings.url;\r\n const { json: initialJson, responseUrl: initialResponseUrl } = await this.fetchMetadata(this._settings.url);\r\n let json = initialJson;\r\n if (json?.type === \"FeatureCollection\") {\r\n // We landed on the items page, we need to look for the collection metadata url\r\n if (Array.isArray(json.links)) {\r\n const collectionLink = json.links.find((link: any)=> link.rel.includes(\"collection\") && link.type === \"application/json\");\r\n this._collectionUrl = new URL(collectionLink.href, initialResponseUrl).toString();\r\n }\r\n } else if (json.itemType === \"feature\") {\r\n // We landed on a specific collection page.\r\n collectionMetadata = json;\r\n collectionResponseUrl = initialResponseUrl;\r\n\r\n // Check if the collection id matches at least one sub-layer\r\n if (this._settings.subLayers && this._settings.subLayers.length > 0) {\r\n const subLayer = this._settings.subLayers.find((s)=>s.id === collectionMetadata.id);\r\n if (subLayer)\r\n layerId = subLayer.id;\r\n } else {\r\n // No sub-layers were specified, defaults to collection id.\r\n layerId = collectionMetadata.id;\r\n }\r\n\r\n } else if (Array.isArray(json.collections)) {\r\n // We landed in the \"Collections\" page\r\n // Find to find the specified layer id among the available collections\r\n readCollectionsPage(json, initialResponseUrl);\r\n } else if (Array.isArray(json.links)) {\r\n // This might be the main landing page\r\n // We need to find the the \"Collections\" page\r\n const collectionsLink = json.links.find((link: any)=> link.rel.includes(\"data\") && link.type === \"application/json\");\r\n if (!collectionsLink) {\r\n Logger.logError(loggerCategory, \"Could not find collections link\");\r\n throw new ServerError(IModelStatus.ValidationFailed, \"\");\r\n }\r\n\r\n const collectionsHref = new URL(collectionsLink.href, initialResponseUrl).toString();\r\n const collectionsResult = await this.fetchMetadata(collectionsHref);\r\n json = collectionsResult.json;\r\n if (Array.isArray(json.collections)) {\r\n readCollectionsPage(json, collectionsResult.responseUrl);\r\n }\r\n }\r\n\r\n // Read collection metadata\r\n if (!collectionMetadata) {\r\n ({ json: collectionMetadata, responseUrl: collectionResponseUrl } = await this.fetchMetadata(this._collectionUrl));\r\n }\r\n\r\n if (layerId !== undefined && layerId !== collectionMetadata.id) {\r\n layerIdMismatch();\r\n }\r\n\r\n // Read cartographic range\r\n if (Array.isArray(collectionMetadata?.extent?.spatial?.bbox)\r\n && collectionMetadata.extent.spatial.bbox.length > 0\r\n && collectionMetadata.extent.spatial.crs === this._itemsCrs\r\n ) {\r\n const firstBbox = collectionMetadata.extent.spatial?.bbox[0];\r\n this.cartoRange = MapCartoRectangle.fromDegrees(firstBbox[0], firstBbox[1], firstBbox[2], firstBbox[3]);\r\n }\r\n\r\n // Read important links\r\n let queryablesHref: string|undefined;\r\n let itemsHref: string|undefined;\r\n if (Array.isArray(collectionMetadata?.links)) {\r\n // Items links (Mandatory)\r\n const itemsLink = collectionMetadata.links.find((link: any)=> link.rel.includes(\"items\") && link.type === \"application/geo+json\");\r\n itemsHref = new URL(itemsLink.href, collectionResponseUrl).toString();\r\n\r\n // Queryables link (Optional)\r\n const queryablesLink = collectionMetadata.links.find((link: any)=> link.rel.includes(\"queryables\") && link.type === \"application/schema+json\");\r\n queryablesHref = queryablesLink ? new URL(queryablesLink.href, collectionResponseUrl).toString() : undefined;\r\n\r\n }\r\n\r\n if (itemsHref)\r\n this._itemsUrl = itemsHref;\r\n else {\r\n const msg = \"Unable to find items link on collection\";\r\n Logger.logError(loggerCategory, msg);\r\n throw new Error(msg);\r\n }\r\n if (queryablesHref)\r\n this._queryables = (await this.fetchMetadata(queryablesHref)).json;\r\n\r\n if (!this._forceTileMode) {\r\n const status = await this.fetchAllItems();\r\n if (status) {\r\n await this.indexStaticData();\r\n }\r\n }\r\n\r\n await this._defaultSymbol.initialize(); // images must be loaded upfront\r\n }\r\n\r\n private async fetchMetadata(url: string): Promise<{ json: any; responseUrl: string }> {\r\n const tmpUrl = this.appendCustomParams(url);\r\n const response = await this.makeRequest(tmpUrl);\r\n const json = await response.json();\r\n return { json, responseUrl: response.url || tmpUrl };\r\n }\r\n\r\n private async fetchAllItems() {\r\n const urlObj = new URL(this._itemsUrl);\r\n urlObj.searchParams.append(\"limit\", `${this._limitParamMaxValue}`);\r\n const url = this.appendCustomParams(urlObj.toString());\r\n this._staticData = await this.fetchItems(url, this._staticModeFetchTimeout);\r\n return this._staticData ? true : false;\r\n }\r\n\r\n private async fetchItems(url: string, timeout: number) {\r\n let data: any;\r\n let success = true;\r\n try {\r\n const fetchBegin = Date.now();\r\n let tmpUrl = this.appendCustomParams(url);\r\n let response = await this.makeTileRequest(tmpUrl, timeout);\r\n let json = await response.json();\r\n data = json;\r\n // Follow \"next\" link if any, resolving each href against the URL that served it\r\n let pageResponseUrl = response.url || tmpUrl;\r\n let nextLink = json.links?.find((link: any)=>link.rel === \"next\");\r\n while (nextLink && (Date.now() - fetchBegin) < timeout && success) {\r\n tmpUrl = this.appendCustomParams(new URL(nextLink.href, pageResponseUrl).toString());\r\n response = await this.makeTileRequest(tmpUrl, this._staticModeFetchTimeout);\r\n pageResponseUrl = response.url || tmpUrl;\r\n json = await response.json();\r\n if (json?.features)\r\n data.features = this._staticData?.features ? [...this._staticData.features, ...json.features] : json.features;\r\n else\r\n success = false;\r\n nextLink = json.links?.find((link: any)=>link.rel === \"next\");\r\n }\r\n if (Date.now() - fetchBegin >= this._staticModeFetchTimeout) {\r\n // We ran out of time, let switch to tile mode\r\n success = false;\r\n }\r\n } catch (e) {\r\n success = false;\r\n if (e instanceof DOMException && e.name === \"AbortError\") {\r\n Logger.logInfo(loggerCategory, \"Request to fetch all features time out, switching to tile mode.\");\r\n } else {\r\n Logger.logError(loggerCategory, \"Unknown error occurred when fetching OgcApiFeatures data.\");\r\n }\r\n }\r\n return success ? data : undefined;\r\n }\r\n\r\n // Read features range and build in-memory spatial index\r\n private async indexStaticData() {\r\n // UGLY IMPORT:\r\n // flatbush only provides ECM modules, and since mocha is not very good with ECM modules,\r\n // we need to have this special import, until we replace mocha with something else.\r\n const flatbush = (await import(\"flatbush\")).default;\r\n let success = true;\r\n try {\r\n const datasetRange = new Range2d();\r\n const buildPositionRange = (coords: Geojson.Position, range: Range2d) => range.extendXY(coords[0], coords[1]);\r\n const buildPositionArrayRange = (coords: Geojson.Position[], range: Range2d) => coords.forEach((position) => buildPositionRange(position, range) );\r\n const buildDoublePositionRange = (coords: Geojson.Position[][], range: Range2d) => coords.forEach((position) => buildPositionArrayRange(position, range) );\r\n const buildTriplePositionRange = (coords: Geojson.Position[][][], range: Range2d) => coords.forEach((position) => buildDoublePositionRange(position, range) );\r\n\r\n const readGeomRange = (geom: Geojson.Geometry, range: Range2d) => {\r\n if (geom.type === \"Point\")\r\n buildPositionRange(geom.coordinates, range);\r\n else if (geom.type === \"LineString\" || geom.type === \"MultiPoint\")\r\n buildPositionArrayRange(geom.coordinates, range);\r\n else if (geom.type === \"Polygon\" || geom.type === \"MultiLineString\")\r\n buildDoublePositionRange(geom.coordinates, range);\r\n else if (geom.type === \"MultiPolygon\" )\r\n buildTriplePositionRange(geom.coordinates, range);\r\n };\r\n\r\n if (this._staticData && Array.isArray(this._staticData.features)) {\r\n this._spatialIdx = new flatbush(this._staticData.features.length);\r\n this._staticData.features.forEach((feature: Geojson.Feature) => {\r\n try {\r\n if (feature.geometry.type === \"LineString\"\r\n || feature.geometry.type === \"MultiLineString\"\r\n || feature.geometry.type === \"Point\"\r\n || feature.geometry.type === \"MultiPoint\"\r\n || feature.geometry.type === \"Polygon\"\r\n || feature.geometry.type === \"MultiPolygon\"\r\n ) {\r\n readGeomRange(feature.geometry, datasetRange);\r\n this._spatialIdx?.add(datasetRange.xLow, datasetRange.yLow, datasetRange.xHigh,datasetRange. yHigh);\r\n datasetRange.setNull();\r\n } else if (feature.geometry.type === \"GeometryCollection\") {\r\n feature.geometry.geometries.forEach((geom) => {\r\n readGeomRange(geom, datasetRange);\r\n this._spatialIdx?.add(datasetRange.xLow, datasetRange.yLow, datasetRange.xHigh,datasetRange. yHigh);\r\n });\r\n datasetRange.setNull();\r\n }\r\n } catch (e: any) {\r\n Logger.logInfo(loggerCategory, `Unknown error occurred indexing feature: ${e.message}`);\r\n success = false;\r\n }\r\n });\r\n\r\n if (success) {\r\n this._spatialIdx.finish();\r\n }\r\n }\r\n\r\n } catch {\r\n Logger.logError(loggerCategory, \"Unknown error occurred when index static data\");\r\n success = false;\r\n }\r\n return success;\r\n }\r\n\r\n public override get tileSize(): number { return 512; }\r\n\r\n // We don't use this method inside this provider (see constructFeatureUrl), but since this is an abstract method, we need to define something\r\n public async constructUrl(_row: number, _column: number, _zoomLevel: number): Promise<string> {\r\n return \"\";\r\n }\r\n\r\n public drawTileDebugInfo(row: number, column: number, zoomLevel: number, context: CanvasRenderingContext2D) {\r\n context.fillStyle = \"cyan\";\r\n context.strokeRect(0, 0, this.tileSize, this.tileSize);\r\n context.font = \"30px Arial\";\r\n context.lineWidth = 5;\r\n context.fillText(`${zoomLevel}-${row}-${column}`, 10, 50);\r\n }\r\n\r\n // Compute transform that provides coordinates in the canvas coordinate system (pixels, origin = top-left)\r\n // from coordinate in world\r\n public computeTileWorld2CanvasTransform(row: number, column: number, zoomLevel: number) {\r\n\r\n const tileExtentWorld4326 = this.getEPSG4326Extent(row, column, zoomLevel);\r\n const worldTileWidth = tileExtentWorld4326.longitudeRight - tileExtentWorld4326.longitudeLeft;\r\n const worldTileHeight = tileExtentWorld4326.latitudeTop - tileExtentWorld4326.latitudeBottom;\r\n const canvasTileWidth = this.tileSize;\r\n const canvasTileHeight = this.tileSize;\r\n const world2CanvasRatioX = canvasTileWidth / worldTileWidth;\r\n const world2CanvasRatioY = canvasTileHeight / worldTileHeight;\r\n const worldTileOrigin = Point3d.create(tileExtentWorld4326.longitudeLeft, tileExtentWorld4326.latitudeBottom);\r\n const worldTileExtent = Point3d.create(tileExtentWorld4326.longitudeRight, tileExtentWorld4326.latitudeTop);\r\n const canvasTileOriginOffset = worldTileOrigin.clone();\r\n const canvasTileExtentOffset = worldTileExtent.clone();\r\n canvasTileOriginOffset.x *= world2CanvasRatioX;\r\n canvasTileOriginOffset.y *= world2CanvasRatioY;\r\n canvasTileExtentOffset.x *= world2CanvasRatioX;\r\n canvasTileExtentOffset.y *= world2CanvasRatioY;\r\n const xTranslate = -1 * canvasTileOriginOffset.x;\r\n\r\n // Canvas origin is upper left corner, so we need to flip the y axis\r\n const yTranslate = canvasTileExtentOffset.y; // y-axis flip\r\n const yWorld2CanvasRatio = -1 * world2CanvasRatioY; // y-axis flip\r\n\r\n const matrix = Matrix4d.createTranslationAndScaleXYZ(xTranslate, yTranslate, 0, world2CanvasRatioX, yWorld2CanvasRatio, 1);\r\n return matrix.asTransform;\r\n }\r\n\r\n public override async loadTile(row: number, column: number, zoomLevel: number): Promise<ImageSource | undefined> {\r\n\r\n const extent4326 = this.getEPSG4326Extent(row, column, zoomLevel);\r\n\r\n let data: any;\r\n if (this.staticMode) {\r\n // Static data mode\r\n const filteredData: Geojson.FeatureCollection = {type: \"FeatureCollection\", features: []};\r\n\r\n this._spatialIdx?.search(extent4326.longitudeLeft, extent4326.latitudeBottom, extent4326.longitudeRight, extent4326.latitudeTop,\r\n (index: number) => {\r\n filteredData.features.push(expectDefined(this._staticData).features[index]);\r\n return true;\r\n });\r\n\r\n data = filteredData;\r\n } else {\r\n // Tiled data mode\r\n const extent4326Str = this.getEPSG4326TileExtentString(row, column, zoomLevel, false);\r\n const urlObj = new URL(this._itemsUrl);\r\n urlObj.searchParams.append(\"bbox\", `${extent4326Str}`);\r\n urlObj.searchParams.append(\"bbox-crs\", this._itemsCrs);\r\n urlObj.searchParams.append(\"limit\", `${this._limitParamMaxValue}`);\r\n const url = this.appendCustomParams(urlObj.toString());\r\n\r\n try {\r\n data = await this.fetchItems(url, this._tileModeFetchTimeout);\r\n } catch {\r\n }\r\n if (!data) {\r\n Logger.logError(loggerCategory, \"Could not fetch OgcApiFeatures data.\");\r\n }\r\n }\r\n\r\n if (!data || !Array.isArray(data.features) || data.features.length === 0) {\r\n Logger.logInfo(loggerCategory, `No data to render for tile (${zoomLevel}/${row}/${column}).`);\r\n }\r\n\r\n // Rendering starts here\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.width = this.tileSize;\r\n canvas.height = this.tileSize;\r\n const ctx = canvas.getContext(\"2d\");\r\n if (ctx == null) {\r\n Logger.logError(loggerCategory, \"No canvas context available for loading tile.\");\r\n return undefined;\r\n }\r\n\r\n try {\r\n // Compute transform if CoordinatesQuantization is not supported by service\r\n const transfo = this.computeTileWorld2CanvasTransform(row, column, zoomLevel);\r\n if (!transfo) {\r\n Logger.logError(loggerCategory, `Could not compute data transformation for tile (${zoomLevel}/${row}/${column})`);\r\n }\r\n\r\n // Create the renderer\r\n\r\n // Instead of passing a Transform oject to the render, it should be possible\r\n // instead to set the Transform directly on the Canvas, when I tried the display was incorrect, floating point issue?\r\n // const transfoRow = transfo!.toRows();\r\n // ctx.setTransform(transfoRow[0][0], transfoRow[1][0], transfoRow[0][1], transfoRow[1][1], transfoRow[0][3], transfoRow[1][3]);\r\n const symbRenderer = ArcGisSymbologyCanvasRenderer.create(this._renderer, this._defaultSymbol);\r\n const renderer = new FeatureCanvasRenderer(ctx, symbRenderer, transfo);\r\n\r\n const featureReader = new OgcApiFeaturesReader();\r\n\r\n await featureReader.readAndRender(data, renderer);\r\n if (this._drawDebugInfo)\r\n this.drawTileDebugInfo(row, column, zoomLevel, ctx);\r\n } catch (e) {\r\n Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${BentleyError.getErrorMessage(e)}`);\r\n }\r\n\r\n try {\r\n return this.createImageSourceFromDataURL(canvas.toDataURL(\"image/png\"), ImageSourceFormat.Png);\r\n } catch (e) {\r\n Logger.logError(loggerCategory, `Exception occurred while rendering tile (${zoomLevel}/${row}/${column}) : ${BentleyError.getErrorMessage(e)}`);\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private createImageSourceFromDataURL(dataUrl: string, format: ImageSourceFormat) {\r\n if (!dataUrl)\r\n return undefined;\r\n\r\n const dataStartPos = dataUrl.indexOf(dataUrlHeaderToken) + dataUrlHeaderToken.length;\r\n\r\n if (dataStartPos < 0)\r\n return undefined;\r\n\r\n const base64Png = dataUrl.substring(dataStartPos);\r\n return new ImageSource(base64StringToUint8Array(base64Png), format);\r\n }\r\n\r\n public override async getFeatureInfo(featureInfos: MapLayerFeatureInfo[], quadId: QuadId, carto: Cartographic, _tree: ImageryMapTileTree, hit: HitDetail, options?: MapFeatureInfoOptions): Promise<void> {\r\n const tileExtent = this.getEPSG4326Extent(quadId.row, quadId.column, quadId.level);\r\n const tilePixelSizeX = (tileExtent.longitudeRight - tileExtent.longitudeLeft) / this.tileSize;\r\n const tilePixelSizeY = (tileExtent.latitudeTop - tileExtent.latitudeBottom) / this.tileSize;\r\n const tolerancePixel = options?.tolerance ?? 7;\r\n const toleranceWorldX = tilePixelSizeX * tolerancePixel;\r\n const toleranceWorldY = tilePixelSizeY * tolerancePixel;\r\n\r\n // Note: We used to pass a single point as the query 'geometry' and leverage the 'distance' parameter, turns\r\n // out that approach was a lot slower on some server compared to using a single envelope.\r\n const bbox: WGS84Extent = {\r\n longitudeLeft: carto.longitudeDegrees - toleranceWorldX, latitudeBottom: carto.latitudeDegrees - toleranceWorldY,\r\n longitudeRight: carto.longitudeDegrees + toleranceWorldX, latitudeTop: carto.latitudeDegrees + toleranceWorldY,\r\n };\r\n\r\n const bboxStr = this.getEPSG4326ExtentString(bbox, false);\r\n const urlObj = new URL(this._itemsUrl);\r\n urlObj.searchParams.append(\"bbox\", `${bboxStr}`);\r\n urlObj.searchParams.append(\"bbox-crs\", this._itemsCrs);\r\n urlObj.searchParams.append(\"limit\", `${this._limitParamMaxValue}`);\r\n const url = this.appendCustomParams(urlObj.toString());\r\n\r\n let data: any;\r\n try {\r\n data = await this.fetchItems(url, this._tileModeFetchTimeout);\r\n } catch {\r\n }\r\n if (!data) {\r\n Logger.logError(loggerCategory, \"Could not fetch OgcApiFeatures data.\");\r\n }\r\n\r\n const featureReader = new OgcApiFeaturesReader();\r\n await featureReader.readFeatureInfo({\r\n collection:data,\r\n layerSettings: this._settings,\r\n queryables: this._queryables,\r\n geomRenderer: new FeatureGraphicsRenderer({viewport: hit.viewport, crs: \"wgs84\"})},\r\n featureInfos );\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArcGisFeatureProvider.d.ts","sourceRoot":"","sources":["../../../src/ArcGisFeature/ArcGisFeatureProvider.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAkC,MAAM,oBAAoB,CAAC;AACtH,OAAO,EAAmB,qBAAqB,EAAmE,SAAS,EAAE,kBAAkB,EAAqB,qBAAqB,EAAE,mBAAmB,EAAiC,MAAM,EAAqB,MAAM,sBAAsB,CAAC;AACvS,OAAO,EAA8B,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAA4C,uBAAuB,EAAE,cAAc,EAAkC,MAAM,yBAAyB,CAAC;AAM/L,OAAO,EAAE,OAAO,EAAgB,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIvG;;EAEE;AACF,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;EAEE;AACF,qBAAa,qBAAsB,YAAW,uBAAuB;IACnE,gBAAuB,UAAU,UAS9B;IAEH,gBAAuB,eAAe,EAAE,YAAY,CAKlD;IACF,gBAAuB,UAAU,UAA0C;IAE3E,gBAAuB,UAAU,UAK9B;IAEU,UAAU;IAKhB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;CAWlD;AAED;;EAEE;AACF,qBAAa,qBAAsB,SAAQ,qBAAqB;IAE9D,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,gCAAgC,CAAS;IAEjD,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,MAAM,CAAU;IAExB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,gBAAgB,CAAK;IAE7B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,kBAAkB,CAA0C;IAEpE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAK;IACjC,WAAW,EAAE,GAAG,CAAC;IAExB,IAAoB,gBAAgB,IAAI,MAAM,CAAkC;IAChF,IAAoB,gBAAgB,IAAI,MAAM,CAAkC;IAEhF,OAAO,CAAC,MAAM,CAAC,YAAY,CAA0B;gBAEzC,QAAQ,EAAE,qBAAqB;IAIrB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ArcGisFeatureProvider.d.ts","sourceRoot":"","sources":["../../../src/ArcGisFeature/ArcGisFeatureProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { base64StringToUint8Array, IModelStatus, Logger } from "@itwin/core-bentley";
|
|
5
|
+
import { base64StringToUint8Array, BentleyError, IModelStatus, Logger } from "@itwin/core-bentley";
|
|
6
6
|
import { ImageSource, ImageSourceFormat, ServerError } from "@itwin/core-common";
|
|
7
7
|
import { ArcGisErrorCode, ArcGISImageryProvider, ArcGisUtilities, FeatureGraphicsRenderer, MapCartoRectangle, MapLayerImageryProviderStatus, setRequestTimeout } from "@itwin/core-frontend";
|
|
8
8
|
import { Matrix4d, Point3d, Range2d } from "@itwin/core-geometry";
|
|
@@ -87,6 +87,9 @@ export class ArcGisFeatureProvider extends ArcGISImageryProvider {
|
|
|
87
87
|
const metadata = await this.getServiceJson();
|
|
88
88
|
const json = metadata?.content;
|
|
89
89
|
if (json === undefined) {
|
|
90
|
+
// By returning (i.e., not throwing), we ensure the tile tree gets created and the current provider is preserved to report status.
|
|
91
|
+
if (this.status === MapLayerImageryProviderStatus.UntrustedOrigin)
|
|
92
|
+
return;
|
|
90
93
|
Logger.logError(loggerCategory, "Could not get service JSON");
|
|
91
94
|
throw new ServerError(IModelStatus.ValidationFailed, "");
|
|
92
95
|
}
|
|
@@ -221,7 +224,7 @@ export class ArcGisFeatureProvider extends ArcGISImageryProvider {
|
|
|
221
224
|
await this._renderer.initialize();
|
|
222
225
|
}
|
|
223
226
|
catch (e) {
|
|
224
|
-
Logger.logError(loggerCategory, `Could not initialize symbology renderer for '${this._settings.name}': ${e}`);
|
|
227
|
+
Logger.logError(loggerCategory, `Could not initialize symbology renderer for '${this._settings.name}': ${BentleyError.getErrorMessage(e)}`);
|
|
225
228
|
}
|
|
226
229
|
// Sanity check: make sure we got default symbology for this geometry type
|
|
227
230
|
// if not, it will throw
|
|
@@ -377,7 +380,7 @@ export class ArcGisFeatureProvider extends ArcGISImageryProvider {
|
|
|
377
380
|
}
|
|
378
381
|
}
|
|
379
382
|
catch (e) {
|
|
380
|
-
Logger.logInfo(loggerCategory, `Error occurred with debug FeatureInfo: ${e}`);
|
|
383
|
+
Logger.logInfo(loggerCategory, `Error occurred with debug FeatureInfo: ${BentleyError.getErrorMessage(e)}`);
|
|
381
384
|
}
|
|
382
385
|
}
|
|
383
386
|
try {
|
|
@@ -396,7 +399,7 @@ export class ArcGisFeatureProvider extends ArcGISImageryProvider {
|
|
|
396
399
|
await featureReader.readFeatureInfo(responseData, featureInfos, renderer);
|
|
397
400
|
}
|
|
398
401
|
catch (e) {
|
|
399
|
-
Logger.logError(loggerCategory, `Exception occurred while loading feature info data : ${e}`);
|
|
402
|
+
Logger.logError(loggerCategory, `Exception occurred while loading feature info data : ${BentleyError.getErrorMessage(e)}`);
|
|
400
403
|
return;
|
|
401
404
|
}
|
|
402
405
|
return;
|
|
@@ -508,7 +511,7 @@ export class ArcGisFeatureProvider extends ArcGISImageryProvider {
|
|
|
508
511
|
}
|
|
509
512
|
}
|
|
510
513
|
catch (e) {
|
|
511
|
-
Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${e}`);
|
|
514
|
+
Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${BentleyError.getErrorMessage(e)}`);
|
|
512
515
|
return;
|
|
513
516
|
}
|
|
514
517
|
if (responseData.exceedTransferLimit) {
|
|
@@ -533,7 +536,7 @@ export class ArcGisFeatureProvider extends ArcGISImageryProvider {
|
|
|
533
536
|
this.drawTileDebugInfo(row, column, zoomLevel, ctx);
|
|
534
537
|
}
|
|
535
538
|
catch (e) {
|
|
536
|
-
Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${e}`);
|
|
539
|
+
Logger.logError(loggerCategory, `Exception occurred while loading tile (${zoomLevel}/${row}/${column}) : ${BentleyError.getErrorMessage(e)}`);
|
|
537
540
|
}
|
|
538
541
|
try {
|
|
539
542
|
const dataUrl = canvas.toDataURL("image/png");
|
|
@@ -542,7 +545,7 @@ export class ArcGisFeatureProvider extends ArcGISImageryProvider {
|
|
|
542
545
|
return new ImageSource(base64StringToUint8Array(dataUrl2), ImageSourceFormat.Png);
|
|
543
546
|
}
|
|
544
547
|
catch (e) {
|
|
545
|
-
Logger.logError(loggerCategory, `Exception occurred while rendering tile (${zoomLevel}/${row}/${column}) : ${e}.`);
|
|
548
|
+
Logger.logError(loggerCategory, `Exception occurred while rendering tile (${zoomLevel}/${row}/${column}) : ${BentleyError.getErrorMessage(e)}.`);
|
|
546
549
|
}
|
|
547
550
|
return undefined;
|
|
548
551
|
}
|