@vcmap/core 5.0.0-rc.26 → 5.0.0-rc.27

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 CHANGED
@@ -2,18 +2,6 @@ import olFeature from 'ol/Feature';
2
2
  import Geometry from 'ol/geom/Geometry';
3
3
  import Style from 'ol/style/Style';
4
4
 
5
- export interface AppBackedCategoryOptions extends CategoryOptions {
6
- collectionName: string;
7
- }
8
-
9
- export class AppBackedCategory extends Category<VcsObject> {
10
- constructor(options: AppBackedCategoryOptions);
11
- protected _deserializeItem(config: VcsObjectOptions): Promise<VcsObject>;
12
- setApp(app: VcsApp): void;
13
- serializeForContext(contextId: string): null;
14
- toJSON(): AppBackedCategoryOptions;
15
- }
16
-
17
5
  /**
18
6
  */
19
7
  export interface CategoryOptions extends VcsObjectOptions {
@@ -6348,6 +6336,10 @@ export interface ArcStyleOptions extends ArrowStyleOptions {
6348
6336
  * number of segments to interpolate the arc by
6349
6337
  */
6350
6338
  numberOfSegments?: number;
6339
+ /**
6340
+ * offset in m(mercator) from the arc end and arc start to the start/end points Is only rendered if offset * 2 < distance between start and endpoint
6341
+ */
6342
+ offset?: number;
6351
6343
  }
6352
6344
 
6353
6345
  /**
@@ -6377,6 +6369,7 @@ export const featureArcStruct: unique symbol;
6377
6369
  export class ArcStyle extends ArrowStyle {
6378
6370
  constructor(options?: ArcStyleOptions);
6379
6371
  numberOfSegments: any;
6372
+ offset: any;
6380
6373
  arcFactor: any;
6381
6374
  primitiveOptions: VectorPropertiesPrimitiveOptions;
6382
6375
  end: ArrowEnd;
@@ -8631,6 +8624,7 @@ export interface OverrideCollectionInterface<T extends any> {
8631
8624
  shadowMap: Map<string, object[]>;
8632
8625
  override: (item: T) => T;
8633
8626
  parseItems: (items: object[], contextId: string) => Promise<void>;
8627
+ getSerializedByKey: (key: string) => object;
8634
8628
  removeContext: (contextId: string) => Promise<void>;
8635
8629
  serializeContext: (contextId: string) => object[];
8636
8630
  }
@@ -8640,6 +8634,7 @@ export class OverrideCollection<T extends any> extends Collection<T> implements
8640
8634
  shadowMap: Map<string, object[]>;
8641
8635
  override: (item: T) => T;
8642
8636
  parseItems: (items: object[], contextId: string) => Promise<void>;
8637
+ getSerializedByKey: (key: string) => object;
8643
8638
  removeContext: (contextId: string) => Promise<void>;
8644
8639
  serializeContext: (contextId: string) => object[];
8645
8640
  }
@@ -8649,6 +8644,7 @@ export class OverrideLayerCollection extends LayerCollection implements Override
8649
8644
  shadowMap: Map<string, object[]>;
8650
8645
  override: (item: Layer) => Layer;
8651
8646
  parseItems: (items: object[], contextId: string) => Promise<void>;
8647
+ getSerializedByKey: (key: string) => object;
8652
8648
  removeContext: (contextId: string) => Promise<void>;
8653
8649
  serializeContext: (contextId: string) => object[];
8654
8650
  }
@@ -8658,6 +8654,7 @@ export class OverrideMapCollection extends MapCollection implements OverrideColl
8658
8654
  shadowMap: Map<string, object[]>;
8659
8655
  override: (item: VcsMap) => VcsMap;
8660
8656
  parseItems: (items: object[], contextId: string) => Promise<void>;
8657
+ getSerializedByKey: (key: string) => object;
8661
8658
  removeContext: (contextId: string) => Promise<void>;
8662
8659
  serializeContext: (contextId: string) => object[];
8663
8660
  }
package/index.js CHANGED
@@ -7,7 +7,6 @@ import './src/cesium/cesium3DTileFeature.js';
7
7
  import './src/cesium/cesiumVcsCameraPrimitive.js';
8
8
  import './src/cesium/entity.js';
9
9
 
10
- export { default as AppBackedCategory } from './src/category/appBackedCategory.js';
11
10
  export { default as Category } from './src/category/category.js';
12
11
  export { default as CategoryCollection } from './src/category/categoryCollection.js';
13
12
  export { layerClassRegistry, tileProviderClassRegistry, featureProviderClassRegistry, mapClassRegistry, styleClassRegistry, categoryClassRegistry, getObjectFromClassRegistry, default as ClassRegistry } from './src/classRegistry.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcmap/core",
3
- "version": "5.0.0-rc.26",
3
+ "version": "5.0.0-rc.27",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -50,6 +50,7 @@
50
50
  "mocha-junit-reporter": "^2.0.2",
51
51
  "nock": "^13.2.4",
52
52
  "node-fetch": "^3.2.0",
53
+ "resize-observer-polyfill": "1.5.1",
53
54
  "sinon": "^9.2.4",
54
55
  "sinon-chai": "^3.6.0",
55
56
  "tui-jsdoc-template": "^1.2.2",
@@ -57,7 +58,7 @@
57
58
  },
58
59
  "peerDependencies": {
59
60
  "@vcmap-cesium/engine": "~1.1.2",
60
- "ol": "~7.1.0"
61
+ "ol": "~7.2.2"
61
62
  },
62
63
  "eslintConfig": {
63
64
  "extends": [
@@ -80,7 +81,6 @@
80
81
  "proj4": "^2.7.5",
81
82
  "rbush": ">=3.0.1",
82
83
  "rbush-knn": "^3.0.1",
83
- "underscore.template": "^0.1.7",
84
84
  "uuid": "^8.3.2"
85
85
  }
86
86
  }
@@ -1,6 +1,5 @@
1
1
  import { getLogger as getLoggerByName } from '@vcsuite/logger';
2
2
  import Category from './category.js';
3
- import './appBackedCategory.js';
4
3
  import IndexedCollection from '../util/indexedCollection.js';
5
4
  import { getObjectFromClassRegistry } from '../classRegistry.js';
6
5
 
@@ -11,6 +11,7 @@ import ArrowStyle from './arrowStyle.js';
11
11
  * @typedef {ArrowStyleOptions} ArcStyleOptions
12
12
  * @property {number} [arcFactor=0.15] - factor to calculate the 'height' of an arc, based on the distance from start to end
13
13
  * @property {number} [numberOfSegments=64] - number of segments to interpolate the arc by
14
+ * @property {number} [offset=0] - offset in m(mercator) from the arc end and arc start to the start/end points Is only rendered if offset * 2 < distance between start and endpoint
14
15
  */
15
16
 
16
17
  /**
@@ -33,17 +34,6 @@ export const featureArcStruct = Symbol('FeatureArcStruct');
33
34
  */
34
35
  const featureArcStyleId = Symbol('ArcStyleId');
35
36
 
36
- /**
37
- * @param {import("ol/coordinate").Coordinate} p1
38
- * @param {import("ol/coordinate").Coordinate} p2
39
- * @param {number} factor
40
- * @returns {number}
41
- */
42
- function determineArcHeight(p1, p2, factor) {
43
- const distance = cartesian2DDistance(p1, p2);
44
- return distance * factor;
45
- }
46
-
47
37
  /**
48
38
  * Gets the radius of the circle covering p1, p2, p3. see https://math.stackexchange.com/a/1460096
49
39
  * @param {import("ol/coordinate").Coordinate} p1
@@ -117,26 +107,29 @@ function determineQuadrantOffset(center, coordinate, angle) {
117
107
  * @param {import("ol/coordinate").Coordinate} center
118
108
  * @param {number} radius
119
109
  * @param {number} numberOfSegments
110
+ * @param {number} offset
120
111
  * @returns {Array<import("ol/coordinate").Coordinate>}
121
112
  */
122
- function interpolateBetweenAngles(p1, p2, center, radius, numberOfSegments) {
113
+ function interpolateBetweenAngles(p1, p2, center, radius, numberOfSegments, offset) {
123
114
  const zeroVector = Cartesian2.UNIT_X;
124
115
  const p1V = new Cartesian2(p1[0] - center[0], p1[1] - center[1]);
125
116
  const p2V = new Cartesian2(p2[0] - center[0], p2[1] - center[1]);
126
117
  let startAngle = Cartesian2.angleBetween(zeroVector, p1V);
127
118
  startAngle = determineQuadrantOffset(center, p1, startAngle);
128
- const distance = Cartesian2.angleBetween(p1V, p2V);
119
+ let distance = Cartesian2.angleBetween(p1V, p2V);
129
120
  const coordinates = new Array(numberOfSegments);
121
+ const offsetAngle = offset / radius;
122
+ startAngle += offsetAngle;
123
+ distance -= offsetAngle * 2;
130
124
 
131
- for (let i = 0; i < numberOfSegments; ++i) {
132
- const angle = startAngle + (modulo(i, numberOfSegments) * distance) / numberOfSegments;
125
+ for (let i = 0; i <= numberOfSegments; ++i) {
126
+ const angle = startAngle + (modulo(i, numberOfSegments + 1) * distance) / numberOfSegments;
133
127
  coordinates[i] = [
134
128
  center[0] + radius * Math.cos(angle),
135
129
  center[1] + radius * Math.sin(angle),
136
130
  0,
137
131
  ];
138
132
  }
139
- coordinates.push([p2[0], p2[1], 0]);
140
133
  return coordinates;
141
134
  }
142
135
 
@@ -146,19 +139,38 @@ function interpolateBetweenAngles(p1, p2, center, radius, numberOfSegments) {
146
139
  * @param {number} arcHeight
147
140
  * @param {number} numberOfSegments
148
141
  * @param {number} arcFactor
142
+ * @param {number} offset
149
143
  * @returns {Array<import("ol/coordinate").Coordinate>}
150
144
  */
151
- function getArcCoordinates(p1, p2, arcHeight, numberOfSegments, arcFactor) {
145
+ function getArcCoordinates(p1, p2, arcHeight, numberOfSegments, arcFactor, offset) {
152
146
  const midPoint = getMidPoint(p1, p2);
153
147
  midPoint[2] += (arcHeight / 2);
154
- const distance = cartesian2DDistance(p1, p2) / numberOfSegments;
148
+ const fullDistance = cartesian2DDistance(p1, p2);
149
+
150
+ const p1Cartesian = new Cartesian3(p1[0], p1[1], p1[2] ?? 0);
151
+ const midPointCartesian = new Cartesian3(midPoint[0], midPoint[1], midPoint[2] ?? 0);
152
+ const p2Cartesian = new Cartesian3(p2[0], p2[1], p2[2] ?? 0);
153
+ let points;
154
+ if (offset > 0) {
155
+ const distanceP1Midpoint = Cartesian3.distance(p1Cartesian, midPointCartesian);
156
+ const offsetNumber = (1 / distanceP1Midpoint) * offset;
157
+
158
+ const arcHeightCorrection = arcHeight / 4;
159
+ const offsetHeightCorrection =
160
+ (offsetNumber > 0.5 ? Math.abs(1 - offsetNumber) : offsetNumber) * arcHeightCorrection;
161
+ const newP1 = Cartesian3.lerp(p1Cartesian, midPointCartesian, offsetNumber, new Cartesian3());
162
+ newP1.z += offsetHeightCorrection;
163
+ const newP2 = Cartesian3.lerp(p2Cartesian, midPointCartesian, offsetNumber, new Cartesian3());
164
+ newP2.z += offsetHeightCorrection;
165
+ points = [newP1, midPointCartesian, newP2];
166
+ } else {
167
+ points = [p1Cartesian, midPointCartesian, p2Cartesian];
168
+ }
169
+
170
+ const distance = (fullDistance - offset * 2) / 64;
155
171
  const spline = new CatmullRomSpline({
156
172
  times: [0, 0.5, 1],
157
- points: [
158
- new Cartesian3(p1[0], p1[1], p1[2] ?? 0),
159
- new Cartesian3(midPoint[0], midPoint[1], midPoint[2] ?? 0),
160
- new Cartesian3(p2[0], p2[1], p2[2] ?? 0),
161
- ],
173
+ points,
162
174
  firstTangent: new Cartesian3(0, 0, arcFactor * distance),
163
175
  lastTangent: new Cartesian3(0, 0, -arcFactor * distance),
164
176
  });
@@ -177,8 +189,9 @@ function getArcCoordinates(p1, p2, arcHeight, numberOfSegments, arcFactor) {
177
189
  * @param {number} arcFactor
178
190
  * @param {import("ol").Feature} feature
179
191
  * @param {number} numberOfSegments
192
+ * @param {number} offset
180
193
  */
181
- function createFeatureArc(arcFactor, feature, numberOfSegments) {
194
+ function createFeatureArc(arcFactor, feature, numberOfSegments, offset) {
182
195
  if (feature[featureArcStruct]) {
183
196
  feature[featureArcStruct].destroy();
184
197
  }
@@ -187,20 +200,27 @@ function createFeatureArc(arcFactor, feature, numberOfSegments) {
187
200
  const destroy = () => {
188
201
  unByKey(listeners);
189
202
  };
190
- listeners.push(feature.on('change:geometry', () => { createFeatureArc(arcFactor, feature, numberOfSegments); }));
203
+ listeners.push(feature.on('change:geometry', () => { createFeatureArc(arcFactor, feature, numberOfSegments, offset); }));
191
204
 
192
205
  if (geometry instanceof LineString) {
193
- listeners.push(geometry.on('change', () => { createFeatureArc(arcFactor, feature, numberOfSegments); }));
206
+ listeners.push(geometry.on('change', () => { createFeatureArc(arcFactor, feature, numberOfSegments, offset); }));
194
207
  const p1 = geometry.getFirstCoordinate();
195
208
  const p2 = geometry.getLastCoordinate();
196
- const arcHeight = determineArcHeight(p1, p2, arcFactor);
209
+ const distance = cartesian2DDistance(p1, p2);
210
+ const arcHeight = distance * arcFactor;
211
+ // check offset validity
212
+ let validOffset = offset;
213
+ if ((offset * 2) > distance) {
214
+ validOffset = 0;
215
+ }
197
216
  const midPoint = getMidPointOnArc(p1, p2, arcHeight);
198
217
  const { center, radius } = determineCircle(p1, p2, midPoint);
199
218
 
200
- const coordinates = interpolateBetweenAngles(p1, p2, center, radius, numberOfSegments);
219
+ const coordinates = interpolateBetweenAngles(p1, p2, center, radius, numberOfSegments, validOffset);
220
+ const c = getArcCoordinates(p1, p2, arcHeight, numberOfSegments, arcFactor, validOffset);
201
221
  feature[featureArcStruct] = {
202
222
  geometry: new LineString(coordinates),
203
- coordinates: getArcCoordinates(p1, p2, arcHeight, numberOfSegments, arcFactor),
223
+ coordinates: c,
204
224
  destroy,
205
225
  };
206
226
  } else {
@@ -241,6 +261,11 @@ class ArcStyle extends ArrowStyle {
241
261
  * @private
242
262
  */
243
263
  this._numberOfSegments = parseInteger(options.numberOfSegments, 64);
264
+ /**
265
+ * @type {number}
266
+ * @private
267
+ */
268
+ this._offset = parseNumber(options.offset, 0);
244
269
 
245
270
  this.setGeometry(this._getFeatureArcGeometry.bind(this));
246
271
  }
@@ -264,6 +289,25 @@ class ArcStyle extends ArrowStyle {
264
289
  }
265
290
  }
266
291
 
292
+ /**
293
+ * An offset from the arc end/start to the starting point / end point
294
+ * @type {number}
295
+ */
296
+ get offset() {
297
+ return this._offset;
298
+ }
299
+
300
+ /**
301
+ * @param {number} value
302
+ */
303
+ set offset(value) {
304
+ check(value, Number);
305
+ if (value !== this._offset && value > 0) {
306
+ this._offset = value;
307
+ this._revisionId = uuidv4();
308
+ }
309
+ }
310
+
267
311
  /**
268
312
  * The factor with which to calculate the 'height' of an arc using the distance from start to end of the LineString.
269
313
  * @type {number}
@@ -288,7 +332,7 @@ class ArcStyle extends ArrowStyle {
288
332
  */
289
333
  _getFeatureArcGeometry(feature) {
290
334
  if (!feature[featureArcStruct] || feature[featureArcStyleId] !== this._revisionId) {
291
- createFeatureArc(this._arcFactor, feature, this._numberOfSegments);
335
+ createFeatureArc(this._arcFactor, feature, this._numberOfSegments, this._offset);
292
336
  feature[featureArcStyleId] = this._revisionId;
293
337
  }
294
338
  return feature[featureArcStruct].geometry;
@@ -23,6 +23,7 @@ function getLogger() {
23
23
  * @property {function(T):T|null} override - returns the overriden item or null if the item could not be inserted (this would be the result of a race condition)
24
24
  * @property {Map<string, Array<Object>>} shadowMap
25
25
  * @property {function(Array<Object>, string):Promise<void>} parseItems
26
+ * @property {function(string):Object} getSerializedByKey
26
27
  * @property {function(string):Promise<void>} removeContext
27
28
  * @property {function(string):Array<Object>} serializeContext
28
29
  * @template {*} T
@@ -133,6 +134,18 @@ function makeOverrideCollection(
133
134
  }
134
135
  };
135
136
 
137
+ /**
138
+ * @param {string} key
139
+ * @returns {Object|undefined}
140
+ */
141
+ overrideCollection.getSerializedByKey = function getSerializedByKey(key) {
142
+ const item = overrideCollection.getByKey(key);
143
+ if (item) {
144
+ return serialize(item);
145
+ }
146
+ return undefined;
147
+ };
148
+
136
149
  overrideCollection.removed.addEventListener(async (item) => {
137
150
  const itemId = item[overrideCollection.uniqueKey];
138
151
 
@@ -1,89 +0,0 @@
1
- import Category from './category.js';
2
- import { categoryClassRegistry } from '../classRegistry.js';
3
- import Viewpoint from '../util/viewpoint.js';
4
- import ObliqueCollection from '../oblique/obliqueCollection.js';
5
- import { deserializeLayer, deserializeMap } from '../vcsAppContextHelpers.js';
6
-
7
- /**
8
- * @typedef {CategoryOptions} AppBackedCategoryOptions
9
- * @property {string} collectionName
10
- */
11
-
12
- /**
13
- * @type {Object<string, string>}
14
- */
15
- const collectionNameMap = {
16
- layers: 'layerClassRegistry',
17
- styles: 'styleClassRegistry',
18
- maps: 'mapClassRegistry',
19
- categories: 'categoryClassRegistry',
20
- };
21
-
22
- /**
23
- * @class
24
- * @extends {Category<import("@vcmap/core").VcsObject>}
25
- */
26
- class AppBackedCategory extends Category {
27
- static get className() { return 'AppBackedCategory'; }
28
-
29
- /**
30
- * @param {AppBackedCategoryOptions} options
31
- */
32
- constructor(options) {
33
- options.classRegistryName = collectionNameMap[options.collectionName];
34
- super(options);
35
- this._collectionName = options.collectionName;
36
- }
37
-
38
- /**
39
- * @param {VcsObjectOptions} config
40
- * @returns {Promise<import("@vcmap/core").VcsObject>}
41
- * @protected
42
- */
43
- async _deserializeItem(config) {
44
- if (!this._app) {
45
- throw new Error('Cannot deserialize item before setting the vcApp');
46
- }
47
-
48
- if (this._collectionName === 'viewpoints') {
49
- return new Viewpoint(config);
50
- } else if (this._collectionName === 'obliqueCollections') {
51
- return new ObliqueCollection(config);
52
- } else if (this._collectionName === 'layers') {
53
- return deserializeLayer(this._app, config);
54
- } else if (this._collectionName === 'maps') {
55
- return deserializeMap(this._app, config);
56
- }
57
- return super._deserializeItem(config);
58
- }
59
-
60
- /**
61
- * @param {import("@vcmap/core").VcsApp} app
62
- */
63
- setApp(app) {
64
- super.setApp(app);
65
- this.setCollection(this._app[this._collectionName]);
66
- }
67
-
68
- /**
69
- * @param {string} contextId
70
- * @returns {null}
71
- */
72
- // eslint-disable-next-line class-methods-use-this,no-unused-vars
73
- serializeForContext(contextId) {
74
- return null;
75
- }
76
-
77
- /**
78
- * @returns {AppBackedCategoryOptions}
79
- */
80
- toJSON() {
81
- const config = /** @type {AppBackedCategoryOptions} */ (super.toJSON());
82
- delete config.classRegistryName;
83
- config.collectionName = this._collectionName;
84
- return config;
85
- }
86
- }
87
-
88
- export default AppBackedCategory;
89
- categoryClassRegistry.registerClass(AppBackedCategory.className, AppBackedCategory);