@openglobus/og 0.13.5 → 0.13.6
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/dist/@openglobus/og.esm.js +2 -2
- package/dist/@openglobus/og.esm.js.map +1 -1
- package/dist/@openglobus/og.umd.js +2 -2
- package/dist/@openglobus/og.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/og/Events.js +188 -188
- package/src/og/Globe.js +1 -0
- package/src/og/control/KeyboardNavigation.js +48 -2
- package/src/og/control/TouchNavigation.js +13 -13
- package/src/og/control/ZoomControl.js +1 -1
- package/src/og/ellipsoid/Ellipsoid.js +1 -1
- package/src/og/entity/LabelHandler.js +2 -2
- package/src/og/input/input.js +7 -1
- package/src/og/layer/KML.js +181 -12
- package/src/og/layer/Layer.js +4 -2
- package/src/og/renderer/RendererEvents.js +17 -3
- package/src/og/scene/Planet.js +45 -27
- package/src/og/terrain/EmptyTerrain.js +159 -146
- package/src/og/terrain/Geoid.js +246 -241
- package/src/og/terrain/GlobusTerrain.js +17 -18
- package/src/og/terrain/MapboxTerrain.js +292 -294
- package/src/og/utils/PlainSegmentWorker.js +38 -26
- package/types/control/KeyboardNavigation.d.ts +3 -0
- package/types/input/input.d.ts +6 -0
- package/types/layer/KML.d.ts +26 -1
- package/types/renderer/RendererEvents.d.ts +2 -0
- package/types/scene/Planet.d.ts +5 -0
- package/types/terrain/EmptyTerrain.d.ts +3 -1
- package/types/terrain/Geoid.d.ts +1 -10
- package/types/terrain/GlobusTerrain.d.ts +0 -1
- package/types/terrain/MapboxTerrain.d.ts +1 -1
package/src/og/layer/KML.js
CHANGED
|
@@ -42,17 +42,179 @@ export class KML extends Vector {
|
|
|
42
42
|
_extractCoordonatesFromKml(xmlDoc) {
|
|
43
43
|
const raw = Array.from(xmlDoc.getElementsByTagName("coordinates"));
|
|
44
44
|
const rawText = raw.map(item => item.textContent.trim());
|
|
45
|
-
const coordinates = rawText.map(item =>
|
|
45
|
+
const coordinates = rawText.map(item =>
|
|
46
46
|
item
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
.replace(/\n/g, " ")
|
|
48
|
+
.replace(/\t/g, " ")
|
|
49
|
+
.replace(/ +/g, " ")
|
|
50
|
+
.split(" ")
|
|
51
|
+
.map((co) => co.split(",").map(parseFloat))
|
|
52
52
|
);
|
|
53
53
|
return coordinates;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
_AGBRtoRGBA(agbr) {
|
|
60
|
+
if (!agbr || agbr.length != 8) return
|
|
61
|
+
|
|
62
|
+
const a = parseInt(agbr.slice(0, 2), 16) / 255;
|
|
63
|
+
const b = parseInt(agbr.slice(2, 4), 16);
|
|
64
|
+
const g = parseInt(agbr.slice(4, 6), 16);
|
|
65
|
+
const r = parseInt(agbr.slice(6, 8), 16);
|
|
66
|
+
|
|
67
|
+
return `rgba(${r},${g},${b},${a})`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @private
|
|
72
|
+
returns array of longitude, latitude, altitude (altitude optional)
|
|
73
|
+
*/
|
|
74
|
+
_parseKMLcoordinates(coords) {
|
|
75
|
+
const coordinates = coords.innerHTML.trim()
|
|
76
|
+
.replace(/\n/g, ' ')
|
|
77
|
+
.replace(/\t/g, ' ')
|
|
78
|
+
.replace(/ +/g, ' ')
|
|
79
|
+
.split(" ")
|
|
80
|
+
.map((co) => co.split(",").map(parseFloat))
|
|
81
|
+
|
|
82
|
+
return coordinates;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
_kmlPlacemarkToEntity(placemark, extent) {
|
|
89
|
+
if (!placemark) return;
|
|
90
|
+
|
|
91
|
+
const nameTags = Array.from(placemark.getElementsByTagName("name"))
|
|
92
|
+
const name = nameTags && nameTags[0]?.innerHTML?.trim() || '';
|
|
93
|
+
|
|
94
|
+
const { iconHeading, iconURL, iconColor, lineWidth, lineColor } = this._extractStyle(placemark);
|
|
95
|
+
|
|
96
|
+
// TODO handle MultiGeometry
|
|
97
|
+
|
|
98
|
+
const lonLats = [];
|
|
99
|
+
for (const coord of placemark.getElementsByTagName("coordinates")) {
|
|
100
|
+
const coordinates = this._parseKMLcoordinates(coord) || [[0, 0, 0]]
|
|
101
|
+
|
|
102
|
+
for (const lonlatalt of coordinates) {
|
|
103
|
+
const [lon, lat, alt] = lonlatalt
|
|
104
|
+
|
|
105
|
+
lonLats.push(new LonLat(lon, lat, alt));
|
|
106
|
+
|
|
107
|
+
if (lon < extent.southWest.lon) extent.southWest.lon = lon;
|
|
108
|
+
if (lat < extent.southWest.lat) extent.southWest.lat = lat;
|
|
109
|
+
if (lon > extent.northEast.lon) extent.northEast.lon = lon;
|
|
110
|
+
if (lat > extent.northEast.lat) extent.northEast.lat = lat;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (lonLats.length === 1) {
|
|
115
|
+
const hdgrad = iconHeading * 0.01745329; // radians
|
|
116
|
+
|
|
117
|
+
return new Entity({
|
|
118
|
+
name,
|
|
119
|
+
lonlat: lonLats[0],
|
|
120
|
+
billboard: {
|
|
121
|
+
src: iconURL,
|
|
122
|
+
size: [24, 24],
|
|
123
|
+
color: iconColor,
|
|
124
|
+
rotation: hdgrad
|
|
125
|
+
},
|
|
126
|
+
properties: {
|
|
127
|
+
color: iconColor,
|
|
128
|
+
heading: iconHeading
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
} else {
|
|
133
|
+
return new Entity({
|
|
134
|
+
polyline: {
|
|
135
|
+
pathLonLat: [lonLats],
|
|
136
|
+
thickness: lineWidth,
|
|
137
|
+
color: lineColor,
|
|
138
|
+
isClosed: false
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
_extractStyle(placemark) {
|
|
145
|
+
let iconColor;
|
|
146
|
+
let iconHeading;
|
|
147
|
+
let iconURL;
|
|
148
|
+
let lineColor;
|
|
149
|
+
let lineWidth;
|
|
150
|
+
|
|
151
|
+
const style = placemark.getElementsByTagName("Style")[0];
|
|
152
|
+
if (style) {
|
|
153
|
+
let iconstyle = style.getElementsByTagName("IconStyle")[0];
|
|
154
|
+
if (iconstyle) {
|
|
155
|
+
let color = iconstyle.getElementsByTagName("color")[0];
|
|
156
|
+
if (color)
|
|
157
|
+
iconColor = this._AGBRtoRGBA(color.innerHTML.trim());
|
|
158
|
+
|
|
159
|
+
let heading = iconstyle.getElementsByTagName("heading")[0];
|
|
160
|
+
if (heading) {
|
|
161
|
+
const hdg = parseFloat(heading.innerHTML.trim());
|
|
162
|
+
if (hdg >= 0 && hdg <= 360)
|
|
163
|
+
iconHeading = hdg % 360;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let icon = iconstyle.getElementsByTagName("Icon")[0];
|
|
167
|
+
if (icon) {
|
|
168
|
+
let href = icon.getElementsByTagName("href")[0];
|
|
169
|
+
if (href) {
|
|
170
|
+
iconURL = href.innerHTML.trim();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let linestyle = style.getElementsByTagName("LineStyle")[0];
|
|
176
|
+
if (linestyle) {
|
|
177
|
+
let color = linestyle.getElementsByTagName("color")[0];
|
|
178
|
+
if (color)
|
|
179
|
+
lineColor = this._AGBRtoRGBA(color.innerHTML.trim());
|
|
180
|
+
let width = linestyle.getElementsByTagName("width")[0];
|
|
181
|
+
if (width !== undefined)
|
|
182
|
+
lineWidth = parseFloat(width.innerHTML.trim());
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!iconColor) iconColor = "#FFFFFF"
|
|
187
|
+
if (!iconHeading) iconHeading = 0
|
|
188
|
+
if (!iconURL) iconURL = "https://openglobus.org/examples/billboards/carrot.png"
|
|
189
|
+
|
|
190
|
+
if (!lineColor) lineColor = "#FFFFFF"
|
|
191
|
+
if (!lineWidth) lineWidth = 1
|
|
192
|
+
|
|
193
|
+
return { iconHeading, iconURL, iconColor, lineWidth, lineColor };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
_parseKML(xml, extent, entities = undefined) {
|
|
197
|
+
if (!entities)
|
|
198
|
+
entities = [];
|
|
199
|
+
|
|
200
|
+
if (xml.documentElement.nodeName !== "kml")
|
|
201
|
+
return entities;
|
|
202
|
+
|
|
203
|
+
for (const placemark of xml.getElementsByTagName("Placemark")) {
|
|
204
|
+
const entity = this._kmlPlacemarkToEntity(placemark, extent);
|
|
205
|
+
if (entity) entities.push(entity);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return entities;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
_convertKMLintoEntities(xml) {
|
|
212
|
+
const extent = new Extent(new LonLat(180.0, 90.0), new LonLat(-180.0, -90.0));
|
|
213
|
+
const entities = this._parseKML(xml, extent);
|
|
214
|
+
|
|
215
|
+
return { entities, extent }
|
|
216
|
+
}
|
|
217
|
+
|
|
56
218
|
/**
|
|
57
219
|
* Creates billboards or polylines from array of lonlat.
|
|
58
220
|
* @public
|
|
@@ -129,6 +291,7 @@ export class KML extends Vector {
|
|
|
129
291
|
* @returns {Promise<{entities: Entity[], extent: Extent}>}
|
|
130
292
|
*/
|
|
131
293
|
async addKmlFromFiles(kmls, color = null, billboard = null) {
|
|
294
|
+
if (!Array.isArray(kmls)) return null
|
|
132
295
|
const kmlObjs = await Promise.all(kmls.map(this._getXmlContent));
|
|
133
296
|
const coordonates = kmlObjs.map(this._extractCoordonatesFromKml);
|
|
134
297
|
const { entities, extent } = this._convertCoordonatesIntoEntities(
|
|
@@ -179,14 +342,20 @@ export class KML extends Vector {
|
|
|
179
342
|
*/
|
|
180
343
|
async addKmlFromUrl(url, color = null, billboard = null) {
|
|
181
344
|
const kml = await this._getKmlFromUrl(url);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
345
|
+
/*
|
|
346
|
+
const coordonates = this._extractCoordonatesFromKml(kml);
|
|
347
|
+
const { entities, extent } = this._convertCoordonatesIntoEntities(
|
|
348
|
+
[coordonates],
|
|
349
|
+
color || this._color,
|
|
350
|
+
billboard || this._billboard
|
|
351
|
+
);
|
|
352
|
+
*/
|
|
353
|
+
const { entities, extent } = this._convertKMLintoEntities(kml);
|
|
354
|
+
|
|
188
355
|
this._extent = this._expandExtents(this._extent, extent);
|
|
356
|
+
|
|
189
357
|
entities.forEach(this.add.bind(this));
|
|
358
|
+
|
|
190
359
|
return { entities, extent };
|
|
191
360
|
}
|
|
192
361
|
}
|
package/src/og/layer/Layer.js
CHANGED
|
@@ -413,8 +413,10 @@ class Layer {
|
|
|
413
413
|
* @param {string} html - HTML code that represents layer attribution, it could be just a text.
|
|
414
414
|
*/
|
|
415
415
|
setAttribution(html) {
|
|
416
|
-
this._attribution
|
|
417
|
-
|
|
416
|
+
if (this._attribution !== html) {
|
|
417
|
+
this._attribution = html;
|
|
418
|
+
this._planet && this._planet.updateAttributionsList();
|
|
419
|
+
}
|
|
418
420
|
}
|
|
419
421
|
|
|
420
422
|
/**
|
|
@@ -161,6 +161,8 @@ class RendererEvents extends Events {
|
|
|
161
161
|
prev_x: 0,
|
|
162
162
|
/** Previous touch Y coordinate. */
|
|
163
163
|
prev_y: 0,
|
|
164
|
+
/** Screen touch position world direction. */
|
|
165
|
+
direction: new Vec3(),
|
|
164
166
|
/** JavaScript touching system event message. */
|
|
165
167
|
sys: null,
|
|
166
168
|
/** Current touched(picking) object. */
|
|
@@ -222,6 +224,13 @@ class RendererEvents extends Events {
|
|
|
222
224
|
this.mouseState.x,
|
|
223
225
|
this.mouseState.y
|
|
224
226
|
);
|
|
227
|
+
//
|
|
228
|
+
// TODO: Replace in some other place with a thought that we do
|
|
229
|
+
// not need to make unproject when we do not make touching
|
|
230
|
+
this.touchState.direction = this.renderer.activeCamera.unproject(
|
|
231
|
+
this.touchState.x,
|
|
232
|
+
this.touchState.y
|
|
233
|
+
);
|
|
225
234
|
this.entityPickingEvents();
|
|
226
235
|
this._keyboardHandler.handleEvents();
|
|
227
236
|
this.handleMouseEvents();
|
|
@@ -493,7 +502,7 @@ class RendererEvents extends Events {
|
|
|
493
502
|
var ts = this.touchState;
|
|
494
503
|
ts.sys = event;
|
|
495
504
|
|
|
496
|
-
ts.
|
|
505
|
+
ts.clientX = event.touches.item(0).clientX - event.offsetLeft;
|
|
497
506
|
ts.clientY = event.touches.item(0).clientY - event.offsetTop;
|
|
498
507
|
|
|
499
508
|
let h = this.renderer.handler;
|
|
@@ -569,8 +578,13 @@ class RendererEvents extends Events {
|
|
|
569
578
|
|
|
570
579
|
ts.sys = event;
|
|
571
580
|
ts.moving = true;
|
|
572
|
-
|
|
573
|
-
|
|
581
|
+
|
|
582
|
+
var dX = ts.x - ts.prev_x
|
|
583
|
+
var dY = ts.y - ts.prev_y
|
|
584
|
+
if (Math.abs(dX) > 9 || Math.abs(dY) > 9) {
|
|
585
|
+
this._dblTchBegins = 0;
|
|
586
|
+
this._oneTouchStart = false;
|
|
587
|
+
}
|
|
574
588
|
}
|
|
575
589
|
|
|
576
590
|
/**
|
package/src/og/scene/Planet.js
CHANGED
|
@@ -613,21 +613,36 @@ export class Planet extends RenderNode {
|
|
|
613
613
|
this._quadTree.destroyBranches();
|
|
614
614
|
}
|
|
615
615
|
|
|
616
|
-
if (terrain._geoid) {
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
.
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
616
|
+
//if (terrain._geoid) {
|
|
617
|
+
|
|
618
|
+
if (terrain._geoid.model) {
|
|
619
|
+
this._plainSegmentWorker.setGeoid(terrain.getGeoid());
|
|
620
|
+
terrain._isReady = true;
|
|
621
|
+
} else {
|
|
622
|
+
Geoid.loadModel(terrain._geoid.src)
|
|
623
|
+
.then((m) => {
|
|
624
|
+
terrain.getGeoid().setModel(m);
|
|
625
|
+
this._plainSegmentWorker.setGeoid(terrain.getGeoid());
|
|
626
|
+
terrain._isReady = true;
|
|
627
|
+
})
|
|
628
|
+
.catch((err) => {
|
|
629
|
+
console.log(err);
|
|
630
|
+
});
|
|
630
631
|
}
|
|
632
|
+
|
|
633
|
+
// if (!terrain._geoid.model) {
|
|
634
|
+
// Geoid.loadModel(terrain._geoid.src)
|
|
635
|
+
// .then((m) => {
|
|
636
|
+
// terrain.getGeoid().setModel(m);
|
|
637
|
+
// this._plainSegmentWorker.setGeoid(terrain.getGeoid());
|
|
638
|
+
// })
|
|
639
|
+
// .catch((err) => {
|
|
640
|
+
// console.log(err);
|
|
641
|
+
// });
|
|
642
|
+
// } else {
|
|
643
|
+
// this._plainSegmentWorker.setGeoid(terrain.getGeoid());
|
|
644
|
+
// }
|
|
645
|
+
//}
|
|
631
646
|
}
|
|
632
647
|
|
|
633
648
|
/**
|
|
@@ -917,15 +932,7 @@ export class Planet extends RenderNode {
|
|
|
917
932
|
}
|
|
918
933
|
}
|
|
919
934
|
|
|
920
|
-
|
|
921
|
-
if (html.length) {
|
|
922
|
-
this.renderer.div.attributions.style.display = "block";
|
|
923
|
-
this.renderer.div.attributions.innerHTML = "<ul>" + html + "</ul>";
|
|
924
|
-
} else {
|
|
925
|
-
this.renderer.div.attributions.style.display = "none";
|
|
926
|
-
this.renderer.div.attributions.innerHTML = "";
|
|
927
|
-
}
|
|
928
|
-
}
|
|
935
|
+
this._applyAttribution(html)
|
|
929
936
|
}
|
|
930
937
|
|
|
931
938
|
/**
|
|
@@ -971,17 +978,28 @@ export class Planet extends RenderNode {
|
|
|
971
978
|
}
|
|
972
979
|
}
|
|
973
980
|
|
|
981
|
+
this._applyAttribution(html);
|
|
982
|
+
|
|
983
|
+
this._sortLayers();
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Apply to render list of layer attributions
|
|
988
|
+
* @private
|
|
989
|
+
*/
|
|
990
|
+
_applyAttribution(html) {
|
|
974
991
|
if (this.renderer) {
|
|
975
992
|
if (html.length) {
|
|
976
|
-
|
|
977
|
-
this.renderer.div.attributions.innerHTML
|
|
993
|
+
html = "<ul>" + html + "</ul>";
|
|
994
|
+
if (this.renderer.div.attributions.innerHTML !== html) {
|
|
995
|
+
this.renderer.div.attributions.style.display = "block";
|
|
996
|
+
this.renderer.div.attributions.innerHTML = html;
|
|
997
|
+
}
|
|
978
998
|
} else {
|
|
979
999
|
this.renderer.div.attributions.style.display = "none";
|
|
980
1000
|
this.renderer.div.attributions.innerHTML = "";
|
|
981
1001
|
}
|
|
982
1002
|
}
|
|
983
|
-
|
|
984
|
-
this._sortLayers();
|
|
985
1003
|
}
|
|
986
1004
|
|
|
987
1005
|
/**
|