@vcmap/core 5.0.0-rc.2 → 5.0.0-rc.3
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/index.d.ts +57 -27
- package/index.js +1 -1
- package/package.json +1 -1
- package/src/vcs/vcm/interaction/coordinateAtPixel.js +1 -1
- package/src/vcs/vcm/layer/oblique/obliqueHelpers.js +2 -2
- package/src/vcs/vcm/layer/terrainHelpers.js +4 -8
- package/src/vcs/vcm/maps/oblique.js +6 -6
- package/src/vcs/vcm/oblique/ObliqueCollection.js +83 -31
- package/src/vcs/vcm/oblique/ObliqueDataSet.js +60 -17
- package/src/vcs/vcm/oblique/ObliqueImage.js +1 -1
- package/src/vcs/vcm/oblique/ObliqueImageMeta.js +2 -2
- package/src/vcs/vcm/oblique/ObliqueProvider.js +10 -7
- package/src/vcs/vcm/oblique/helpers.js +12 -40
- package/src/vcs/vcm/oblique/parseImageJson.js +17 -9
- package/src/vcs/vcm/util/extent.js +11 -1
- package/src/vcs/vcm/util/indexedCollection.js +23 -0
- package/src/vcs/vcm/util/layerCollection.js +10 -5
- package/src/vcs/vcm/util/projection.js +37 -3
- package/src/vcs/vcm/util/viewpoint.js +3 -0
package/index.d.ts
CHANGED
|
@@ -3124,7 +3124,7 @@ export function sampleCesiumTerrain(terrainProvider: import("@vcmap/cesium").Ces
|
|
|
3124
3124
|
* changes input coordinate Array in place, new height can also be accessed by coordinates[x][2]
|
|
3125
3125
|
* @param [optSourceProjection] - if input is not WGS84
|
|
3126
3126
|
*/
|
|
3127
|
-
export function getHeightFromTerrainProvider(terrainProvider: import("@vcmap/cesium").CesiumTerrainProvider, coordinates: import("ol/coordinate").Coordinate[], optSourceProjection?: Projection
|
|
3127
|
+
export function getHeightFromTerrainProvider(terrainProvider: import("@vcmap/cesium").CesiumTerrainProvider, coordinates: import("ol/coordinate").Coordinate[], optSourceProjection?: Projection, result?: import("ol/coordinate").Coordinate[]): Promise<import("ol/coordinate").Coordinate[]>;
|
|
3128
3128
|
|
|
3129
3129
|
/**
|
|
3130
3130
|
* checks, whether a terrain tile is available at given position or not
|
|
@@ -5158,7 +5158,7 @@ export class Oblique extends BaseOLMap {
|
|
|
5158
5158
|
switchThreshold: any;
|
|
5159
5159
|
mapChangeEvent: any;
|
|
5160
5160
|
readonly collection: ObliqueCollection;
|
|
5161
|
-
readonly imageChanged:
|
|
5161
|
+
readonly imageChanged: VcsEvent<ObliqueImage>;
|
|
5162
5162
|
readonly currentImage: ObliqueImage | null;
|
|
5163
5163
|
getExtentOfCurrentImage(): Extent;
|
|
5164
5164
|
getCurrentImage(): ObliqueImage;
|
|
@@ -5365,9 +5365,14 @@ export interface ObliqueVersion {
|
|
|
5365
5365
|
buildNumber: number;
|
|
5366
5366
|
}
|
|
5367
5367
|
|
|
5368
|
-
export interface
|
|
5369
|
-
|
|
5370
|
-
|
|
5368
|
+
export interface ObliqueDataSetOptions {
|
|
5369
|
+
url: string;
|
|
5370
|
+
projection?: ProjectionOptions;
|
|
5371
|
+
terrainProvider?: TerrainProviderOptions;
|
|
5372
|
+
}
|
|
5373
|
+
|
|
5374
|
+
export interface ObliqueCollectionOptions extends VcsObjectOptions {
|
|
5375
|
+
dataSets?: (ObliqueDataSet | ObliqueDataSetOptions)[];
|
|
5371
5376
|
maxZoom?: number | undefined;
|
|
5372
5377
|
minZoom?: number | undefined;
|
|
5373
5378
|
scaleFactor?: number | undefined;
|
|
@@ -5376,16 +5381,13 @@ export interface ObliqueCollectionOptions {
|
|
|
5376
5381
|
|
|
5377
5382
|
export class ObliqueCollection {
|
|
5378
5383
|
constructor(options: ObliqueCollectionOptions);
|
|
5379
|
-
|
|
5380
|
-
* The unique name of the collection
|
|
5381
|
-
*/
|
|
5382
|
-
name: string;
|
|
5384
|
+
static getDefaultOptions(): ObliqueCollectionOptions;
|
|
5383
5385
|
viewOptions: ObliqueViewOptions;
|
|
5384
5386
|
|
|
5385
5387
|
/**
|
|
5386
5388
|
* Event raised when images are loaded. Is passed an Array of ObliqueImages as its only argument.
|
|
5387
5389
|
*/
|
|
5388
|
-
imagesLoaded:
|
|
5390
|
+
imagesLoaded: VcsEvent<ObliqueImage[]>;
|
|
5389
5391
|
readonly dataSets: ObliqueDataSet[];
|
|
5390
5392
|
/**
|
|
5391
5393
|
* Indicates, that this collection has been loaded
|
|
@@ -5476,6 +5478,20 @@ export class ObliqueCollection {
|
|
|
5476
5478
|
* Destroys all data sets and all images and any image/tile features for this collection
|
|
5477
5479
|
*/
|
|
5478
5480
|
destroy(): void;
|
|
5481
|
+
toJSON(): ObliqueCollectionOptions;
|
|
5482
|
+
}
|
|
5483
|
+
|
|
5484
|
+
/**
|
|
5485
|
+
*/
|
|
5486
|
+
export interface ObliqueDataSetImagesLoaded {
|
|
5487
|
+
/**
|
|
5488
|
+
* the loaded images
|
|
5489
|
+
*/
|
|
5490
|
+
images: ObliqueImage[];
|
|
5491
|
+
/**
|
|
5492
|
+
* an optional tile coordinate
|
|
5493
|
+
*/
|
|
5494
|
+
tileCoordinate?: string;
|
|
5479
5495
|
}
|
|
5480
5496
|
|
|
5481
5497
|
/**
|
|
@@ -5490,16 +5506,14 @@ export const enum DataState {
|
|
|
5490
5506
|
export function getStateFromStatesArray(states: DataState[]): DataState;
|
|
5491
5507
|
|
|
5492
5508
|
export class ObliqueDataSet {
|
|
5493
|
-
constructor(url: string, projection:
|
|
5509
|
+
constructor(url: string, projection: Projection | ProjectionOptions, terrainProviderOptions?: TerrainProviderOptions);
|
|
5494
5510
|
url: string;
|
|
5495
5511
|
baseUrl: string;
|
|
5496
|
-
projection:
|
|
5497
|
-
terrainProvider: import("@vcmap/cesium").CesiumTerrainProvider | undefined;
|
|
5512
|
+
projection: Projection;
|
|
5498
5513
|
/**
|
|
5499
|
-
* Event raised when images are loaded.
|
|
5500
|
-
* a string representing the tile coordinate ("z/x/y"), if the images where loaded for a tile.
|
|
5514
|
+
* Event raised when images are loaded.
|
|
5501
5515
|
*/
|
|
5502
|
-
imagesLoaded:
|
|
5516
|
+
imagesLoaded: VcsEvent<ObliqueDataSetImagesLoaded>;
|
|
5503
5517
|
|
|
5504
5518
|
|
|
5505
5519
|
|
|
@@ -5513,6 +5527,7 @@ export class ObliqueDataSet {
|
|
|
5513
5527
|
* reflect the state of loaded tiles.
|
|
5514
5528
|
*/
|
|
5515
5529
|
readonly state: DataState;
|
|
5530
|
+
readonly terrainProvider: import("@vcmap/cesium").CesiumTerrainProvider | undefined;
|
|
5516
5531
|
/**
|
|
5517
5532
|
* Loads the data set.
|
|
5518
5533
|
*/
|
|
@@ -5546,6 +5561,7 @@ export class ObliqueDataSet {
|
|
|
5546
5561
|
* Loads all the tiles for a given extent.
|
|
5547
5562
|
*/
|
|
5548
5563
|
loadDataForExtent(extent: import("ol/extent").Extent): Promise<void>;
|
|
5564
|
+
toJSON(): ObliqueDataSetOptions;
|
|
5549
5565
|
}
|
|
5550
5566
|
|
|
5551
5567
|
export interface ObliqueImageOptions {
|
|
@@ -5558,7 +5574,7 @@ export interface ObliqueImageOptions {
|
|
|
5558
5574
|
projectionCenter?: import("@vcmap/cesium").Cartesian3 | undefined;
|
|
5559
5575
|
pToRealworld?: import("@vcmap/cesium").Matrix3 | undefined;
|
|
5560
5576
|
pToImage?: import("@vcmap/cesium").Matrix4 | undefined;
|
|
5561
|
-
projection?:
|
|
5577
|
+
projection?: Projection | undefined;
|
|
5562
5578
|
terrainProvider?: import("@vcmap/cesium").CesiumTerrainProvider | undefined;
|
|
5563
5579
|
}
|
|
5564
5580
|
|
|
@@ -5624,7 +5640,7 @@ export interface ObliqueImageMetaOptions {
|
|
|
5624
5640
|
size: import("ol/size").Size;
|
|
5625
5641
|
tileSize: import("ol/size").Size;
|
|
5626
5642
|
tileResolution: number[];
|
|
5627
|
-
projection:
|
|
5643
|
+
projection: Projection;
|
|
5628
5644
|
url: string;
|
|
5629
5645
|
terrainProvider: import("@vcmap/cesium").CesiumTerrainProvider;
|
|
5630
5646
|
name: string;
|
|
@@ -5657,7 +5673,7 @@ export class ObliqueImageMeta {
|
|
|
5657
5673
|
/**
|
|
5658
5674
|
* The world projection of the images associated with this meta
|
|
5659
5675
|
*/
|
|
5660
|
-
projection:
|
|
5676
|
+
projection: Projection;
|
|
5661
5677
|
url: string;
|
|
5662
5678
|
/**
|
|
5663
5679
|
* An optional terrain provider
|
|
@@ -5692,7 +5708,7 @@ export class ObliqueProvider {
|
|
|
5692
5708
|
/**
|
|
5693
5709
|
* Event raised once a new image is set on the provider. Will be passed the new image as the only argument.
|
|
5694
5710
|
*/
|
|
5695
|
-
imageChanged:
|
|
5711
|
+
imageChanged: VcsEvent<ObliqueImage>;
|
|
5696
5712
|
/**
|
|
5697
5713
|
* Whether the post render handler should switch on image edge. Setting
|
|
5698
5714
|
* this to false will suspend all post render handler switches.
|
|
@@ -5821,7 +5837,7 @@ export interface ImageTransformationOptions {
|
|
|
5821
5837
|
/**
|
|
5822
5838
|
* the projection of the input/output coordinates, assumes image source projection
|
|
5823
5839
|
*/
|
|
5824
|
-
dataProjection?:
|
|
5840
|
+
dataProjection?: Projection | undefined;
|
|
5825
5841
|
/**
|
|
5826
5842
|
* the transformToWorld process iterativly calculates a new Height Value from the terrainProvider until the difference to the new height value is smaller
|
|
5827
5843
|
*/
|
|
@@ -5858,17 +5874,12 @@ export function transformFromImage(image: ObliqueImage, imageCoordinate: import(
|
|
|
5858
5874
|
|
|
5859
5875
|
export function hasSameOrigin(url: string): boolean;
|
|
5860
5876
|
|
|
5861
|
-
/**
|
|
5862
|
-
* destroys a cesium Event Emitter, (removes all listeners)
|
|
5863
|
-
*/
|
|
5864
|
-
export function destroyCesiumEvent(cesiumEvent: import("@vcmap/cesium").Event): void;
|
|
5865
|
-
|
|
5866
5877
|
/**
|
|
5867
5878
|
* @returns version
|
|
5868
5879
|
*/
|
|
5869
5880
|
export function getVersionFromImageJson(json: any): ObliqueVersion;
|
|
5870
5881
|
|
|
5871
|
-
export function parseImageMeta(json: ObliqueImageJson, url: string, projection?:
|
|
5882
|
+
export function parseImageMeta(json: ObliqueImageJson, url: string, projection?: Projection, terrainProvider?: import("@vcmap/cesium").CesiumTerrainProvider): ObliqueImageMeta[];
|
|
5872
5883
|
|
|
5873
5884
|
export function parseImageData(json: ObliqueImageJson, imageMetas: ObliqueImageMeta[]): ObliqueImage[];
|
|
5874
5885
|
|
|
@@ -6181,6 +6192,7 @@ export interface ExtentOptions extends ProjectionOptions {
|
|
|
6181
6192
|
*/
|
|
6182
6193
|
export class Extent {
|
|
6183
6194
|
constructor(options?: ExtentOptions);
|
|
6195
|
+
static className: string;
|
|
6184
6196
|
projection: Projection;
|
|
6185
6197
|
extent: import("ol/extent").Extent | null;
|
|
6186
6198
|
getCoordinatesInProjection(destination: Projection, result?: import("ol/extent").Extent): import("ol/extent").Extent;
|
|
@@ -6578,6 +6590,11 @@ export class IndexedCollection<T extends any> extends Collection<T> {
|
|
|
6578
6590
|
* Event raised if an item is relocated within the collection. Is passed the moved item.
|
|
6579
6591
|
*/
|
|
6580
6592
|
moved: VcsEvent<T>;
|
|
6593
|
+
/**
|
|
6594
|
+
* Get the symbol which is attached to an item prior to its removal. If an item is removed, the current index of the item
|
|
6595
|
+
* is set on the item with this symbol.
|
|
6596
|
+
*/
|
|
6597
|
+
readonly previousIndexSymbol: symbol;
|
|
6581
6598
|
/**
|
|
6582
6599
|
* Returns an item at index.
|
|
6583
6600
|
*/
|
|
@@ -6589,6 +6606,7 @@ export class IndexedCollection<T extends any> extends Collection<T> {
|
|
|
6589
6606
|
* @returns the index at which the item was inserted
|
|
6590
6607
|
*/
|
|
6591
6608
|
add(item: T, index?: number): number | null;
|
|
6609
|
+
remove(item: T): void;
|
|
6592
6610
|
protected _move(item: T, itemIndex: number, targetIndex: number): number;
|
|
6593
6611
|
/**
|
|
6594
6612
|
* Lowers an item within the array
|
|
@@ -6626,6 +6644,12 @@ export class LayerCollection extends IndexedCollection<Layer> {
|
|
|
6626
6644
|
* The exclusive manager for this collection. Layers within this collection are automatically added and tracked.
|
|
6627
6645
|
*/
|
|
6628
6646
|
exclusiveManager: ExclusiveManager;
|
|
6647
|
+
/**
|
|
6648
|
+
* A symbol to describe the local z index of a layer. The local z index must not equal the layers z index, but is
|
|
6649
|
+
* always consistent in comparison to the neighbouring layers. If a layer is moved other then by z index, the collection
|
|
6650
|
+
* ensures consistency by setting a new local z index if needed.
|
|
6651
|
+
*/
|
|
6652
|
+
readonly zIndexSymbol: symbol;
|
|
6629
6653
|
/**
|
|
6630
6654
|
* Adds a layer to the collection. Can optionally be passed an index at which to insert the layer.
|
|
6631
6655
|
* @returns returns the layer index or null, if the layers name is not unique
|
|
@@ -6745,6 +6769,7 @@ export function cartesian3DDistance(p1: import("ol/coordinate").Coordinate, p2:
|
|
|
6745
6769
|
/**
|
|
6746
6770
|
*/
|
|
6747
6771
|
export interface ProjectionOptions {
|
|
6772
|
+
type?: string;
|
|
6748
6773
|
/**
|
|
6749
6774
|
* EPSG of the projection, for example: "EPSG:4326" if not specified, uses the framework projection
|
|
6750
6775
|
*/
|
|
@@ -6757,6 +6782,10 @@ export interface ProjectionOptions {
|
|
|
6757
6782
|
* aliases to define
|
|
6758
6783
|
*/
|
|
6759
6784
|
alias?: string[] | undefined | null;
|
|
6785
|
+
/**
|
|
6786
|
+
* an alternate prefix to use for custom projection
|
|
6787
|
+
*/
|
|
6788
|
+
prefix?: string | undefined;
|
|
6760
6789
|
}
|
|
6761
6790
|
|
|
6762
6791
|
/**
|
|
@@ -6770,6 +6799,7 @@ export function setDefaultProjectionOptions(options: ProjectionOptions): void;
|
|
|
6770
6799
|
*/
|
|
6771
6800
|
export class Projection {
|
|
6772
6801
|
constructor(options: ProjectionOptions);
|
|
6802
|
+
static className: any;
|
|
6773
6803
|
/**
|
|
6774
6804
|
* epsg code in the format "EPSG:25832"
|
|
6775
6805
|
*/
|
package/index.js
CHANGED
|
@@ -98,7 +98,7 @@ export { default as ObliqueImageMeta } from './src/vcs/vcm/oblique/ObliqueImageM
|
|
|
98
98
|
export { default as ObliqueProvider } from './src/vcs/vcm/oblique/ObliqueProvider.js';
|
|
99
99
|
export { default as ObliqueView } from './src/vcs/vcm/oblique/ObliqueView.js';
|
|
100
100
|
export { ObliqueViewDirection, obliqueViewDirectionNames, getDirectionName } from './src/vcs/vcm/oblique/ObliqueViewDirection.js';
|
|
101
|
-
export { sortRealWordEdgeCoordinates, checkLineIntersection, transformCWIFC, transformToImage, transformFromImage, hasSameOrigin
|
|
101
|
+
export { sortRealWordEdgeCoordinates, checkLineIntersection, transformCWIFC, transformToImage, transformFromImage, hasSameOrigin } from './src/vcs/vcm/oblique/helpers.js';
|
|
102
102
|
export { getVersionFromImageJson, parseImageMeta, parseImageData, parseLegacyImageData } from './src/vcs/vcm/oblique/parseImageJson.js';
|
|
103
103
|
export { default as ClippingObject } from './src/vcs/vcm/util/clipping/clippingObject.js';
|
|
104
104
|
export { default as ClippingObjectManager } from './src/vcs/vcm/util/clipping/clippingObjectManager.js';
|
package/package.json
CHANGED
|
@@ -85,7 +85,7 @@ class CoordinateAtPixel extends AbstractInteraction {
|
|
|
85
85
|
if (Number.isFinite(pixel[0]) && Number.isFinite(pixel[1])) {
|
|
86
86
|
return transformFromImage(image, pixel, {
|
|
87
87
|
dontUseTerrain: !!move,
|
|
88
|
-
dataProjection: mercatorProjection
|
|
88
|
+
dataProjection: mercatorProjection,
|
|
89
89
|
}).then((coordinates) => {
|
|
90
90
|
event.obliqueParameters = { pixel };
|
|
91
91
|
event.position = coordinates.coords;
|
|
@@ -91,7 +91,7 @@ export async function mercatorGeometryToImageGeometry(inputSourceGeometry, desti
|
|
|
91
91
|
const coordinates = sourceGeometry.getCoordinates();
|
|
92
92
|
/** type {Array.<import("ol/coordinate").Coordinate>} */
|
|
93
93
|
const flattenCoordinates = getFlatCoordinatesFromGeometry(sourceGeometry, coordinates);
|
|
94
|
-
let transformer = getTransform(mercatorProjection.proj, image.meta.projection);
|
|
94
|
+
let transformer = getTransform(mercatorProjection.proj, image.meta.projection.proj);
|
|
95
95
|
|
|
96
96
|
let updatedPositions = [];
|
|
97
97
|
if (image.meta.terrainProvider) {
|
|
@@ -99,7 +99,7 @@ export async function mercatorGeometryToImageGeometry(inputSourceGeometry, desti
|
|
|
99
99
|
Projection.mercatorToWgs84(coord, true);
|
|
100
100
|
return Cartographic.fromDegrees(coord[0], coord[1]);
|
|
101
101
|
});
|
|
102
|
-
transformer = getTransform(wgs84Projection.proj, image.meta.projection);
|
|
102
|
+
transformer = getTransform(wgs84Projection.proj, image.meta.projection.proj);
|
|
103
103
|
updatedPositions = await sampleTerrainMostDetailed(image.meta.terrainProvider, cartographicCoordinates);
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CesiumTerrainProvider, Cartographic, Cartesian2, sampleTerrainMostDetailed, sampleTerrain } from '@vcmap/cesium';
|
|
2
2
|
import { getTransform } from 'ol/proj.js';
|
|
3
|
-
import
|
|
3
|
+
import { wgs84Projection } from '../util/projection.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @typedef {Object} TerrainProviderOptions
|
|
@@ -69,18 +69,14 @@ export function sampleCesiumTerrain(terrainProvider, level, positions) {
|
|
|
69
69
|
* changes input coordinate Array in place, new height can also be accessed by coordinates[x][2]
|
|
70
70
|
* @param {import("@vcmap/cesium").CesiumTerrainProvider} terrainProvider
|
|
71
71
|
* @param {Array<import("ol/coordinate").Coordinate>} coordinates
|
|
72
|
-
* @param {
|
|
72
|
+
* @param {import("@vcmap/core").Projection=} optSourceProjection - if input is not WGS84
|
|
73
73
|
* @param {Array<import("ol/coordinate").Coordinate>=} result
|
|
74
74
|
* @returns {Promise<Array<import("ol/coordinate").Coordinate>>}
|
|
75
75
|
*/
|
|
76
76
|
export function getHeightFromTerrainProvider(terrainProvider, coordinates, optSourceProjection, result) {
|
|
77
|
-
const
|
|
78
|
-
optSourceProjection.proj :
|
|
79
|
-
optSourceProjection;
|
|
80
|
-
|
|
81
|
-
const sourceTransformer = usedProj ?
|
|
77
|
+
const sourceTransformer = optSourceProjection ?
|
|
82
78
|
getTransform(
|
|
83
|
-
|
|
79
|
+
optSourceProjection.proj,
|
|
84
80
|
wgs84Projection.proj,
|
|
85
81
|
) :
|
|
86
82
|
null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { boundingExtent, containsXY } from 'ol/extent.js';
|
|
2
|
-
import {
|
|
2
|
+
import { getTransform, transform, transformExtent } from 'ol/proj.js';
|
|
3
3
|
import { check } from '@vcsuite/check';
|
|
4
4
|
import { parseBoolean, parseNumber } from '@vcsuite/parsers';
|
|
5
5
|
import Extent from '../util/extent.js';
|
|
@@ -243,7 +243,7 @@ class Oblique extends BaseOLMap {
|
|
|
243
243
|
get collection() { return this._obliqueProvider.collection; }
|
|
244
244
|
|
|
245
245
|
/**
|
|
246
|
-
* @type {import("@vcmap/
|
|
246
|
+
* @type {import("@vcmap/core").VcsEvent<import("@vcmap/core").ObliqueImage>}
|
|
247
247
|
* @readonly
|
|
248
248
|
* @api
|
|
249
249
|
*/
|
|
@@ -294,7 +294,7 @@ class Oblique extends BaseOLMap {
|
|
|
294
294
|
if (image) {
|
|
295
295
|
const coords = boundingExtent(image.groundCoordinates);
|
|
296
296
|
return new Extent({
|
|
297
|
-
coordinates: transformExtent(coords, image.meta.projection, mercatorProjection.proj),
|
|
297
|
+
coordinates: transformExtent(coords, image.meta.projection.proj, mercatorProjection.proj),
|
|
298
298
|
epsg: 'EPSG:3857',
|
|
299
299
|
});
|
|
300
300
|
}
|
|
@@ -399,7 +399,7 @@ class Oblique extends BaseOLMap {
|
|
|
399
399
|
return null;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
const transformationOptions = { dataProjection:
|
|
402
|
+
const transformationOptions = { dataProjection: wgs84Projection };
|
|
403
403
|
const { coords } = await transformFromImage(image, viewCenter, transformationOptions);
|
|
404
404
|
return this._computeViewpointInternal(coords);
|
|
405
405
|
}
|
|
@@ -421,7 +421,7 @@ class Oblique extends BaseOLMap {
|
|
|
421
421
|
|
|
422
422
|
const gpInternalProjection = image.transformImage2RealWorld(gpImageCoordinates, image.averageHeight);
|
|
423
423
|
|
|
424
|
-
const transfrom = getTransform(image.meta.projection, wgs84Projection.proj);
|
|
424
|
+
const transfrom = getTransform(image.meta.projection.proj, wgs84Projection.proj);
|
|
425
425
|
const gpWGS84 = transfrom(gpInternalProjection.slice(0, 2));
|
|
426
426
|
return this._computeViewpointInternal(gpWGS84);
|
|
427
427
|
}
|
|
@@ -489,7 +489,7 @@ class Oblique extends BaseOLMap {
|
|
|
489
489
|
const bl = image.transformImage2RealWorld([extent[0], extent[1]]);
|
|
490
490
|
const ur = image.transformImage2RealWorld([extent[2], extent[3]]);
|
|
491
491
|
const bbox = [bl[0], bl[1], ur[0], ur[1]];
|
|
492
|
-
const transformedBbox = transformExtent(bbox, image.meta.projection, wgs84Projection.proj);
|
|
492
|
+
const transformedBbox = transformExtent(bbox, image.meta.projection.proj, wgs84Projection.proj);
|
|
493
493
|
return containsXY(transformedBbox, coords[0], coords[1]);
|
|
494
494
|
}
|
|
495
495
|
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { parseInteger, parseNumber } from '@vcsuite/parsers';
|
|
1
2
|
import RBush from 'rbush';
|
|
2
3
|
import knn from 'rbush-knn';
|
|
3
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
4
4
|
import { getTransform } from 'ol/proj.js';
|
|
5
5
|
import { createXYZ } from 'ol/tilegrid.js';
|
|
6
6
|
import Feature from 'ol/Feature.js';
|
|
7
7
|
import Polygon, { fromExtent } from 'ol/geom/Polygon.js';
|
|
8
8
|
import Vector from 'ol/source/Vector.js';
|
|
9
9
|
import { boundingExtent, buffer, containsCoordinate, getCenter } from 'ol/extent.js';
|
|
10
|
-
import
|
|
11
|
-
import { DataState, getStateFromStatesArray } from './ObliqueDataSet.js';
|
|
10
|
+
import VcsEvent from '../event/vcsEvent.js';
|
|
11
|
+
import ObliqueDataSet, { DataState, getStateFromStatesArray } from './ObliqueDataSet.js';
|
|
12
12
|
import { ObliqueViewDirection } from './ObliqueViewDirection.js';
|
|
13
|
+
import { mercatorProjection } from '../util/projection.js';
|
|
14
|
+
import VcsObject from '../object.js';
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* @typedef {Object} ObliqueCameraOptions
|
|
@@ -52,13 +54,19 @@ import { ObliqueViewDirection } from './ObliqueViewDirection.js';
|
|
|
52
54
|
*/
|
|
53
55
|
|
|
54
56
|
/**
|
|
55
|
-
* @typedef {Object}
|
|
56
|
-
* @property {string
|
|
57
|
-
* @property {
|
|
58
|
-
* @property {
|
|
59
|
-
|
|
57
|
+
* @typedef {Object} ObliqueDataSetOptions
|
|
58
|
+
* @property {string} url
|
|
59
|
+
* @property {ProjectionOptions} [projection]
|
|
60
|
+
* @property {TerrainProviderOptions} [terrainProvider]
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @typedef {VcsObjectOptions} ObliqueCollectionOptions
|
|
65
|
+
* @property {Array<import("@vcmap/core").ObliqueDataSet|ObliqueDataSetOptions>} [dataSets]
|
|
66
|
+
* @property {number|undefined} [maxZoom]
|
|
67
|
+
* @property {number|undefined} [minZoom]
|
|
60
68
|
* @property {number|undefined} [scaleFactor=4]
|
|
61
|
-
* @property {number|undefined} hideLevels
|
|
69
|
+
* @property {number|undefined} [hideLevels]
|
|
62
70
|
* @api
|
|
63
71
|
*/
|
|
64
72
|
|
|
@@ -68,7 +76,7 @@ import { ObliqueViewDirection } from './ObliqueViewDirection.js';
|
|
|
68
76
|
*/
|
|
69
77
|
function getImageFeatures(images) {
|
|
70
78
|
return images.map((image) => {
|
|
71
|
-
const transform = getTransform(image.meta.projection,
|
|
79
|
+
const transform = getTransform(image.meta.projection.proj, mercatorProjection.proj);
|
|
72
80
|
const feature = new Feature({
|
|
73
81
|
geometry: new Polygon([image.groundCoordinates.map(c => transform(c.slice(0, 2)))]),
|
|
74
82
|
viewDirection: image.viewDirection,
|
|
@@ -103,18 +111,28 @@ function getTileFeatures(tiles) {
|
|
|
103
111
|
* @class
|
|
104
112
|
* @export
|
|
105
113
|
*/
|
|
106
|
-
class ObliqueCollection {
|
|
114
|
+
class ObliqueCollection extends VcsObject {
|
|
115
|
+
static get className() { return 'oblique.ObliqueCollection'; }
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @returns {ObliqueCollectionOptions}
|
|
119
|
+
*/
|
|
120
|
+
static getDefaultOptions() {
|
|
121
|
+
return {
|
|
122
|
+
maxZoom: 0,
|
|
123
|
+
minZoom: 0,
|
|
124
|
+
scaleFactor: 4,
|
|
125
|
+
dataSets: undefined,
|
|
126
|
+
hideLevels: 0,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
107
130
|
/**
|
|
108
131
|
* @param {ObliqueCollectionOptions} options
|
|
109
132
|
*/
|
|
110
133
|
constructor(options) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
* @type {string}
|
|
114
|
-
* @api
|
|
115
|
-
*/
|
|
116
|
-
this.name = options.name || uuidv4();
|
|
117
|
-
|
|
134
|
+
super(options);
|
|
135
|
+
const defaultOptions = ObliqueCollection.getDefaultOptions();
|
|
118
136
|
/**
|
|
119
137
|
* Maps each direction to an RTree
|
|
120
138
|
* @type {Map<import("@vcmap/core").ObliqueViewDirection, RBush>}
|
|
@@ -136,10 +154,10 @@ class ObliqueCollection {
|
|
|
136
154
|
|
|
137
155
|
/** @type {ObliqueViewOptions} */
|
|
138
156
|
this.viewOptions = {
|
|
139
|
-
maxZoom: options.maxZoom
|
|
140
|
-
minZoom: options.minZoom
|
|
141
|
-
scaleFactor: options.scaleFactor
|
|
142
|
-
hideLevels: options.hideLevels
|
|
157
|
+
maxZoom: parseInteger(options.maxZoom, defaultOptions.maxZoom),
|
|
158
|
+
minZoom: parseInteger(options.minZoom, defaultOptions.minZoom),
|
|
159
|
+
scaleFactor: parseNumber(options.scaleFactor, defaultOptions.scaleFactor),
|
|
160
|
+
hideLevels: parseInteger(options.hideLevels, defaultOptions.hideLevels),
|
|
143
161
|
};
|
|
144
162
|
|
|
145
163
|
/** @type {boolean} */
|
|
@@ -147,10 +165,10 @@ class ObliqueCollection {
|
|
|
147
165
|
|
|
148
166
|
/**
|
|
149
167
|
* Event raised when images are loaded. Is passed an Array of ObliqueImages as its only argument.
|
|
150
|
-
* @type {import("@vcmap/
|
|
168
|
+
* @type {import("@vcmap/core").VcsEvent<Array<import("@vcmap/core").ObliqueImage>>}
|
|
151
169
|
* @api
|
|
152
170
|
*/
|
|
153
|
-
this.imagesLoaded = new
|
|
171
|
+
this.imagesLoaded = new VcsEvent();
|
|
154
172
|
|
|
155
173
|
/**
|
|
156
174
|
* @type {import("ol/source").Vector<import("ol/geom/Geometry").default>|null}
|
|
@@ -262,11 +280,18 @@ class ObliqueCollection {
|
|
|
262
280
|
|
|
263
281
|
/**
|
|
264
282
|
* Adds an oblique data set to this collection.
|
|
265
|
-
* @param {import("@vcmap/core").ObliqueDataSet}
|
|
283
|
+
* @param {import("@vcmap/core").ObliqueDataSet|ObliqueDataSetOptions} dataSetOptions
|
|
266
284
|
* @private
|
|
267
285
|
*/
|
|
268
|
-
_addDataSet(
|
|
269
|
-
|
|
286
|
+
_addDataSet(dataSetOptions) {
|
|
287
|
+
/** @type {import("@vcmap/core").ObliqueDataSet} */
|
|
288
|
+
let dataSet;
|
|
289
|
+
if (dataSetOptions instanceof ObliqueDataSet) {
|
|
290
|
+
dataSet = dataSetOptions;
|
|
291
|
+
} else {
|
|
292
|
+
dataSet = new ObliqueDataSet(dataSetOptions.url, dataSetOptions.projection, dataSetOptions.terrainProvider);
|
|
293
|
+
}
|
|
294
|
+
dataSet.imagesLoaded.addEventListener(({ images, tileCoordinate }) => {
|
|
270
295
|
this._loadImages(images, tileCoordinate);
|
|
271
296
|
});
|
|
272
297
|
this._loadImages(dataSet.images);
|
|
@@ -279,7 +304,7 @@ class ObliqueCollection {
|
|
|
279
304
|
* @returns {Promise<void>}
|
|
280
305
|
* @api
|
|
281
306
|
*/
|
|
282
|
-
async addDataSet(dataSet) {
|
|
307
|
+
async addDataSet(dataSet) { // XXX check for dataset here?
|
|
283
308
|
if (this._loadingPromise) {
|
|
284
309
|
await this._loadingPromise;
|
|
285
310
|
await this._loadDataSet(dataSet);
|
|
@@ -322,7 +347,7 @@ class ObliqueCollection {
|
|
|
322
347
|
directions.set(image.viewDirection, []);
|
|
323
348
|
}
|
|
324
349
|
|
|
325
|
-
const transform = getTransform(image.meta.projection,
|
|
350
|
+
const transform = getTransform(image.meta.projection.proj, mercatorProjection.proj);
|
|
326
351
|
const coord = image.centerPointOnGround.slice(0, 2);
|
|
327
352
|
transform(coord, coord);
|
|
328
353
|
directions.get(image.viewDirection).push({
|
|
@@ -491,7 +516,7 @@ class ObliqueCollection {
|
|
|
491
516
|
async hasImageAtCoordinate(mercatorCoordinate, direction) {
|
|
492
517
|
const image = await this.loadImageForCoordinate(mercatorCoordinate, direction);
|
|
493
518
|
if (image) {
|
|
494
|
-
const transform = getTransform(
|
|
519
|
+
const transform = getTransform(mercatorProjection.proj, image.meta.projection.proj);
|
|
495
520
|
const internalCoordinates = mercatorCoordinate.slice(0, 2);
|
|
496
521
|
transform(internalCoordinates, internalCoordinates);
|
|
497
522
|
const extent = boundingExtent(image.groundCoordinates);
|
|
@@ -513,7 +538,7 @@ class ObliqueCollection {
|
|
|
513
538
|
async loadAdjacentImage(image, heading, deviation = Math.PI / 4) {
|
|
514
539
|
const tree = this._directionTrees.get(image.viewDirection);
|
|
515
540
|
if (tree) {
|
|
516
|
-
const transform = getTransform(image.meta.projection,
|
|
541
|
+
const transform = getTransform(image.meta.projection.proj, mercatorProjection.proj);
|
|
517
542
|
const coords = image.groundCoordinates.map(c => transform(c.slice(0, 2)));
|
|
518
543
|
const extent = boundingExtent(coords);
|
|
519
544
|
await this.loadDataForExtent(buffer(extent, 200));
|
|
@@ -566,6 +591,33 @@ class ObliqueCollection {
|
|
|
566
591
|
this._imageFeatureSource.clear(true);
|
|
567
592
|
this._imageFeatureSource = null;
|
|
568
593
|
}
|
|
594
|
+
this.imagesLoaded.destroy();
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* @returns {ObliqueCollectionOptions}
|
|
599
|
+
*/
|
|
600
|
+
toJSON() {
|
|
601
|
+
/** @type {ObliqueCollectionOptions} */
|
|
602
|
+
const config = super.toJSON();
|
|
603
|
+
const defaultOptions = ObliqueCollection.getDefaultOptions();
|
|
604
|
+
if (this.viewOptions.maxZoom !== defaultOptions.maxZoom) {
|
|
605
|
+
config.maxZoom = this.viewOptions.maxZoom;
|
|
606
|
+
}
|
|
607
|
+
if (this.viewOptions.minZoom !== defaultOptions.minZoom) {
|
|
608
|
+
config.minZoom = this.viewOptions.minZoom;
|
|
609
|
+
}
|
|
610
|
+
if (this.viewOptions.scaleFactor !== defaultOptions.scaleFactor) {
|
|
611
|
+
config.scaleFactor = this.viewOptions.scaleFactor;
|
|
612
|
+
}
|
|
613
|
+
if (this.viewOptions.hideLevels !== defaultOptions.hideLevels) {
|
|
614
|
+
config.hideLevels = this.viewOptions.hideLevels;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
if (this.dataSets.length > 0) {
|
|
618
|
+
config.dataSets = this.dataSets.map(d => d.toJSON());
|
|
619
|
+
}
|
|
620
|
+
return config;
|
|
569
621
|
}
|
|
570
622
|
}
|
|
571
623
|
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { Event as CesiumEvent } from '@vcmap/cesium';
|
|
2
1
|
import axios from 'axios';
|
|
3
2
|
import { createXYZ } from 'ol/tilegrid.js';
|
|
4
|
-
import { destroyCesiumEvent } from './helpers.js';
|
|
5
3
|
import { cartesian2DDistance } from '../util/math.js';
|
|
6
4
|
import { parseImageData, parseImageMeta, parseLegacyImageData, getVersionFromImageJson } from './parseImageJson.js';
|
|
5
|
+
import VcsEvent from '../event/vcsEvent.js';
|
|
6
|
+
import { getTerrainProviderForUrl } from '../layer/terrainHelpers.js';
|
|
7
|
+
import Projection from '../util/projection.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} ObliqueDataSetImagesLoaded
|
|
11
|
+
* @property {Array<import("@vcmap/core").ObliqueImage>} images - the loaded images
|
|
12
|
+
* @property {string} [tileCoordinate] - an optional tile coordinate
|
|
13
|
+
*/
|
|
7
14
|
|
|
8
15
|
/**
|
|
9
16
|
* Enumeration of data set states
|
|
@@ -43,10 +50,10 @@ export function getStateFromStatesArray(states) {
|
|
|
43
50
|
class ObliqueDataSet {
|
|
44
51
|
/**
|
|
45
52
|
* @param {string} url
|
|
46
|
-
* @param {import("
|
|
47
|
-
* @param {
|
|
53
|
+
* @param {import("@vcmap/core").Projection|ProjectionOptions=} projection
|
|
54
|
+
* @param {TerrainProviderOptions=} terrainProviderOptions
|
|
48
55
|
*/
|
|
49
|
-
constructor(url, projection,
|
|
56
|
+
constructor(url, projection, terrainProviderOptions) {
|
|
50
57
|
/** @type {string} */
|
|
51
58
|
this.url = url;
|
|
52
59
|
if (!/\.json$/.test(this.url)) {
|
|
@@ -55,22 +62,36 @@ class ObliqueDataSet {
|
|
|
55
62
|
|
|
56
63
|
/** @type {string} */
|
|
57
64
|
this.baseUrl = this.url.replace(/\/?([^/]+\.json)?$/, '');
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
|
|
66
|
+
let projectionObject = projection;
|
|
67
|
+
if (projectionObject && !(projectionObject instanceof Projection)) {
|
|
68
|
+
projectionObject = new Projection(projectionObject);
|
|
69
|
+
}
|
|
70
|
+
/** @type {import("@vcmap/core").Projection} */
|
|
71
|
+
this.projection = /** @type {import("@vcmap/core").Projection} */ (projectionObject);
|
|
72
|
+
/**
|
|
73
|
+
* @type {TerrainProviderOptions}
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
this._terrainProviderOptions = terrainProviderOptions ? { ...terrainProviderOptions } : undefined;
|
|
77
|
+
/**
|
|
78
|
+
* @type {import("@vcmap/cesium").CesiumTerrainProvider|undefined}
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
this._terrainProvider = this._terrainProviderOptions ?
|
|
82
|
+
getTerrainProviderForUrl(this._terrainProviderOptions) :
|
|
83
|
+
undefined;
|
|
62
84
|
/**
|
|
63
85
|
* @type {Array<import("@vcmap/core").ObliqueImageMeta>}
|
|
64
86
|
* @private
|
|
65
87
|
*/
|
|
66
88
|
this._imageMetas = [];
|
|
67
89
|
/**
|
|
68
|
-
* Event raised when images are loaded.
|
|
69
|
-
*
|
|
70
|
-
* @type {import("@vcmap/cesium").Event}
|
|
90
|
+
* Event raised when images are loaded.
|
|
91
|
+
* @type {import("@vcmap/core").VcsEvent<ObliqueDataSetImagesLoaded>}
|
|
71
92
|
* @api
|
|
72
93
|
*/
|
|
73
|
-
this.imagesLoaded = new
|
|
94
|
+
this.imagesLoaded = new VcsEvent();
|
|
74
95
|
/** @type {Map<string, DataState>} */
|
|
75
96
|
this._tiles = new Map();
|
|
76
97
|
/** @type {Map<string, Promise<void>>} */
|
|
@@ -118,6 +139,14 @@ class ObliqueDataSet {
|
|
|
118
139
|
return this._state;
|
|
119
140
|
}
|
|
120
141
|
|
|
142
|
+
/**
|
|
143
|
+
* @type {import("@vcmap/cesium").CesiumTerrainProvider|undefined}
|
|
144
|
+
* @readonly
|
|
145
|
+
*/
|
|
146
|
+
get terrainProvider() {
|
|
147
|
+
return this._terrainProvider;
|
|
148
|
+
}
|
|
149
|
+
|
|
121
150
|
/**
|
|
122
151
|
* Loads the data set.
|
|
123
152
|
* @returns {Promise<void>}
|
|
@@ -194,7 +223,7 @@ class ObliqueDataSet {
|
|
|
194
223
|
}
|
|
195
224
|
if (images.length > 0) {
|
|
196
225
|
this._images = images;
|
|
197
|
-
this.imagesLoaded.raiseEvent(images);
|
|
226
|
+
this.imagesLoaded.raiseEvent({ images });
|
|
198
227
|
}
|
|
199
228
|
}
|
|
200
229
|
}
|
|
@@ -303,7 +332,7 @@ class ObliqueDataSet {
|
|
|
303
332
|
const images = parseImageData(data, this._imageMetas);
|
|
304
333
|
if (images.length > 0) {
|
|
305
334
|
this._images = this._images.concat(images);
|
|
306
|
-
this.imagesLoaded.raiseEvent(images, stringTileCoordinates);
|
|
335
|
+
this.imagesLoaded.raiseEvent({ images, tileCoordinate: stringTileCoordinates });
|
|
307
336
|
}
|
|
308
337
|
})
|
|
309
338
|
.catch((err) => {
|
|
@@ -344,13 +373,27 @@ class ObliqueDataSet {
|
|
|
344
373
|
}
|
|
345
374
|
|
|
346
375
|
destroy() {
|
|
347
|
-
|
|
376
|
+
this.imagesLoaded.destroy();
|
|
348
377
|
this._images = [];
|
|
349
378
|
this._imageMetas = [];
|
|
350
379
|
this._tiles.clear();
|
|
351
380
|
this._loadingPromises.clear();
|
|
352
381
|
this._tileGrid = null;
|
|
353
|
-
this.
|
|
382
|
+
this._terrainProvider = null;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* @returns {ObliqueDataSetOptions}
|
|
387
|
+
*/
|
|
388
|
+
toJSON() {
|
|
389
|
+
const config = { url: this.url };
|
|
390
|
+
if (this.projection) {
|
|
391
|
+
config.projection = this.projection.toJSON();
|
|
392
|
+
}
|
|
393
|
+
if (this._terrainProviderOptions) {
|
|
394
|
+
config.terrainProvider = { ...this._terrainProviderOptions };
|
|
395
|
+
}
|
|
396
|
+
return config;
|
|
354
397
|
}
|
|
355
398
|
}
|
|
356
399
|
|
|
@@ -13,7 +13,7 @@ import { getHeightFromTerrainProvider } from '../layer/terrainHelpers.js';
|
|
|
13
13
|
* @property {import("@vcmap/cesium").Cartesian3|undefined} projectionCenter
|
|
14
14
|
* @property {import("@vcmap/cesium").Matrix3|undefined} pToRealworld
|
|
15
15
|
* @property {import("@vcmap/cesium").Matrix4|undefined} pToImage
|
|
16
|
-
* @property {import("
|
|
16
|
+
* @property {import("@vcmap/core").Projection|undefined} [projection]
|
|
17
17
|
* @property {import("@vcmap/cesium").CesiumTerrainProvider|undefined} terrainProvider
|
|
18
18
|
* @api
|
|
19
19
|
*/
|
|
@@ -9,7 +9,7 @@ import { cartesian2DDistance } from '../util/math.js';
|
|
|
9
9
|
* @property {import("ol/size").Size} size
|
|
10
10
|
* @property {import("ol/size").Size} tileSize
|
|
11
11
|
* @property {Array<number>} tileResolution
|
|
12
|
-
* @property {import("
|
|
12
|
+
* @property {import("@vcmap/core").Projection} projection
|
|
13
13
|
* @property {string} url
|
|
14
14
|
* @property {import("@vcmap/cesium").CesiumTerrainProvider} terrainProvider
|
|
15
15
|
* @property {string} name
|
|
@@ -64,7 +64,7 @@ class ObliqueImageMeta {
|
|
|
64
64
|
this.tileResolution = options.tileResolution;
|
|
65
65
|
/**
|
|
66
66
|
* The world projection of the images associated with this meta
|
|
67
|
-
* @type {import("
|
|
67
|
+
* @type {import("@vcmap/core").Projection}
|
|
68
68
|
* @api
|
|
69
69
|
*/
|
|
70
70
|
this.projection = options.projection;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Event as CesiumEvent } from '@vcmap/cesium';
|
|
2
1
|
import { getTransform } from 'ol/proj.js';
|
|
3
2
|
import View from 'ol/View.js';
|
|
4
3
|
import { unByKey } from 'ol/Observable.js';
|
|
5
4
|
import { DataState } from './ObliqueDataSet.js';
|
|
6
5
|
import OLView from './ObliqueView.js';
|
|
7
|
-
import {
|
|
6
|
+
import { transformFromImage } from './helpers.js';
|
|
8
7
|
import { getHeightFromTerrainProvider } from '../layer/terrainHelpers.js';
|
|
9
8
|
import { mercatorProjection } from '../util/projection.js';
|
|
9
|
+
import VcsEvent from '../event/vcsEvent.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {Object} ObliqueViewPoint
|
|
@@ -63,10 +63,10 @@ class ObliqueProvider {
|
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
65
|
* Event raised once a new image is set on the provider. Will be passed the new image as the only argument.
|
|
66
|
-
* @type {import("@vcmap/
|
|
66
|
+
* @type {import("@vcmap/core").VcsEvent<import("@vcmap/core").ObliqueImage>}
|
|
67
67
|
* @api
|
|
68
68
|
*/
|
|
69
|
-
this.imageChanged = new
|
|
69
|
+
this.imageChanged = new VcsEvent();
|
|
70
70
|
/**
|
|
71
71
|
* Whether the post render handler should switch on image edge. Setting
|
|
72
72
|
* this to false will suspend all post render handler switches.
|
|
@@ -232,7 +232,7 @@ class ObliqueProvider {
|
|
|
232
232
|
}
|
|
233
233
|
const pulledCenter = this._pullCoordinateToImageCenter(imageCoordinates.slice());
|
|
234
234
|
const worldCoords = this._currentImage.transformImage2RealWorld(pulledCenter).slice(0, 2);
|
|
235
|
-
const transform = getTransform(this._currentImage.meta.projection,
|
|
235
|
+
const transform = getTransform(this._currentImage.meta.projection.proj, mercatorProjection.proj);
|
|
236
236
|
const mercatorCoords = transform(worldCoords);
|
|
237
237
|
const buffer = 200; // XXX make configurable?
|
|
238
238
|
const extent = [
|
|
@@ -299,7 +299,10 @@ class ObliqueProvider {
|
|
|
299
299
|
const [width, height] = this._currentImage.meta.size;
|
|
300
300
|
let center = [width / 2, height / 2];
|
|
301
301
|
if (optCenter) {
|
|
302
|
-
const worldCenter = getTransform(
|
|
302
|
+
const worldCenter = getTransform(
|
|
303
|
+
mercatorProjection.proj,
|
|
304
|
+
this._currentImage.meta.projection.proj,
|
|
305
|
+
)(optCenter.slice(0, 2));
|
|
303
306
|
const imageCenter = this._currentImage.transformRealWorld2Image(worldCenter, optCenter[2]);
|
|
304
307
|
imageCenter[0] = withinBounds(imageCenter[0], width);
|
|
305
308
|
imageCenter[1] = withinBounds(imageCenter[1], height);
|
|
@@ -424,7 +427,7 @@ class ObliqueProvider {
|
|
|
424
427
|
this._postRenderListener = null;
|
|
425
428
|
}
|
|
426
429
|
|
|
427
|
-
|
|
430
|
+
this.imageChanged.destroy();
|
|
428
431
|
this._collection = null;
|
|
429
432
|
this._olMap = null;
|
|
430
433
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/* eslint no-underscore-dangle: ["error", { "allow": ["_listeners", "_scopes", "_toRemove"] }] */
|
|
2
2
|
/* eslint-disable no-continue */
|
|
3
3
|
import { boundingExtent, getBottomLeft, getBottomRight, getTopLeft, getTopRight } from 'ol/extent.js';
|
|
4
|
-
import {
|
|
4
|
+
import { transform } from 'ol/proj.js';
|
|
5
5
|
import { Cartesian2 } from '@vcmap/cesium';
|
|
6
6
|
import { ObliqueViewDirection } from './ObliqueViewDirection.js';
|
|
7
7
|
import { getHeightFromTerrainProvider } from '../layer/terrainHelpers.js';
|
|
8
8
|
import { cartesian2DDistance } from '../util/math.js';
|
|
9
|
+
import { mercatorProjection, wgs84Projection } from '../util/projection.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @type {import("@vcmap/cesium").Cartesian2}
|
|
@@ -292,7 +293,7 @@ export function transformCWIFC(inputOrigin, inputTarget, originIsImage, coordina
|
|
|
292
293
|
/**
|
|
293
294
|
* @typedef {Object} ImageTransformationOptions
|
|
294
295
|
* @property {boolean|undefined} [dontUseTerrain]
|
|
295
|
-
* @property {import("
|
|
296
|
+
* @property {import("@vcmap/core").Projection|undefined} [dataProjection] - the projection of the input/output coordinates, assumes image source projection
|
|
296
297
|
* @property {number|undefined} [terrainErrorThreshold=1] - the transformToWorld process iterativly calculates a new Height Value from the terrainProvider until the difference to the new height value is smaller
|
|
297
298
|
* @property {number|undefined} [terrainErrorCountThreshold=3] - how often the transformToWorld process iterativly calculates a new Height Value from the terrainProvider
|
|
298
299
|
* @api
|
|
@@ -313,8 +314,8 @@ export function transformToImage(image, worldCoordinate, options = {}) {
|
|
|
313
314
|
gpInternalCoordinates = worldCoordinate;
|
|
314
315
|
} else {
|
|
315
316
|
gpInternalCoordinates = options.dataProjection ?
|
|
316
|
-
transform(worldCoordinate, options.dataProjection, image.meta.projection) :
|
|
317
|
-
transform(worldCoordinate,
|
|
317
|
+
transform(worldCoordinate, options.dataProjection.proj, image.meta.projection.proj) :
|
|
318
|
+
transform(worldCoordinate, mercatorProjection.proj, image.meta.projection.proj);
|
|
318
319
|
}
|
|
319
320
|
|
|
320
321
|
function useAverageHeight() {
|
|
@@ -369,14 +370,14 @@ function pickTerrain(pickTerrainOptions) {
|
|
|
369
370
|
count,
|
|
370
371
|
height,
|
|
371
372
|
} = pickTerrainOptions;
|
|
372
|
-
|
|
373
|
+
|
|
373
374
|
return getHeightFromTerrainProvider(image.meta.terrainProvider, [worldCoordinate])
|
|
374
375
|
.then(([worldCoordinateWithHeights]) => {
|
|
375
376
|
if (worldCoordinateWithHeights[2] != null) {
|
|
376
377
|
const newWorldCoords = transform(
|
|
377
378
|
image.transformImage2RealWorld(imageCoordinate, worldCoordinateWithHeights[2]),
|
|
378
|
-
image.meta.projection,
|
|
379
|
-
wgs84Projection,
|
|
379
|
+
image.meta.projection.proj,
|
|
380
|
+
wgs84Projection.proj,
|
|
380
381
|
);
|
|
381
382
|
newWorldCoords[2] = worldCoordinateWithHeights[2];
|
|
382
383
|
if (
|
|
@@ -406,11 +407,10 @@ function pickTerrain(pickTerrainOptions) {
|
|
|
406
407
|
* @export
|
|
407
408
|
*/
|
|
408
409
|
export async function transformFromImage(image, imageCoordinate, options = {}) {
|
|
409
|
-
const wgs84Projection = getProjection('EPSG:4326');
|
|
410
410
|
const initialWorldCoords = transform(
|
|
411
411
|
image.transformImage2RealWorld(imageCoordinate, image.averageHeight),
|
|
412
|
-
image.meta.projection,
|
|
413
|
-
wgs84Projection,
|
|
412
|
+
image.meta.projection.proj,
|
|
413
|
+
wgs84Projection.proj,
|
|
414
414
|
);
|
|
415
415
|
|
|
416
416
|
const terrainErrorThreshold = options.terrainErrorThreshold || 1;
|
|
@@ -430,8 +430,8 @@ export async function transformFromImage(image, imageCoordinate, options = {}) {
|
|
|
430
430
|
}
|
|
431
431
|
|
|
432
432
|
coordsObj.coords = options.dataProjection ?
|
|
433
|
-
transform(coordsObj.coords, wgs84Projection, options.dataProjection) :
|
|
434
|
-
transform(coordsObj.coords, wgs84Projection,
|
|
433
|
+
transform(coordsObj.coords, wgs84Projection.proj, options.dataProjection.proj) :
|
|
434
|
+
transform(coordsObj.coords, wgs84Projection.proj, mercatorProjection.proj);
|
|
435
435
|
return coordsObj;
|
|
436
436
|
}
|
|
437
437
|
|
|
@@ -453,31 +453,3 @@ export function hasSameOrigin(url) {
|
|
|
453
453
|
const uri = new URL(url);
|
|
454
454
|
return currentUri.host.toLowerCase() === uri.host.toLocaleLowerCase();
|
|
455
455
|
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* destroys a cesium Event Emitter, (removes all listeners)
|
|
459
|
-
* @param {import("@vcmap/cesium").Event} cesiumEvent
|
|
460
|
-
*/
|
|
461
|
-
export function destroyCesiumEvent(cesiumEvent) {
|
|
462
|
-
// @ts-ignore
|
|
463
|
-
for (let i = 0; i < cesiumEvent._listeners.length; i++) {
|
|
464
|
-
// @ts-ignore
|
|
465
|
-
cesiumEvent._listeners[i] = undefined;
|
|
466
|
-
}
|
|
467
|
-
// @ts-ignore
|
|
468
|
-
for (let i = 0; i < cesiumEvent._scopes.length; i++) {
|
|
469
|
-
// @ts-ignore
|
|
470
|
-
cesiumEvent._scopes[i] = undefined;
|
|
471
|
-
}
|
|
472
|
-
// @ts-ignore
|
|
473
|
-
for (let i = 0; i < cesiumEvent._toRemove.length; i++) {
|
|
474
|
-
// @ts-ignore
|
|
475
|
-
cesiumEvent._toRemove[i] = undefined;
|
|
476
|
-
}
|
|
477
|
-
// @ts-ignore
|
|
478
|
-
cesiumEvent._listeners.length = 0;
|
|
479
|
-
// @ts-ignore
|
|
480
|
-
cesiumEvent._scopes.length = 0;
|
|
481
|
-
// @ts-ignore
|
|
482
|
-
cesiumEvent._toRemove.length = 0;
|
|
483
|
-
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import proj4 from 'proj4';
|
|
3
|
-
import { register } from 'ol/proj/proj4.js';
|
|
4
|
-
import { get as getProjection } from 'ol/proj.js';
|
|
5
1
|
import { Matrix3, Cartesian3, Matrix4 } from '@vcmap/cesium';
|
|
6
2
|
import ObliqueImage from './ObliqueImage.js';
|
|
7
3
|
import { obliqueViewDirectionNames } from './ObliqueViewDirection.js';
|
|
8
4
|
import ImageMeta from './ObliqueImageMeta.js';
|
|
5
|
+
import Projection from '../util/projection.js';
|
|
6
|
+
|
|
7
|
+
let customObliqueProjectionId = 0;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @returns {number}
|
|
11
|
+
*/
|
|
12
|
+
function getNextObliqueProjectionId() {
|
|
13
|
+
customObliqueProjectionId += 1;
|
|
14
|
+
return customObliqueProjectionId;
|
|
15
|
+
}
|
|
9
16
|
|
|
10
17
|
/**
|
|
11
18
|
* @param {Object} json
|
|
@@ -33,7 +40,7 @@ export function getVersionFromImageJson(json) {
|
|
|
33
40
|
/**
|
|
34
41
|
* @param {ObliqueImageJson} json
|
|
35
42
|
* @param {string} url
|
|
36
|
-
* @param {
|
|
43
|
+
* @param {import("@vcmap/core").Projection=} projection
|
|
37
44
|
* @param {import("@vcmap/cesium").CesiumTerrainProvider=} terrainProvider
|
|
38
45
|
* @returns {Array<import("@vcmap/core").ObliqueImageMeta>}
|
|
39
46
|
*/
|
|
@@ -47,10 +54,11 @@ export function parseImageMeta(json, url, projection, terrainProvider) {
|
|
|
47
54
|
let imageProjection = projection;
|
|
48
55
|
const imageMetas = [];
|
|
49
56
|
if (!imageProjection && json.generalImageInfo.crs) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
imageProjection = new Projection({
|
|
58
|
+
epsg: getNextObliqueProjectionId(),
|
|
59
|
+
prefix: 'OBLIQUE:',
|
|
60
|
+
proj4: json.generalImageInfo.crs,
|
|
61
|
+
});
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
const defaultOptions = {
|
|
@@ -35,6 +35,11 @@ function checkExtentValidity(extent) {
|
|
|
35
35
|
* @api
|
|
36
36
|
*/
|
|
37
37
|
class Extent {
|
|
38
|
+
/**
|
|
39
|
+
* @type {string}
|
|
40
|
+
*/
|
|
41
|
+
static get className() { return 'vcs.vcm.util.Extent'; }
|
|
42
|
+
|
|
38
43
|
/**
|
|
39
44
|
* @param {ExtentOptions=} options object
|
|
40
45
|
*/
|
|
@@ -44,6 +49,7 @@ class Extent {
|
|
|
44
49
|
epsg: options.epsg,
|
|
45
50
|
proj4: options.proj4,
|
|
46
51
|
alias: options.alias,
|
|
52
|
+
prefix: options.prefix,
|
|
47
53
|
});
|
|
48
54
|
|
|
49
55
|
/** @type {import("ol/extent").Extent|null} */
|
|
@@ -79,7 +85,11 @@ class Extent {
|
|
|
79
85
|
* @returns {ExtentOptions}
|
|
80
86
|
*/
|
|
81
87
|
toJSON() {
|
|
82
|
-
return {
|
|
88
|
+
return {
|
|
89
|
+
coordinates: this.extent.slice(),
|
|
90
|
+
...this.projection.toJSON(),
|
|
91
|
+
type: Extent.className,
|
|
92
|
+
};
|
|
83
93
|
}
|
|
84
94
|
|
|
85
95
|
/**
|
|
@@ -42,8 +42,22 @@ class IndexedCollection extends Collection {
|
|
|
42
42
|
* @api
|
|
43
43
|
*/
|
|
44
44
|
this.moved = new VcsEvent();
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @type {symbol}
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
this._previousIndexSymbol = Symbol('previousIndex');
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Get the symbol which is attached to an item prior to its removal. If an item is removed, the current index of the item
|
|
55
|
+
* is set on the item with this symbol.
|
|
56
|
+
* @type {symbol}
|
|
57
|
+
* @readonly
|
|
58
|
+
*/
|
|
59
|
+
get previousIndexSymbol() { return this._previousIndexSymbol; }
|
|
60
|
+
|
|
47
61
|
/**
|
|
48
62
|
* Returns an item at index.
|
|
49
63
|
* @param {number} index
|
|
@@ -76,6 +90,15 @@ class IndexedCollection extends Collection {
|
|
|
76
90
|
return null;
|
|
77
91
|
}
|
|
78
92
|
|
|
93
|
+
/**
|
|
94
|
+
* @inheritDoc
|
|
95
|
+
* @param {T} item
|
|
96
|
+
*/
|
|
97
|
+
remove(item) {
|
|
98
|
+
item[this._previousIndexSymbol] = this._array.indexOf(item);
|
|
99
|
+
super.remove(item);
|
|
100
|
+
}
|
|
101
|
+
|
|
79
102
|
/**
|
|
80
103
|
* @param {T} item
|
|
81
104
|
* @param {number} itemIndex
|
|
@@ -44,9 +44,6 @@ class LayerCollection extends IndexedCollection {
|
|
|
44
44
|
this._layerEventListeners = {};
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* A symbol to describe the local z index of a layer. The local z index must not equal the layers z index, but is
|
|
48
|
-
* always consistent in comparison to the neighbouring layers. If a layer is moved other then by z index, the collection
|
|
49
|
-
* ensures consistency by setting a new local z index if needed.
|
|
50
47
|
* @type {symbol}
|
|
51
48
|
* @private
|
|
52
49
|
*/
|
|
@@ -67,6 +64,15 @@ class LayerCollection extends IndexedCollection {
|
|
|
67
64
|
this.exclusiveManager = new ExclusiveManager();
|
|
68
65
|
}
|
|
69
66
|
|
|
67
|
+
/**
|
|
68
|
+
* A symbol to describe the local z index of a layer. The local z index must not equal the layers z index, but is
|
|
69
|
+
* always consistent in comparison to the neighbouring layers. If a layer is moved other then by z index, the collection
|
|
70
|
+
* ensures consistency by setting a new local z index if needed.
|
|
71
|
+
* @type {symbol}
|
|
72
|
+
* @readonly
|
|
73
|
+
*/
|
|
74
|
+
get zIndexSymbol() { return this._zIndexSymbol; }
|
|
75
|
+
|
|
70
76
|
/**
|
|
71
77
|
* @param {import("@vcmap/core").Layer} layer
|
|
72
78
|
* @private
|
|
@@ -116,10 +122,9 @@ class LayerCollection extends IndexedCollection {
|
|
|
116
122
|
_zIndexChanged(layer) {
|
|
117
123
|
const currentIndex = this.indexOf(layer);
|
|
118
124
|
if (currentIndex > -1) {
|
|
119
|
-
const increased = layer[this._zIndexSymbol] < layer.zIndex;
|
|
120
125
|
layer[this._zIndexSymbol] = layer.zIndex;
|
|
121
126
|
let zIndexPosition = this._findZIndexPosition(layer.zIndex);
|
|
122
|
-
if (
|
|
127
|
+
if (zIndexPosition > 0 && zIndexPosition > currentIndex) {
|
|
123
128
|
zIndexPosition -= 1; // remove self from count
|
|
124
129
|
}
|
|
125
130
|
zIndexPosition = zIndexPosition != null ? zIndexPosition : this._array.length - 1;
|
|
@@ -3,12 +3,15 @@ import { register } from 'ol/proj/proj4.js';
|
|
|
3
3
|
import proj4 from 'proj4';
|
|
4
4
|
import { getLogger as getLoggerByName } from '@vcsuite/logger';
|
|
5
5
|
import { check } from '@vcsuite/check';
|
|
6
|
+
import { VcsClassRegistry } from '../classRegistry.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @typedef {Object} ProjectionOptions
|
|
10
|
+
* @property {string} [type]
|
|
9
11
|
* @property {string|number} [epsg] - EPSG of the projection, for example: "EPSG:4326" if not specified, uses the framework projection
|
|
10
12
|
* @property {string|undefined|null} [proj4] - definition of the projection. See for example: {@link http://spatialreference.org/ref/epsg/4326/proj4/} proj4
|
|
11
13
|
* @property {Array<string>|undefined|null} [alias] - aliases to define
|
|
14
|
+
* @property {string|undefined} [prefix='EPSG:'] - an alternate prefix to use for custom projection
|
|
12
15
|
* @api stable
|
|
13
16
|
*/
|
|
14
17
|
|
|
@@ -36,7 +39,8 @@ let defaultProjectionOption = {
|
|
|
36
39
|
* @returns {string}
|
|
37
40
|
*/
|
|
38
41
|
function parseEPSGCode(value, prefix = 'EPSG:') {
|
|
39
|
-
const
|
|
42
|
+
const regex = new RegExp(`^(?:${prefix})?(\\d+)`, 'i');
|
|
43
|
+
const matches = `${value}`.match(regex);
|
|
40
44
|
if (matches && matches[1]) {
|
|
41
45
|
return `${prefix}${matches[1]}`;
|
|
42
46
|
}
|
|
@@ -73,9 +77,11 @@ function validateProjectionOptions(options) {
|
|
|
73
77
|
* @returns {ProjectionOptions} valid options
|
|
74
78
|
*/
|
|
75
79
|
function registerProjection(options) {
|
|
76
|
-
const saneOptions = {
|
|
80
|
+
const saneOptions = {
|
|
81
|
+
prefix: options.prefix,
|
|
82
|
+
};
|
|
77
83
|
if (options.epsg) {
|
|
78
|
-
saneOptions.epsg = parseEPSGCode(options.epsg);
|
|
84
|
+
saneOptions.epsg = parseEPSGCode(options.epsg, options.prefix);
|
|
79
85
|
if (saneOptions.epsg) {
|
|
80
86
|
if (options.proj4) {
|
|
81
87
|
saneOptions.proj4 = options.proj4;
|
|
@@ -123,6 +129,11 @@ export function setDefaultProjectionOptions(options) {
|
|
|
123
129
|
* @api stable
|
|
124
130
|
*/
|
|
125
131
|
class Projection {
|
|
132
|
+
/**
|
|
133
|
+
* @returns {string}
|
|
134
|
+
*/
|
|
135
|
+
static get className() { return 'vcs.vcm.util.Projection'; }
|
|
136
|
+
|
|
126
137
|
/**
|
|
127
138
|
* @param {ProjectionOptions} options
|
|
128
139
|
*/
|
|
@@ -143,6 +154,20 @@ class Projection {
|
|
|
143
154
|
if (!this.proj) {
|
|
144
155
|
this._epsg = Projection.parseEPSGCode(defaultProjectionOption.epsg);
|
|
145
156
|
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Cached for toJSON
|
|
160
|
+
* @type {Array<string>}
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
this._alias = saneOptions.alias;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Cached for toJSON
|
|
167
|
+
* @type {string}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
this._prefix = saneOptions.prefix;
|
|
146
171
|
}
|
|
147
172
|
|
|
148
173
|
/**
|
|
@@ -264,11 +289,18 @@ class Projection {
|
|
|
264
289
|
*/
|
|
265
290
|
toJSON() {
|
|
266
291
|
const configObject = {
|
|
292
|
+
type: Projection.className,
|
|
267
293
|
epsg: this.epsg,
|
|
268
294
|
};
|
|
269
295
|
if (this.proj4) {
|
|
270
296
|
configObject.proj4 = this.proj4;
|
|
271
297
|
}
|
|
298
|
+
if (Array.isArray(this._alias) && this._alias.length > 0) {
|
|
299
|
+
configObject.alias = this._alias.slice();
|
|
300
|
+
}
|
|
301
|
+
if (this._prefix) {
|
|
302
|
+
configObject.prefix = this._prefix;
|
|
303
|
+
}
|
|
272
304
|
return configObject;
|
|
273
305
|
}
|
|
274
306
|
|
|
@@ -346,3 +378,5 @@ export const wgs84Projection = new Projection({ epsg: 4326 });
|
|
|
346
378
|
* @export
|
|
347
379
|
*/
|
|
348
380
|
export const mercatorProjection = new Projection({ epsg: 3857 });
|
|
381
|
+
|
|
382
|
+
VcsClassRegistry.registerClass(Projection.className, Projection);
|
|
@@ -3,6 +3,7 @@ import { parseBoolean, parseNumber } from '@vcsuite/parsers';
|
|
|
3
3
|
import Projection, { wgs84Projection } from './projection.js';
|
|
4
4
|
import VcsObject from '../object.js';
|
|
5
5
|
import Extent from './extent.js';
|
|
6
|
+
import { VcsClassRegistry } from '../classRegistry.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* compares two numeric properties
|
|
@@ -331,3 +332,5 @@ class ViewPoint extends VcsObject {
|
|
|
331
332
|
}
|
|
332
333
|
|
|
333
334
|
export default ViewPoint;
|
|
335
|
+
|
|
336
|
+
VcsClassRegistry.registerClass(ViewPoint.className, ViewPoint);
|