forked from SuperMap/iClient-JavaScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.js
More file actions
374 lines (340 loc) · 12.5 KB
/
util.js
File metadata and controls
374 lines (340 loc) · 12.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
import { isObject } from '../util/BaseUtil';
export function geojsonCoordsToPoint2Ds(coords) {
if (!coords) {
throw new Error('No GeoJSON coords provided');
}
if (!coords || coords.length === 0) {
return null;
}
const length = coords.length;
const dim = 2; // coords[0].length
const coordArr = new Float64Array(coords.flat());
const coordPtr = window.ugcModule._malloc(length * dim * 8);
window.ugcModule.HEAPF64.set(coordArr, coordPtr / 8);
const seqPtr = window.ugcModule._UGCWasm_Geometry_CreatePoint2DsFromBuffer(coordPtr, length);
window.ugcModule._free(coordPtr);
return seqPtr;
}
export function geojsonCoords2UGDoubleArray(coords) {
if (!coords) {
throw new Error('No GeoJSON coords provided')
}
if (!coords || coords.length === 0) {
return null
}
const length = coords.length
const coordArr = new Float64Array(coords)
const coordPtr = window.ugcModule._malloc(length * 8)
window.ugcModule.HEAPF64.set(coordArr, coordPtr / 8)
const pDoubleArray = window.ugcModule._UGCWasm_Helper_CreateDoubleArray(coordPtr, length)
window.ugcModule._free(coordPtr)
return pDoubleArray
}
export function getJSArrayFromUGDoubleArray(pDoubleArray) {
// get length of doublearray
var length = window.ugcModule._UGCWasm_Helper_GetDoubleArrayLength(pDoubleArray);
// allocate memory 一个double是8个字节
const pBuffer = window.ugcModule._malloc(length * 8);
// copy doublearray to buffer
window.ugcModule._UGCWasm_Helper_GetBufferFromDoubleArray(pDoubleArray, pBuffer);
// get double in buffer to Float64Array
const view = new Float64Array(window.ugcModule.HEAPF64.buffer, pBuffer, length);
const coords = [];
for (let i = 0; i < length; i++) {
coords.push(view[i]);
}
// free buffer memory
window.ugcModule._free(pBuffer);
return coords;
}
/**
* @private
* @description Convert UGC geometry pointer to GeoJSON object.
* @name ugGeometry2Geojson
* @kind function
* @param {number} pUGGeo - The UGC geometry pointer.
* @returns {GeoJSON} A GeoJSON object.
* @example
* import ugGeometry2Geojson from 'UGGeometry2GeoJson.js'
* const geos = await initGeosJs()
* const reader = geos.GEOSWKTReader_create()
* const wkt = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
* const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
* const json = geosGeomToGeojson(geomPtr, geos)
* console.log(JSON.stringify(json))
* // => {"type":"Polygon","coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]]}
*/
export function ugGeometry2Geojson(pUGGeo) {
// if (!pUGGeo) {
// throw new Error("No UGC geometry pointer provided");
// }
if (!pUGGeo) {
return null;
}
const geomType = window.ugcModule._UGCWasm_Geometry_GetType(pUGGeo);
switch (geomType) {
case 1: {
// UGGeoPoint
const point2d = [];
var x = window.ugcModule._UGCWasm_GeoPoint_GetX(pUGGeo);
var y = window.ugcModule._UGCWasm_GeoPoint_GetY(pUGGeo);
point2d.push(x, y)
// create geojson point
const pointJson = {
type: "Point",
coordinates: point2d
};
return pointJson
}
case 3: {
// UGGeoLine
const outlines = [];
// get part count
const partCount = window.ugcModule._UGCWasm_GeoLine_GetPartCount(pUGGeo);
for (let j = 0; j < partCount; j++) {
// get part j point count
var count = window.ugcModule._UGCWasm_GeoLine_GetPartPointCount(pUGGeo, j);
// 一个double是8个字节,而一个point2D是两个double,所以需要申请 点个数 * 2 * 8
const pBuffer = window.ugcModule._malloc(count * 2 * 8);
// get part j points
window.ugcModule._UGCWasm_GeoLine_GetPart2(pUGGeo, pBuffer, j);
// Float64Array to line part coordinates
const view = new Float64Array(window.ugcModule.HEAPF64.buffer, pBuffer, count * 2);
const coords = [];
for (let i = 0; i < count * 2; i = i + 2) {
coords.push([view[i], view[i + 1]]);
}
window.ugcModule._free(pBuffer);
outlines.push(coords);
}
// create geojson linestring
const linestringJson = {
type: "LineString",
coordinates: outlines[0]
};
return linestringJson
}
case 5: {
// UGGeoRegion
const outlines = [];
// get part count
const partCount = window.ugcModule._UGCWasm_GeoRegion_GetPartCount(pUGGeo);
for (let j = 0; j < partCount; j++) {
// get part j point count
const count = window.ugcModule._UGCWasm_GeoRegion_GetPartPointCount(pUGGeo, j);
// 一个double是8个字节,而一个point2D是两个double,所以需要申请 点个数 * 2 * 8
const pBuffer = window.ugcModule._malloc(count * 2 * 8);
// get part j points
window.ugcModule._UGCWasm_GeoRegion_GetPart2(pUGGeo, pBuffer, j);
// Float64Array to line part coordinates
const view = new Float64Array(window.ugcModule.HEAPF64.buffer, pBuffer, count * 2);
const coords = [];
for (let i = 0; i < count * 2; i = i + 2) {
coords.push([view[i], view[i + 1]]);
}
window.ugcModule._free(pBuffer);
outlines.push(coords);
}
// create geojson polygon
const polyJson = {
type: "Polygon",
coordinates: outlines
};
return polyJson
}
default:
return null;
}
}
/**
* @private
* @description 转换 GeoJSON 对象到 GEOS geometry pointer。
* @name geojsonToGeosGeom
* @param {GeoJSON} geojson - The GeoJSON object.
* @returns {number} A pointer to GEOS geometry
*/
export function geojson2UGGeometry(geojson) {
if (!geojson) {
throw new Error('No GeoJSON object provided')
}
// assume only 2d (x, y) geometries
switch (geojson.type) {
case 'Feature':
return geojson2UGGeometry(geojson.geometry)
case 'FeatureCollection':
if (geojson.features.length === 0) {
return null
} else {
return geojson2UGGeometry(geojson.features[0].geometry)
}
// case 'GeometryCollection':
// if (geojson.geometries.length === 0) {
// return geos.GEOSGeom_createEmptyCollection(7) // geos.GEOS_GEOMETRYCOLLECTION
// } else {
// const geoms = []
// // iterate over each feature
// geojson.geometries.forEach((feature) => {
// geoms.push(geojsonToGeosGeom(feature, geos))
// })
// const geomsPtr = geos.window.ugcModule._malloc(geoms.length * 4)
// const geomsArr = new Uint32Array(geoms)
// geos.window.ugcModule.HEAPU32.set(geomsArr, geomsPtr / 4)
// const multiGeomsPtr = geos.GEOSGeom_createCollection(
// 7, // geos.GEOS_GEOMETRYCOLLECTION
// geomsPtr,
// geoms.length
// )
// geos.window.ugcModule._free(geomsPtr)
// return multiGeomsPtr
// }
case 'Point':
if (geojson.coordinates.length === 0) {
return window.ugcModule._UGCWasm_GeoPoint_New()
} else {
return window.ugcModule._UGCWasm_GeoPoint_New2(
geojson.coordinates[0],
geojson.coordinates[1]
)
}
case 'LineString':
if (geojson.coordinates.length === 0) {
return window.ugcModule._UGCWasm_GeoLine_New()
} else {
const pGeoLine = window.ugcModule._UGCWasm_GeoLine_New()
const pPoint2Ds = geojsonCoordsToPoint2Ds(geojson.coordinates)
window.ugcModule._UGCWasm_GeoLine_AddPart2(pGeoLine, pPoint2Ds, geojson.coordinates.length)
return pGeoLine
}
case 'Polygon':
if (geojson.coordinates.length === 0) {
return window.ugcModule._UGCWasm_GeoRegion_New()
} else {
const pGeoRegion = window.ugcModule._UGCWasm_GeoRegion_New()
const pPoint2Ds0 = geojsonCoordsToPoint2Ds(geojson.coordinates[0])
window.ugcModule._UGCWasm_GeoRegion_AddPart2(pGeoRegion, pPoint2Ds0, geojson.coordinates[0].length)
if (geojson.coordinates.length > 1) {
for (let i = 1; i < geojson.coordinates.length; i++) {
const pPoint2Dsi = geojsonCoordsToPoint2Ds(geojson.coordinates[i])
window.ugcModule._UGCWasm_GeoRegion_AddPart2(pGeoRegion, pPoint2Dsi, geojson.coordinates[i].length)
}
}
return pGeoRegion
}
// case 'MultiPoint':
// if (geojson.coordinates.length === 0) {
// return geos.GEOSGeom_createEmptyCollection(4) // geos.GEOS_MULTIPOINT
// } else {
// const points = []
// for (let i = 0; i < geojson.coordinates.length; i++) {
// points.push(
// geos.GEOSGeom_createPointFromXY(
// geojson.coordinates[i][0],
// geojson.coordinates[i][1]
// )
// )
// }
// const pointsPtr = geos.window.ugcModule._malloc(points.length * 4)
// const pointsArr = new Uint32Array(points)
// geos.window.ugcModule.HEAPU32.set(pointsArr, pointsPtr / 4)
// const multiPointPtr = geos.GEOSGeom_createCollection(
// 4, // geos.GEOS_MULTIPOINT
// pointsPtr,
// points.length
// )
// geos.window.ugcModule._free(pointsPtr)
// return multiPointPtr
// }
case 'MultiLineString':
if (geojson.coordinates.length === 0) {
return window.ugcModule._UGCWasm_GeoLine_New()
} else {
const pGeoLine = window.ugcModule._UGCWasm_GeoLine_New()
const pPoint2Ds0 = geojsonCoordsToPoint2Ds(geojson.coordinates[0])
window.ugcModule._UGCWasm_GeoLine_AddPart2(pGeoLine, pPoint2Ds0, geojson.coordinates[0].length)
if (geojson.coordinates.length > 1) {
for (let i = 1; i < geojson.coordinates.length; i++) {
const pPoint2Dsi = geojsonCoordsToPoint2Ds(geojson.coordinates[i])
window.ugcModule._UGCWasm_GeoLine_AddPart2(pGeoLine, pPoint2Dsi, geojson.coordinates[i].length)
}
}
return pGeoLine
}
// case 'MultiPolygon':
// if (geojson.coordinates.length === 0) {
// return geos.GEOSGeom_createEmptyCollection(6) // geos.GEOS_MULTIPOLYGON
// } else {
// const polygons = []
// for (let i = 0; i < geojson.coordinates.length; i++) {
// const shellSeq = geojsonCoordsToGeosCoordSeq(
// geojson.coordinates[i][0]
// )
// const shell = geos.GEOSGeom_createLinearRing(shellSeq)
// const holes = []
// if (geojson.coordinates[i].length > 1) {
// for (let j = 1; j < geojson.coordinates[i].length; j++) {
// const holeSeq = geojsonCoordsToGeosCoordSeq(
// geojson.coordinates[i][j]
// )
// holes.push(geos.GEOSGeom_createLinearRing(holeSeq))
// }
// }
// let holesPtr = null
// if (holes.length > 0) {
// const holesArr = new Uint32Array(holes)
// holesPtr = geos.window.ugcModule._malloc(holes.length * 4)
// geos.window.ugcModule.HEAPU32.set(holesArr, holesPtr / 4)
// }
// const polyPtr = geos.GEOSGeom_createPolygon(
// shell,
// holesPtr,
// holes.length
// )
// if (holes.length > 0) {
// geos.window.ugcModule._free(holesPtr)
// }
// polygons.push(polyPtr)
// }
// const polygonsPtr = geos.window.ugcModule._malloc(polygons.length * 4)
// const polygonsArr = new Uint32Array(polygons)
// geos.window.ugcModule.HEAPU32.set(polygonsArr, polygonsPtr / 4)
// const multiPolyPtr = geos.GEOSGeom_createCollection(
// 6, // geos.GEOS_MULTIPOLYGON
// polygonsPtr,
// polygons.length
// )
// geos.window.ugcModule._free(polygonsPtr)
// return multiPolyPtr
// }
default:
throw new Error('Unsupported GeoJSON type: ' + geojson.type + '. Are you sure this is valid GeoJSON?')
}
}
export function formatCoord(pointList) {
let xList = [];
let yList = [];
if (isObject(pointList) && pointList.type === 'FeatureCollection') {
pointList.features.forEach((feature) => {
const coord = feature.geometry.coordinates;
xList.push(coord[0]);
yList.push(coord[1])
});
} else if (Array.isArray(pointList)) {
pointList.forEach((item) => {
if (item.type === 'Feature') {
const coord = item.geometry.coordinates;
xList.push(coord[0]);
yList.push(coord[1])
} else if (Array.isArray(item)) {
xList.push(item[0]);
yList.push(item[1])
} else if (isObject(item)) {
xList.push(item.x);
yList.push(item.y)
}
});
}
return {
xList,
yList
}
}