ogcopenapis 0.0.12 → 1.0.0
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/LICENSE +20 -20
- package/README.md +310 -72
- package/lib/OgcOpenApiCrsTools.d.ts +10 -9
- package/lib/OgcOpenApiCrsTools.d.ts.map +1 -0
- package/lib/OgcOpenApiCrsTools.js +40 -39
- package/lib/OgcOpenApiCrsTools.js.map +1 -0
- package/lib/OgcOpenApiFeatureStore.d.ts +94 -93
- package/lib/OgcOpenApiFeatureStore.d.ts.map +1 -0
- package/lib/OgcOpenApiFeatureStore.js +200 -244
- package/lib/OgcOpenApiFeatureStore.js.map +1 -0
- package/lib/OgcOpenApiFetchTools.d.ts +37 -30
- package/lib/OgcOpenApiFetchTools.d.ts.map +1 -0
- package/lib/OgcOpenApiFetchTools.js +68 -50
- package/lib/OgcOpenApiFetchTools.js.map +1 -0
- package/lib/OgcOpenApiGetCapabilities.d.ts +209 -112
- package/lib/OgcOpenApiGetCapabilities.d.ts.map +1 -0
- package/lib/OgcOpenApiGetCapabilities.js +424 -277
- package/lib/OgcOpenApiGetCapabilities.js.map +1 -0
- package/lib/OgcOpenApiMapsModel.d.ts +41 -36
- package/lib/OgcOpenApiMapsModel.d.ts.map +1 -0
- package/lib/OgcOpenApiMapsModel.js +88 -75
- package/lib/OgcOpenApiMapsModel.js.map +1 -0
- package/lib/OgcOpenApiMvtTools.d.ts +12 -0
- package/lib/OgcOpenApiMvtTools.d.ts.map +1 -0
- package/lib/OgcOpenApiMvtTools.js +100 -0
- package/lib/OgcOpenApiMvtTools.js.map +1 -0
- package/lib/OgcOpenApiStyleTools.d.ts +51 -0
- package/lib/OgcOpenApiStyleTools.d.ts.map +1 -0
- package/lib/OgcOpenApiStyleTools.js +155 -0
- package/lib/OgcOpenApiStyleTools.js.map +1 -0
- package/lib/OgcOpenApiTileMatrixTools.d.ts +41 -0
- package/lib/OgcOpenApiTileMatrixTools.d.ts.map +1 -0
- package/lib/OgcOpenApiTileMatrixTools.js +88 -0
- package/lib/OgcOpenApiTileMatrixTools.js.map +1 -0
- package/lib/OgcOpenApiTilesModel.d.ts +56 -31
- package/lib/OgcOpenApiTilesModel.d.ts.map +1 -0
- package/lib/OgcOpenApiTilesModel.js +167 -128
- package/lib/OgcOpenApiTilesModel.js.map +1 -0
- package/lib/OgcOpenApiVectorTilesModel.d.ts +39 -0
- package/lib/OgcOpenApiVectorTilesModel.d.ts.map +1 -0
- package/lib/OgcOpenApiVectorTilesModel.js +122 -0
- package/lib/OgcOpenApiVectorTilesModel.js.map +1 -0
- package/lib/OgcOpenApiWmtsTools.d.ts +30 -0
- package/lib/OgcOpenApiWmtsTools.d.ts.map +1 -0
- package/lib/OgcOpenApiWmtsTools.js +89 -0
- package/lib/OgcOpenApiWmtsTools.js.map +1 -0
- package/package.json +56 -27
- package/src/OgcOpenApiCrsTools.ts +40 -0
- package/src/OgcOpenApiFeatureStore.ts +296 -0
- package/src/OgcOpenApiFetchTools.ts +84 -0
- package/src/OgcOpenApiGetCapabilities.ts +641 -0
- package/src/OgcOpenApiMapsModel.ts +128 -0
- package/src/OgcOpenApiMvtTools.ts +104 -0
- package/src/OgcOpenApiStyleTools.ts +187 -0
- package/src/OgcOpenApiTileMatrixTools.ts +111 -0
- package/src/OgcOpenApiTilesModel.ts +214 -0
- package/src/OgcOpenApiVectorTilesModel.ts +141 -0
- package/src/OgcOpenApiWmtsTools.ts +114 -0
- package/lib/OgcOpenApiGetCollectionTiles.d.ts +0 -7
- package/lib/OgcOpenApiGetCollectionTiles.js +0 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OgcOpenApiWmtsTools.js","sourceRoot":"","sources":["../src/OgcOpenApiWmtsTools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,39 +1,68 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ogcopenapis",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OGC API Features, Maps, Tiles and Styles for LuciadRIA",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./lib/*": {
|
|
8
|
+
"types": "./lib/*.d.ts",
|
|
9
|
+
"import": "./lib/*.js"
|
|
10
|
+
},
|
|
11
|
+
"./*": {
|
|
12
|
+
"types": "./lib/*.d.ts",
|
|
13
|
+
"import": "./lib/*.js"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
5
17
|
"files": [
|
|
6
|
-
"lib/"
|
|
18
|
+
"lib/",
|
|
19
|
+
"src/",
|
|
20
|
+
"!src/**/*.test.ts",
|
|
21
|
+
"!src/fixtures/"
|
|
7
22
|
],
|
|
23
|
+
"sideEffects": false,
|
|
8
24
|
"scripts": {
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
25
|
+
"clean": "node -e \"require('node:fs').rmSync('lib', {recursive: true, force: true})\"",
|
|
26
|
+
"build:lib": "tsc -p tsconfig.build.json",
|
|
27
|
+
"build": "npm run clean && npm run build:lib",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:live": "vitest run --config vitest.live.config.ts",
|
|
30
|
+
"test:record": "vitest run --config vitest.record.config.ts",
|
|
31
|
+
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
32
|
+
"test:package": "npm run build && node test/package/checkPackage.mjs",
|
|
33
|
+
"prepublishOnly": "npm run test && npm run test:package",
|
|
34
|
+
"demo": "vite demo",
|
|
35
|
+
"demo:build": "vite build demo"
|
|
17
36
|
},
|
|
18
|
-
"keywords": [
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
"keywords": [
|
|
38
|
+
"ogc",
|
|
39
|
+
"ogc-api",
|
|
40
|
+
"features",
|
|
41
|
+
"maps",
|
|
42
|
+
"tiles",
|
|
43
|
+
"vector-tiles",
|
|
44
|
+
"styles",
|
|
45
|
+
"luciadria"
|
|
46
|
+
],
|
|
47
|
+
"author": "felipecarrillo100",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@luciad/ria": ">=2026.1.0"
|
|
31
51
|
},
|
|
32
|
-
"
|
|
33
|
-
"@
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@arethetypeswrong/cli": "0.18.5",
|
|
54
|
+
"@luciad/ria": "2026.1.1",
|
|
55
|
+
"@types/node": "^18.11.18",
|
|
56
|
+
"jsdom": "^25.0.1",
|
|
57
|
+
"playwright-core": "1.63.0",
|
|
58
|
+
"publint": "0.3.25",
|
|
59
|
+
"typescript": "5.9.3",
|
|
60
|
+
"vite": "^5.4.21",
|
|
61
|
+
"vitest": "^3.2.4",
|
|
62
|
+
"vitest-canvas-mock": "^1.2.0"
|
|
34
63
|
},
|
|
35
64
|
"repository": {
|
|
36
65
|
"type": "git",
|
|
37
|
-
"url": "git+https://github.com/felipecarrillo100/ogcopenapis"
|
|
66
|
+
"url": "git+https://github.com/felipecarrillo100/ogcopenapis.git"
|
|
38
67
|
}
|
|
39
68
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class OgcOpenApiCrsTools {
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param uriOrName
|
|
5
|
+
* @private
|
|
6
|
+
*/
|
|
7
|
+
public static getReferenceName(uriOrNameI: string) {
|
|
8
|
+
let uriOrName;
|
|
9
|
+
if (typeof uriOrNameI === "undefined") {
|
|
10
|
+
uriOrName = "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
|
|
11
|
+
} else {
|
|
12
|
+
uriOrName = uriOrNameI.replace(/[<>]/g, '');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!uriOrName.startsWith('http')) {
|
|
16
|
+
return uriOrName;
|
|
17
|
+
}
|
|
18
|
+
const prefix = 'http://www.opengis.net/def/crs/';
|
|
19
|
+
if (uriOrName.startsWith(prefix)) {
|
|
20
|
+
const cleanCRS = uriOrName.substr(prefix.length);
|
|
21
|
+
const parts = cleanCRS.split('/');
|
|
22
|
+
if (parts.length === 3) {
|
|
23
|
+
const name = parts[0];
|
|
24
|
+
const version = parts[1];
|
|
25
|
+
const code = parts[2];
|
|
26
|
+
switch (name) {
|
|
27
|
+
case 'EPSG':
|
|
28
|
+
return name + ':' + code;
|
|
29
|
+
break;
|
|
30
|
+
case 'OGC':
|
|
31
|
+
return 'CRS' + ':' + code.substr('CRS'.length);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return uriOrName;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { OgcOpenApiCrsTools}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {type QueryOptions, Store, type StoreOperationName} from '@luciad/ria/model/store/Store.js';
|
|
2
|
+
import type {Cursor} from '@luciad/ria/model/Cursor.js';
|
|
3
|
+
import {Feature} from '@luciad/ria/model/feature/Feature.js';
|
|
4
|
+
import {Bounds} from '@luciad/ria/shape/Bounds.js';
|
|
5
|
+
import {Codec, type CodecDecodeOptions} from '@luciad/ria/model/codec/Codec.js';
|
|
6
|
+
import {createBounds} from '@luciad/ria/shape/ShapeFactory.js';
|
|
7
|
+
import {CoordinateReference} from '@luciad/ria/reference/CoordinateReference.js';
|
|
8
|
+
import {getReference} from "@luciad/ria/reference/ReferenceProvider.js";
|
|
9
|
+
import {createTransformation} from "@luciad/ria/transformation/TransformationFactory.js";
|
|
10
|
+
import {OgcOpenApiCrsTools} from "./OgcOpenApiCrsTools.js";
|
|
11
|
+
import {GeoJsonCodec} from "@luciad/ria/model/codec/GeoJsonCodec.js";
|
|
12
|
+
import {GMLCodec} from "@luciad/ria/model/codec/GMLCodec.js";
|
|
13
|
+
import type {ProxifyFunction} from "./OgcOpenApiGetCapabilities.js";
|
|
14
|
+
import {OgcOpenApiFetchTools} from "./OgcOpenApiFetchTools.js";
|
|
15
|
+
|
|
16
|
+
export interface OgcOpenApiFeatureStoreConstructorOptions {
|
|
17
|
+
swapAxes?: string[];
|
|
18
|
+
dataUrl: string;
|
|
19
|
+
featureUrl?: string;
|
|
20
|
+
outputFormat: string;
|
|
21
|
+
useCrs84Bounds?: boolean;
|
|
22
|
+
codec: Codec;
|
|
23
|
+
credentials?: boolean;
|
|
24
|
+
requestHeaders?: { [key: string]: string };
|
|
25
|
+
extent?: { spatial: { bbox: any[] } };
|
|
26
|
+
crs: string;
|
|
27
|
+
proxify?: ProxifyFunction
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface OgcOpenApiFeatureStoreQueryOptions {
|
|
31
|
+
f?:string;
|
|
32
|
+
limit?: number;
|
|
33
|
+
offset?: number;
|
|
34
|
+
bbox?: number[];
|
|
35
|
+
"bbox-crs"? : string;
|
|
36
|
+
datetime?: string;
|
|
37
|
+
filter?: string;
|
|
38
|
+
"filter-crs"?: string;
|
|
39
|
+
"filter-lang"?: string;
|
|
40
|
+
crs?: string | any;
|
|
41
|
+
skipGeometry?: boolean;
|
|
42
|
+
properties?: string[];
|
|
43
|
+
sortby?: string[];
|
|
44
|
+
ident?: string;
|
|
45
|
+
name?: string;
|
|
46
|
+
q?: string[];
|
|
47
|
+
maxAllowableOffset?: number;
|
|
48
|
+
level?: string;
|
|
49
|
+
sector?: string;
|
|
50
|
+
milCode?: string;
|
|
51
|
+
localType?: string;
|
|
52
|
+
upperLimitDesc?: number;
|
|
53
|
+
upperLimitValue?: number;
|
|
54
|
+
upperLimitUnit?: string;
|
|
55
|
+
upperLimitCode?: string;
|
|
56
|
+
lowerLimitDesc?: string;
|
|
57
|
+
lowerLimitValue?: number;
|
|
58
|
+
lowerLimitUnit?: string;
|
|
59
|
+
lowerLimitCode?: string;
|
|
60
|
+
onshore?:boolean;
|
|
61
|
+
exclusion?: boolean;
|
|
62
|
+
wkhrCode?: string;
|
|
63
|
+
wkhrRemark?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface OgcOpenApiFeaturesCodecDecodeOptions extends CodecDecodeOptions {
|
|
67
|
+
contentCrs?: string;
|
|
68
|
+
contentLength?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export class OgcOpenApiFeatureStore extends Store {
|
|
72
|
+
private dataUrl: string;
|
|
73
|
+
private codec: Codec;
|
|
74
|
+
private baseUrl: string;
|
|
75
|
+
private dataFormat: string | undefined;
|
|
76
|
+
private customCrs: string | undefined;
|
|
77
|
+
private dataBounds: Bounds;
|
|
78
|
+
private requestHeaders: { [key: string]: string };
|
|
79
|
+
private reference: CoordinateReference;
|
|
80
|
+
private outputFormat: string;
|
|
81
|
+
private useCrs84Bounds: boolean;
|
|
82
|
+
private featureUrl: string;
|
|
83
|
+
private proxy: ProxifyFunction;
|
|
84
|
+
private credentials: boolean;
|
|
85
|
+
private serverOptions: { proxy: (url: string, fetchOptions) => { fetchOptions: any; url: string }; hostname: string; complete: (url: string) => string };
|
|
86
|
+
private swapAxes: string[] | undefined;
|
|
87
|
+
|
|
88
|
+
constructor(options: OgcOpenApiFeatureStoreConstructorOptions) {
|
|
89
|
+
super();
|
|
90
|
+
// console.log(options);
|
|
91
|
+
this.swapAxes = options.swapAxes;
|
|
92
|
+
this.useCrs84Bounds = typeof options.useCrs84Bounds !== "undefined" ? options.useCrs84Bounds : false;
|
|
93
|
+
this.dataUrl = options.dataUrl;
|
|
94
|
+
this.outputFormat = options.outputFormat;
|
|
95
|
+
const predictedFeatureUrl = this.dataUrl.replace(/\.[^/.]+$/, "");
|
|
96
|
+
|
|
97
|
+
this.featureUrl = options.featureUrl ? OgcOpenApiFeatureStore.cleanUrl(options.featureUrl, true) : OgcOpenApiFeatureStore.cleanUrl(predictedFeatureUrl, true);
|
|
98
|
+
|
|
99
|
+
this.baseUrl = OgcOpenApiFeatureStore.cleanUrl(this.dataUrl);
|
|
100
|
+
this.dataFormat = OgcOpenApiFeatureStore.dataFormatInQuery(this.dataUrl);
|
|
101
|
+
this.customCrs = options.crs === "http://www.opengis.net/def/crs/OGC/1.3/CRS84" ? undefined : options.crs;
|
|
102
|
+
this.codec = options.codec;
|
|
103
|
+
this.requestHeaders = options.requestHeaders ? options.requestHeaders : {};
|
|
104
|
+
const referenceName = OgcOpenApiCrsTools.getReferenceName(options.crs)
|
|
105
|
+
this.reference = getReference(referenceName);
|
|
106
|
+
this.proxy = options.proxify;
|
|
107
|
+
this.credentials = options.credentials;
|
|
108
|
+
|
|
109
|
+
this.serverOptions = OgcOpenApiFetchTools.createFetchOptions({originalUrl: this.dataUrl, proxify: options.proxify});
|
|
110
|
+
|
|
111
|
+
if (
|
|
112
|
+
options.extent &&
|
|
113
|
+
options.extent.spatial &&
|
|
114
|
+
options.extent.spatial.bbox &&
|
|
115
|
+
options.extent.spatial.bbox.length > 0
|
|
116
|
+
) {
|
|
117
|
+
const bbox = options.extent.spatial.bbox[0];
|
|
118
|
+
const WGS84 = getReference("CRS:84");
|
|
119
|
+
const tmpBounds = createBounds(WGS84, [
|
|
120
|
+
bbox[0],
|
|
121
|
+
bbox[2] - bbox[0],
|
|
122
|
+
bbox[1],
|
|
123
|
+
bbox[3] - bbox[1],
|
|
124
|
+
]);
|
|
125
|
+
this.dataBounds = OgcOpenApiFeatureStore.targetBounds(tmpBounds, this.reference);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Store defines bounds as a getter, the extent is kept in dataBounds
|
|
130
|
+
get bounds(): Bounds {
|
|
131
|
+
return this.dataBounds;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
isOperationSupported(methodName: StoreOperationName): boolean {
|
|
135
|
+
return methodName === "get" || methodName === "spatialQuery";
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
get(id: number | string, optionsInput?: any): Promise<Feature> {
|
|
139
|
+
const options = optionsInput ? { ...optionsInput } : {};
|
|
140
|
+
options.query = (options.query ? options.query : {}) as OgcOpenApiFeatureStoreQueryOptions;
|
|
141
|
+
options.query.f = options.query.f ? options.query.f : this.dataFormat;
|
|
142
|
+
options.query.crs = options.query.crs ? options.query.crs : this.customCrs;
|
|
143
|
+
let request = this.featureUrl + id;
|
|
144
|
+
const simpleQuery = [];
|
|
145
|
+
if (options.query.f) simpleQuery.push("f");
|
|
146
|
+
if (options.query.crs) simpleQuery.push("crs");
|
|
147
|
+
if (simpleQuery.length > 0) {
|
|
148
|
+
const queryString = simpleQuery.map( k => ""+k+"="+options.query[k]).join("&");
|
|
149
|
+
request += "?" + queryString;
|
|
150
|
+
}
|
|
151
|
+
return this.fetchFeatures(request, options.abortSignal).then(cursor => cursor && cursor.hasNext() ? cursor.next() : null);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
query(receivedQuery?: OgcOpenApiFeatureStoreQueryOptions, options?: QueryOptions): Cursor | Promise<Cursor> {
|
|
155
|
+
const query = receivedQuery ? { ...receivedQuery } : {};
|
|
156
|
+
query.f = query.f ? query.f : this.dataFormat;
|
|
157
|
+
query.crs = query.crs ? query.crs : this.customCrs;
|
|
158
|
+
query.limit = query.limit ? query.limit : undefined;
|
|
159
|
+
let request = this.baseUrl;
|
|
160
|
+
|
|
161
|
+
const allKeys = Object.keys(query);
|
|
162
|
+
if (allKeys.length>0) {
|
|
163
|
+
const filteredKeys = allKeys.filter(e => (typeof query[e] !== "undefined" && query[e] !== null));
|
|
164
|
+
const indexOfFormat = filteredKeys.indexOf("f");
|
|
165
|
+
if (indexOfFormat > -1) {
|
|
166
|
+
filteredKeys.splice(indexOfFormat, 1);
|
|
167
|
+
filteredKeys.unshift("f");
|
|
168
|
+
}
|
|
169
|
+
const queryString = filteredKeys.map( k => ""+k+"="+query[k]).join("&");
|
|
170
|
+
request += "?" + queryString;
|
|
171
|
+
}
|
|
172
|
+
return this.fetchFeatures(request, options?.abortSignal);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Fetches and decodes features. The promise always settles: it rejects with the reason when the request,
|
|
176
|
+
// the response or the decoding fails, and when LuciadRIA aborts the request through abortSignal.
|
|
177
|
+
private fetchFeatures(request: string, abortSignal?: AbortSignal): Promise<Cursor> {
|
|
178
|
+
// Mod starta
|
|
179
|
+
const itemsAccept =
|
|
180
|
+
typeof this.requestHeaders.accept !== 'undefined'
|
|
181
|
+
? this.requestHeaders.accept.split(';')
|
|
182
|
+
: typeof this.requestHeaders.Accept !== 'undefined'
|
|
183
|
+
? this.requestHeaders.Accept.split(';')
|
|
184
|
+
: [];
|
|
185
|
+
itemsAccept.push(this.outputFormat);
|
|
186
|
+
const accept = itemsAccept.join(';');
|
|
187
|
+
// Mod end
|
|
188
|
+
const headers = { ...this.requestHeaders, Accept: accept };
|
|
189
|
+
return OgcOpenApiFetchTools.fetch(request, {
|
|
190
|
+
method: 'GET',
|
|
191
|
+
credentials: this.credentials ? "same-origin": "omit",
|
|
192
|
+
headers,
|
|
193
|
+
signal: abortSignal,
|
|
194
|
+
}, this.serverOptions).then((response) => {
|
|
195
|
+
if (response.status !== 200) {
|
|
196
|
+
throw new Error("Invalid response: " + response.status + " for " + request);
|
|
197
|
+
}
|
|
198
|
+
return response.text().then((content) => {
|
|
199
|
+
let contentType = response.headers.get('Content-Type');
|
|
200
|
+
const contentCrs = response.headers.get('content-crs') ? response.headers.get('content-crs') : this.customCrs;
|
|
201
|
+
const contentLengthStr = response.headers.get('Content-Length');
|
|
202
|
+
const contentLength = Number(contentLengthStr);
|
|
203
|
+
contentType = contentType ? contentType : 'text/plain';
|
|
204
|
+
// GeoJsonCodec reads the CRS84 URI, GML is given the URN
|
|
205
|
+
content = content
|
|
206
|
+
.split('srsName="http://www.opengis.net/def/crs/OGC/1.3/CRS84"')
|
|
207
|
+
.join('srsName="urn:ogc:def:crs:OGC:1.3:CRS84"');
|
|
208
|
+
const codecOptions: OgcOpenApiFeaturesCodecDecodeOptions = {
|
|
209
|
+
content, contentType, contentCrs, contentLength
|
|
210
|
+
};
|
|
211
|
+
if (this.codec instanceof GeoJsonCodec || this.codec instanceof GMLCodec) {
|
|
212
|
+
return this.codec.decode({...codecOptions, reference: getReference(OgcOpenApiCrsTools.getReferenceName(contentCrs))});
|
|
213
|
+
}
|
|
214
|
+
return this.codec.decode(codecOptions);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
spatialQuery(
|
|
220
|
+
bounds?: Bounds,
|
|
221
|
+
receivedQuery?: OgcOpenApiFeatureStoreQueryOptions,
|
|
222
|
+
options?: QueryOptions
|
|
223
|
+
): Promise<Cursor> | Cursor {
|
|
224
|
+
const query = (receivedQuery ? { ...receivedQuery } : {}) as OgcOpenApiFeatureStoreQueryOptions;
|
|
225
|
+
delete query.bbox;
|
|
226
|
+
query.limit = query.limit ? query.limit : undefined;
|
|
227
|
+
if (bounds) {
|
|
228
|
+
if (this.useCrs84Bounds) {
|
|
229
|
+
const crs84Bounds = OgcOpenApiFeatureStore.getCRS84BoundingBox(bounds);
|
|
230
|
+
query.bbox = query.bbox
|
|
231
|
+
? query.bbox
|
|
232
|
+
: [
|
|
233
|
+
crs84Bounds.x,
|
|
234
|
+
crs84Bounds.y,
|
|
235
|
+
crs84Bounds.x + crs84Bounds.width,
|
|
236
|
+
crs84Bounds.y + crs84Bounds.height,
|
|
237
|
+
];
|
|
238
|
+
} else {
|
|
239
|
+
query.bbox = query.bbox
|
|
240
|
+
? query.bbox
|
|
241
|
+
: [
|
|
242
|
+
bounds.x,
|
|
243
|
+
bounds.y,
|
|
244
|
+
bounds.x + bounds.width,
|
|
245
|
+
bounds.y + bounds.height,
|
|
246
|
+
];
|
|
247
|
+
if (this.customCrs) {
|
|
248
|
+
query["bbox-crs"] = this.customCrs;
|
|
249
|
+
}
|
|
250
|
+
const referenceName = OgcOpenApiCrsTools.getReferenceName(this.customCrs);
|
|
251
|
+
if (this.swapAxes && this.swapAxes.findIndex(f=>f===referenceName)>-1) {
|
|
252
|
+
query.bbox = [query.bbox[1], query.bbox[0],query.bbox[3], query.bbox[2]]
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return this.query(query, options);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private static getCRS84BoundingBox(shape: Bounds) {
|
|
260
|
+
const WGS84 = getReference("CRS:84");
|
|
261
|
+
const bounds = shape.bounds;
|
|
262
|
+
const toWgs84 = createTransformation(bounds.reference, WGS84);
|
|
263
|
+
return toWgs84.transformBounds(bounds);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private static targetBounds(bounds: Bounds, targetReferenceBounds: CoordinateReference) {
|
|
267
|
+
const WGS84 = getReference("CRS:84");
|
|
268
|
+
const toTargetReference = createTransformation(WGS84, targetReferenceBounds);
|
|
269
|
+
return toTargetReference.transformBounds(bounds);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
private static cleanUrl(dataUrl: string, addSlash=false) {
|
|
273
|
+
const parts = dataUrl.split('?');
|
|
274
|
+
return parts[0].endsWith('/') ? parts[0] : (addSlash ? parts[0] + '/' : parts[0]);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private static dataFormatInQuery(dataUrl: string) {
|
|
278
|
+
let format;
|
|
279
|
+
const parts = dataUrl.split('?');
|
|
280
|
+
if (parts.length > 1) {
|
|
281
|
+
const query = parts[1];
|
|
282
|
+
const qs = query.split('&');
|
|
283
|
+
for (const q of qs) {
|
|
284
|
+
if (q.startsWith('f=')) {
|
|
285
|
+
format = q.slice(2);
|
|
286
|
+
return format;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return format;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export type {
|
|
295
|
+
OgcOpenApiFeaturesCodecDecodeOptions
|
|
296
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type {ProxifyFunction} from "./OgcOpenApiGetCapabilities.js";
|
|
2
|
+
|
|
3
|
+
interface ExtFetchOptions {
|
|
4
|
+
originalUrl: string;
|
|
5
|
+
complete?: (url: string) => string;
|
|
6
|
+
proxify?: ProxifyFunction
|
|
7
|
+
}
|
|
8
|
+
export interface FetchServerOptions {
|
|
9
|
+
proxy: (url: string, fetchOptions) => { fetchOptions: any; url: string };
|
|
10
|
+
hostname: string;
|
|
11
|
+
complete: (url: string) => string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Stand-ins for the braces of URL templates while resolving, URL keeps them as they are
|
|
15
|
+
const OPEN_BRACE = "__OGC_OPEN_BRACE__";
|
|
16
|
+
const CLOSE_BRACE = "__OGC_CLOSE_BRACE__";
|
|
17
|
+
|
|
18
|
+
class OgcOpenApiFetchTools {
|
|
19
|
+
|
|
20
|
+
public static createFetchOptions(options: ExtFetchOptions) {
|
|
21
|
+
const hostname = this.getHostURL(options.originalUrl);
|
|
22
|
+
return {
|
|
23
|
+
hostname: hostname,
|
|
24
|
+
complete: typeof options.complete === "function" ? options.complete : (url: string) => {
|
|
25
|
+
return this.addHostURL(url, hostname)
|
|
26
|
+
},
|
|
27
|
+
proxy: typeof options.proxify === "function" ? options.proxify : (url: string, fetchOptions) => ({
|
|
28
|
+
url: url,
|
|
29
|
+
fetchOptions: fetchOptions
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public static fetch(input: string, options: RequestInit, serverOptions: FetchServerOptions) {
|
|
35
|
+
const fullUrl = serverOptions.complete(input);
|
|
36
|
+
const result = serverOptions.proxy(fullUrl, options)
|
|
37
|
+
return fetch(result.url, result.fetchOptions);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A link of a document, resolved against the URL of that document (RFC 3986): ./x, ../x, x, /x and //host/x.
|
|
42
|
+
* Absolute links are kept as they are. Without an absolute document URL, as behind a relative proxy path, the link
|
|
43
|
+
* is completed with the host of the server.
|
|
44
|
+
*/
|
|
45
|
+
public static resolveUrl(href: string, documentUrl: string, serverOptions: FetchServerOptions) {
|
|
46
|
+
if (typeof href !== "string" || /^[a-z][a-z0-9+.-]*:/i.test(href)) return href;
|
|
47
|
+
if (!/^https?:\/\//i.test(documentUrl)) return serverOptions.complete(href);
|
|
48
|
+
// URL encodes { and } in paths, which tile URL templates use: {tileMatrix}/{tileRow}/{tileCol}
|
|
49
|
+
const resolved = new URL(href.replace(/\{/g, OPEN_BRACE).replace(/}/g, CLOSE_BRACE), documentUrl).href;
|
|
50
|
+
return resolved.split(OPEN_BRACE).join("{").split(CLOSE_BRACE).join("}");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public static addHostURL(url: string, HostUrl?: string) {
|
|
54
|
+
if (typeof url === "undefined") return url;
|
|
55
|
+
const hostUrl = HostUrl ? HostUrl : "";
|
|
56
|
+
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
57
|
+
return url;
|
|
58
|
+
} else {
|
|
59
|
+
if (url.startsWith("/")) return hostUrl + url;
|
|
60
|
+
if (url.startsWith("./")) return hostUrl + url.substring(1);
|
|
61
|
+
}
|
|
62
|
+
return hostUrl + "/" + url;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public static cleanUrl(inputUrl:string) {
|
|
66
|
+
return inputUrl.split("?")[0].replace(/\/?$/, '/');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public static cleanUrlToAsset(inputUrl:string) {
|
|
70
|
+
return inputUrl.split("?")[0].replace(/\/?$/, '');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public static getHostURL(fullUrl: string) {
|
|
74
|
+
if (!fullUrl.startsWith("http")) return "";
|
|
75
|
+
const pathArray = fullUrl.split( '/' );
|
|
76
|
+
const protocol = pathArray[0];
|
|
77
|
+
const host = pathArray[2];
|
|
78
|
+
return protocol + '//' + host;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export {
|
|
83
|
+
OgcOpenApiFetchTools
|
|
84
|
+
}
|