=0?(i=65536*Math.floor(e/65536),n.high=i,n.low=e-i):(i=65536*Math.floor(-e/65536),n.high=-i,n.low=e+i),n};const t={high:0,low:0};i.fromCartesian=function(e,n){o.defined(n)||(n=new i);const h=n.high,a=n.low;return i.encode(e.x,t),h.x=t.high,a.x=t.low,i.encode(e.y,t),h.y=t.high,a.y=t.low,i.encode(e.z,t),h.z=t.high,a.z=t.low,n};const h=new i;i.writeElements=function(e,n,o){i.fromCartesian(e,h);const t=h.high,a=h.low;n[o]=t.x,n[o+1]=t.y,n[o+2]=t.z,n[o+3]=a.x,n[o+4]=a.y,n[o+5]=a.z},e.EncodedCartesian3=i}));
2 |
--------------------------------------------------------------------------------
/js/cesium-1.105.1/Workers/GeometryAttribute-9c1a6bab.js:
--------------------------------------------------------------------------------
1 | define(["exports","./Matrix2-7a8e9daf","./Matrix3-b2351961","./defaultValue-f6d5e6da","./WebGLConstants-7f557f93","./Transforms-f17097e5"],(function(t,e,n,a,r,i){"use strict";var o=Object.freeze({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3});const s={POINTS:r.WebGLConstants.POINTS,LINES:r.WebGLConstants.LINES,LINE_LOOP:r.WebGLConstants.LINE_LOOP,LINE_STRIP:r.WebGLConstants.LINE_STRIP,TRIANGLES:r.WebGLConstants.TRIANGLES,TRIANGLE_STRIP:r.WebGLConstants.TRIANGLE_STRIP,TRIANGLE_FAN:r.WebGLConstants.TRIANGLE_FAN,isLines:function(t){return t===s.LINES||t===s.LINE_LOOP||t===s.LINE_STRIP},isTriangles:function(t){return t===s.TRIANGLES||t===s.TRIANGLE_STRIP||t===s.TRIANGLE_FAN},validate:function(t){return t===s.POINTS||t===s.LINES||t===s.LINE_LOOP||t===s.LINE_STRIP||t===s.TRIANGLES||t===s.TRIANGLE_STRIP||t===s.TRIANGLE_FAN}};var u=Object.freeze(s);function I(t){t=a.defaultValue(t,a.defaultValue.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=a.defaultValue(t.primitiveType,u.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=a.defaultValue(t.geometryType,o.NONE),this.boundingSphereCV=t.boundingSphereCV,this.offsetAttribute=t.offsetAttribute}I.computeNumberOfVertices=function(t){let e=-1;for(const n in t.attributes)if(t.attributes.hasOwnProperty(n)&&a.defined(t.attributes[n])&&a.defined(t.attributes[n].values)){const a=t.attributes[n];e=a.values.length/a.componentsPerAttribute}return e};const N=new n.Cartographic,T=new n.Cartesian3,l=new e.Matrix4,c=[new n.Cartographic,new n.Cartographic,new n.Cartographic],L=[new e.Cartesian2,new e.Cartesian2,new e.Cartesian2],E=[new e.Cartesian2,new e.Cartesian2,new e.Cartesian2],f=new n.Cartesian3,p=new i.Quaternion,m=new e.Matrix4,y=new e.Matrix2;I._textureCoordinateRotationPoints=function(t,a,r,o){let s;const u=e.Rectangle.center(o,N),I=n.Cartographic.toCartesian(u,r,T),C=i.Transforms.eastNorthUpToFixedFrame(I,r,l),b=e.Matrix4.inverse(C,l),h=L,A=c;A[0].longitude=o.west,A[0].latitude=o.south,A[1].longitude=o.west,A[1].latitude=o.north,A[2].longitude=o.east,A[2].latitude=o.south;let x=f;for(s=0;s<3;s++)n.Cartographic.toCartesian(A[s],r,x),x=e.Matrix4.multiplyByPointAsVector(b,x,x),h[s].x=x.x,h[s].y=x.y;const S=i.Quaternion.fromAxisAngle(n.Cartesian3.UNIT_Z,-a,p),d=n.Matrix3.fromQuaternion(S,m),P=t.length;let G=Number.POSITIVE_INFINITY,R=Number.POSITIVE_INFINITY,_=Number.NEGATIVE_INFINITY,O=Number.NEGATIVE_INFINITY;for(s=0;s=e.CesiumMath.SIXTY_FOUR_KILOBYTES?new Uint32Array(r):new Uint16Array(r)},createTypedArrayFromArrayBuffer:function(n,r,t,N){return n>=e.CesiumMath.SIXTY_FOUR_KILOBYTES?new Uint32Array(r,t,N):new Uint16Array(r,t,N)},fromTypedArray:function(n){return n instanceof Uint8Array?N.UNSIGNED_BYTE:n instanceof Uint16Array?N.UNSIGNED_SHORT:n instanceof Uint32Array?N.UNSIGNED_INT:void 0}};var E=Object.freeze(N);n.IndexDatatype=E}));
2 |
--------------------------------------------------------------------------------
/js/cesium-1.105.1/Workers/Plane-5931b53e.js:
--------------------------------------------------------------------------------
1 | define(["exports","./Matrix3-b2351961","./Matrix2-7a8e9daf","./defaultValue-f6d5e6da"],(function(n,e,a,t){"use strict";function r(n,a){this.normal=e.Cartesian3.clone(n),this.distance=a}r.fromPointNormal=function(n,a,i){const s=-e.Cartesian3.dot(a,n);return t.defined(i)?(e.Cartesian3.clone(a,i.normal),i.distance=s,i):new r(a,s)};const i=new e.Cartesian3;r.fromCartesian4=function(n,a){const s=e.Cartesian3.fromCartesian4(n,i),o=n.w;return t.defined(a)?(e.Cartesian3.clone(s,a.normal),a.distance=o,a):new r(s,o)},r.getPointDistance=function(n,a){return e.Cartesian3.dot(n.normal,a)+n.distance};const s=new e.Cartesian3;r.projectPointOntoPlane=function(n,a,i){t.defined(i)||(i=new e.Cartesian3);const o=r.getPointDistance(n,a),c=e.Cartesian3.multiplyByScalar(n.normal,o,s);return e.Cartesian3.subtract(a,c,i)};const o=new a.Matrix4,c=new a.Cartesian4,l=new e.Cartesian3;r.transform=function(n,t,i){const s=n.normal,C=n.distance,d=a.Matrix4.inverseTranspose(t,o);let f=a.Cartesian4.fromElements(s.x,s.y,s.z,C,c);f=a.Matrix4.multiplyByVector(d,f,f);const u=e.Cartesian3.fromCartesian4(f,l);return f=a.Cartesian4.divideByScalar(f,e.Cartesian3.magnitude(u),f),r.fromCartesian4(f,i)},r.clone=function(n,a){return t.defined(a)?(e.Cartesian3.clone(n.normal,a.normal),a.distance=n.distance,a):new r(n.normal,n.distance)},r.equals=function(n,a){return n.distance===a.distance&&e.Cartesian3.equals(n.normal,a.normal)},r.ORIGIN_XY_PLANE=Object.freeze(new r(e.Cartesian3.UNIT_Z,0)),r.ORIGIN_YZ_PLANE=Object.freeze(new r(e.Cartesian3.UNIT_X,0)),r.ORIGIN_ZX_PLANE=Object.freeze(new r(e.Cartesian3.UNIT_Y,0)),n.Plane=r}));
2 |
--------------------------------------------------------------------------------
/js/cesium-1.105.1/Workers/RectangleGeometryLibrary-6ad7ff7a.js:
--------------------------------------------------------------------------------
1 | define(["exports","./Matrix3-b2351961","./defaultValue-f6d5e6da","./Transforms-f17097e5","./Math-355606c6","./Matrix2-7a8e9daf"],(function(t,n,a,o,r,e){"use strict";const s=Math.cos,i=Math.sin,c=Math.sqrt,g={computePosition:function(t,n,o,r,e,g,u){const h=n.radiiSquared,l=t.nwCorner,C=t.boundingRectangle;let S=l.latitude-t.granYCos*r+e*t.granXSin;const M=s(S),d=i(S),w=h.z*d;let X=l.longitude+r*t.granYSin+e*t.granXCos;const Y=M*s(X),m=M*i(X),f=h.x*Y,p=h.y*m,x=c(f*Y+p*m+w*d);if(g.x=f/x,g.y=p/x,g.z=w/x,o){const n=t.stNwCorner;a.defined(n)?(S=n.latitude-t.stGranYCos*r+e*t.stGranXSin,X=n.longitude+r*t.stGranYSin+e*t.stGranXCos,u.x=(X-t.stWest)*t.lonScalar,u.y=(S-t.stSouth)*t.latScalar):(u.x=(X-C.west)*t.lonScalar,u.y=(S-C.south)*t.latScalar)}}},u=new e.Matrix2;let h=new n.Cartesian3;const l=new n.Cartographic;let C=new n.Cartesian3;const S=new o.GeographicProjection;function M(t,a,o,r,s,i,c){const g=Math.cos(a),l=r*g,M=o*g,d=Math.sin(a),w=r*d,X=o*d;h=S.project(t,h),h=n.Cartesian3.subtract(h,C,h);const Y=e.Matrix2.fromRotation(a,u);h=e.Matrix2.multiplyByVector(Y,h,h),h=n.Cartesian3.add(h,C,h),i-=1,c-=1;const m=(t=S.unproject(h,t)).latitude,f=m+i*X,p=m-l*c,x=m-l*c+i*X,G=Math.max(m,f,p,x),R=Math.min(m,f,p,x),y=t.longitude,O=y+i*M,P=y+c*w,W=y+c*w+i*M;return{north:G,south:R,east:Math.max(y,O,P,W),west:Math.min(y,O,P,W),granYCos:l,granYSin:w,granXCos:M,granXSin:X,nwCorner:t}}g.computeOptions=function(t,n,a,o,s,i,c){let g,u=t.east,h=t.west,d=t.north,w=t.south,X=!1,Y=!1;d===r.CesiumMath.PI_OVER_TWO&&(X=!0),w===-r.CesiumMath.PI_OVER_TWO&&(Y=!0);const m=d-w;g=h>u?r.CesiumMath.TWO_PI-h+u:u-h;const f=Math.ceil(g/n)+1,p=Math.ceil(m/n)+1,x=g/(f-1),G=m/(p-1),R=e.Rectangle.northwest(t,i),y=e.Rectangle.center(t,l);0===a&&0===o||(y.longitudea.MaximumLatitude?t=a.MaximumLatitude:t<-a.MaximumLatitude&&(t=-a.MaximumLatitude);const e=Math.sin(t);return.5*Math.log((1+e)/(1-e))},a.MaximumLatitude=a.mercatorAngleToGeodeticLatitude(Math.PI),a.prototype.project=function(t,o){const r=this._semimajorAxis,n=t.longitude*r,u=a.geodeticLatitudeToMercatorAngle(t.latitude)*r,d=t.height;return i.defined(o)?(o.x=n,o.y=u,o.z=d,o):new e.Cartesian3(n,u,d)},a.prototype.unproject=function(t,o){const r=this._oneOverSemimajorAxis,n=t.x*r,u=a.mercatorAngleToGeodeticLatitude(t.y*r),d=t.z;return i.defined(o)?(o.longitude=n,o.latitude=u,o.height=d,o):new e.Cartographic(n,u,d)},t.WebMercatorProjection=a}));
2 |
--------------------------------------------------------------------------------
/js/cesium-1.105.1/Workers/arrayRemoveDuplicates-0d8dde26.js:
--------------------------------------------------------------------------------
1 | define(["exports","./defaultValue-f6d5e6da","./Math-355606c6"],(function(e,n,t){"use strict";const i=t.CesiumMath.EPSILON10;e.arrayRemoveDuplicates=function(e,t,d,f){if(!n.defined(e))return;d=n.defaultValue(d,!1);const u=n.defined(f),s=e.length;if(s<2)return e;let l,r,a,c=e[0],h=0,o=-1;for(l=1;l0){const t=Math.min(y,p);A=Math.round(p/t),G+=t}const R=f.IndexDatatype.createTypedArray(_,2*G);let O,V=0;for(O=0;O0)for(O=0;O"u"&&(self={}),self.onmessage=function(a){const e=a.data.array,s=self.webkitPostMessage||self.postMessage;try{s({array:e},[e.buffer])}catch{s({})}};
27 |
--------------------------------------------------------------------------------
/js/cities/cesium-toolbar-button.js:
--------------------------------------------------------------------------------
1 | import CitiesDataSource from './CitiesDataSource.js'
2 |
3 | function htmlToElement(html) {
4 | var template = document.createElement('template');
5 | html = html.trim(); // Never return a text node of whitespace as the result
6 | template.innerHTML = html;
7 | return template.content.firstChild;
8 | }
9 |
10 | const svg = `M 22.82 31.243 L 19.451 22.169 L 7.143 22.169 L 3.773 31.243 L 0 31.243 L 11.725 0 L 15.094 0 \
11 | L 26.818 31.243 L 22.82 31.243 Z M 8.288 19.024 L 18.283 19.024 L 13.297 5.548 L 8.288 19.024 Z`;
12 |
13 | export default function LabelsButton(viewer) {
14 | var container = Cesium.getElement(document.querySelector('.cesium-viewer-toolbar'));
15 |
16 | var element = document.createElement("button");
17 | element.type = "button";
18 | element.className = "cesium-button cesium-toolbar-button cesium-home-button";
19 | element.setAttribute(
20 | "data-bind",
21 | "attr: { title: tooltip }, click: command, cesiumSvgPath: { path: _svgPath, width: 26, height: 34 }"
22 | );
23 |
24 | const viewModel = {
25 | _svgPath: svg,
26 | active: true,
27 | ds: CitiesDataSource(viewer),
28 | command: function() {
29 | this.ds.show = !this.ds.show;
30 | },
31 | tooltip: "Labels"
32 | };
33 | viewModel.ds.show = false;
34 | Cesium.knockout.applyBindings(viewModel, element);
35 |
36 | container.appendChild(element);
37 | }
38 |
--------------------------------------------------------------------------------
/js/components/entity-info.js:
--------------------------------------------------------------------------------
1 | import './position.js'
2 | import './orientation.js'
3 | import './geometry.js'
4 |
5 | function round(value, step = 1.0) {
6 | const inv = 1.0 / step;
7 | return Math.round(value * inv) / inv;
8 | }
9 |
10 | export function getLonLatHeight(entity) {
11 | if (entity.position) {
12 | const cartographic = Cesium.Cartographic.fromCartesian(entity.position.getValue());
13 |
14 | return {
15 | latitude: Cesium.Math.toDegrees(cartographic.latitude),
16 | longitude: Cesium.Math.toDegrees(cartographic.longitude),
17 | height: cartographic.height
18 | }
19 | }
20 |
21 | return null;
22 | }
23 |
24 | const template = `
25 |
26 |
27 |
28 | Position
29 |
30 |
31 |
32 | Latitude
33 |
34 |
35 |
36 | Longitude
37 |
38 |
39 |
40 | Altitude
41 |
42 |
43 |
44 | {{ round(position.latitude, 0.0001) }}
45 |
46 |
47 |
48 | {{ round(position.longitude, 0.0001) }}
49 |
50 |
51 |
52 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | `;
69 |
70 | Vue.component('entity-info', {
71 | props: ['entity'],
72 | template: template,
73 | data: () => ({
74 | position: null
75 | }),
76 | created: function() {
77 | this.position = this.entity
78 | && this.entity.position
79 | && getLonLatHeight(this.entity);
80 | },
81 | watch: {
82 | entity: function(entity) {
83 | this.position = entity
84 | && entity.position
85 | && getLonLatHeight(entity);
86 | }
87 | },
88 | methods: {
89 | round,
90 | updateAltitude: function(altitude) {
91 | let c = Cesium.Cartographic.fromCartesian(this.entity.position.getValue());
92 | c.height = parseFloat(altitude) || 0.0;
93 | this.entity.position = Cesium.Cartographic.toCartesian(c);
94 | }
95 | }
96 | });
--------------------------------------------------------------------------------
/js/components/entity-list-item.js:
--------------------------------------------------------------------------------
1 | const template = `
2 |
4 |
5 |
6 |
7 |
8 |
9 | mdi-folder
10 | mdi-pin
11 | mdi-widgets-outline
12 | mdi-vector-polyline
13 |
14 |
15 |
16 |
17 |
18 |
19 | `;
20 |
21 | Vue.component('entity-list-item', {
22 | props: ['entity', 'isFolder'],
23 | methods: {
24 | selectHandler: function() {
25 | this.$emit('select', this.entity);
26 | },
27 | doubleClick: function() {
28 | this.$emit('zoom-to');
29 | }
30 | },
31 | template: template
32 | });
--------------------------------------------------------------------------------
/js/components/entity-type-label.js:
--------------------------------------------------------------------------------
1 | const template = `
2 | {{ label }}
3 | `;
4 |
5 | const LABELS = {
6 | polyline: 'Line',
7 | polygon: 'Polygon',
8 | model: '3d Model',
9 | rectangle: 'Rectangle',
10 | billboard: 'Pin',
11 | label: 'Label'
12 | }
13 |
14 | const PLURALS = {
15 | polyline: 'Lines',
16 | polygon: 'Polygons',
17 | model: '3d Models',
18 | rectangle: 'Rectangles',
19 | billboard: 'Pins',
20 | label: 'Labels'
21 | }
22 |
23 | export function entityType(entity) {
24 | return Object.keys(LABELS).find(t => {
25 | return entity[t] !== undefined;
26 | });
27 | }
28 |
29 | export function labelForType(type, plural = true) {
30 | return plural ? PLURALS[type] : LABELS[type];
31 | }
32 |
33 | Vue.component('entity-type-label', {
34 | template,
35 | props: {
36 | entity: {
37 | type: Object,
38 | required: true
39 | },
40 | plural: {
41 | type: Boolean,
42 | required: false,
43 | default: true
44 | }
45 | },
46 | computed: {
47 | label() {
48 | let type = entityType(this.entity);
49 | return this.plural ? PLURALS[type] : LABELS[type];
50 | }
51 | }
52 | });
--------------------------------------------------------------------------------
/js/components/geometry.js:
--------------------------------------------------------------------------------
1 | import GeometryEditor from '../util/GeometryEditor.js'
2 |
3 | import {
4 | disableSelectedEntityChangeListener,
5 | enableSelectedEntityChangeListener
6 | } from '../index.js'
7 |
8 | const template = `
9 |
10 |
11 | Edit geometry
12 |
13 |
14 |
15 | Click on map to add points. Or move existing points.
16 |
17 |
18 | Save
19 |
20 |
21 | Cancel
22 |
23 |
24 |
25 | `;
26 |
27 | let geometryEditor;
28 |
29 | Vue.component('geometry-editor', {
30 | template,
31 | props: ['entity'],
32 | data: function () {
33 | const active = geometryEditor && geometryEditor.entity === this.entity;
34 | return {
35 | active,
36 | };
37 | },
38 | mounted() {
39 | if (!geometryEditor) {
40 | geometryEditor = new GeometryEditor(viewer);
41 | }
42 |
43 | if (!this.active) {
44 | enableSelectedEntityChangeListener();
45 | }
46 | },
47 | computed: {
48 | type() {
49 | return this.entity.polygon ? 'polygon' : this.entity.polyline ? 'polyline' : null;
50 | }
51 | },
52 | methods: {
53 | edit() {
54 | disableSelectedEntityChangeListener();
55 | this.active = true;
56 | if (!geometryEditor.entity) {
57 | geometryEditor.editEntity(this.type, this.entity);
58 | }
59 | },
60 | save() {
61 | enableSelectedEntityChangeListener();
62 | this.active = false;
63 | geometryEditor.save();
64 | },
65 | cancel() {
66 | enableSelectedEntityChangeListener();
67 | this.active = false;
68 | geometryEditor.cancel();
69 | }
70 | }
71 | });
72 |
--------------------------------------------------------------------------------
/js/components/orientation.js:
--------------------------------------------------------------------------------
1 | const template = `
2 |
3 |
4 |
9 |
10 |
11 |
16 |
17 |
18 |
23 |
24 |
25 | `;
26 |
27 | export function localHPRToGlobalOrientationQuaternion(position, hpr) {
28 | return Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
29 | }
30 |
31 | export function globalOrientationQuaternionToLocalHPR(position, orientation) {
32 | let orientationAbs = Cesium.Matrix3.fromQuaternion(orientation, new Cesium.Matrix3());
33 |
34 | let transform = Cesium.Matrix4.fromRotationTranslation(
35 | orientationAbs,
36 | position,
37 | new Cesium.Matrix4());
38 |
39 | return Cesium.Transforms.fixedFrameToHeadingPitchRoll(transform);
40 | }
41 |
42 | Vue.component('orientation-editor', {
43 | template,
44 | props: ['entity'],
45 | computed: {
46 | hpr: {
47 | get: function() {
48 | if (this.entity.orientation) {
49 | return globalOrientationQuaternionToLocalHPR(
50 | this.entity.position.getValue(),
51 | this.entity.orientation.getValue()
52 | );
53 | }
54 | return null;
55 | },
56 | set: function(newVal) {
57 | let orientationQ = localHPRToGlobalOrientationQuaternion(
58 | this.entity.position.getValue(),
59 | newVal
60 | );
61 | this.entity.orientation = orientationQ;
62 | }
63 | },
64 | heading: {
65 | get: function() {
66 | if (this.hpr) {
67 | return Math.round(Cesium.Math.toDegrees(this.hpr.heading));
68 | }
69 | return null;
70 | },
71 | set: function(heading) {
72 | this.hpr = Cesium.HeadingPitchRoll.fromDegrees(heading, this.pitch, this.roll);
73 | }
74 | },
75 | pitch: {
76 | get: function() {
77 | if (this.hpr) {
78 | return Math.round(Cesium.Math.toDegrees(this.hpr.pitch));
79 | }
80 | return null;
81 | },
82 | set: function(pitch) {
83 | this.hpr = Cesium.HeadingPitchRoll.fromDegrees(this.heading, pitch, this.roll);
84 | }
85 | },
86 | roll: {
87 | get: function() {
88 | if (this.hpr) {
89 | return Math.round(Cesium.Math.toDegrees(this.hpr.roll));
90 | }
91 | return null;
92 | },
93 | set: function(roll) {
94 | this.hpr = Cesium.HeadingPitchRoll.fromDegrees(this.heading, this.pitch, roll);
95 | }
96 | }
97 | }
98 | });
99 |
--------------------------------------------------------------------------------
/js/customizations.js:
--------------------------------------------------------------------------------
1 | window.addEventListener('viewer-created', e => {
2 | console.log('Cesium viewer created', e.detail.viewer);
3 | });
--------------------------------------------------------------------------------
/js/editors/model.js:
--------------------------------------------------------------------------------
1 | import '../fields/direct.js'
2 | import '../fields/checkbox.js'
3 | import '../fields/enum.js'
4 | import '../fields/material.js'
5 |
6 | const template = `
7 |
8 |
Model
9 |
10 |
16 |
17 |
18 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
39 |
40 |
48 |
49 |
56 |
57 |
58 |
66 |
67 |
75 |
76 |
77 |
78 | `;
79 |
80 | Vue.component('model-editor', {
81 | props: ['entity', 'model', 'advanced'],
82 | template: template,
83 | methods: {
84 | inputHandler(...args) {
85 | this.$emit('update', ...args);
86 | }
87 | }
88 | });
--------------------------------------------------------------------------------
/js/editors/polyline.js:
--------------------------------------------------------------------------------
1 | import '../fields/direct.js'
2 | import '../fields/checkbox.js'
3 | import '../fields/enum.js'
4 | import '../fields/material.js'
5 |
6 | const template = `
7 |
8 |
Polyline
9 |
10 |
16 |
17 |
18 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | {{ avgHeight }}
33 |
34 |
35 |
41 |
42 |
43 |
49 |
50 |
51 |
59 |
60 |
61 | Property specifying whether this polyline will classify terrain, 3D Tiles,
62 | or both when clamped to the ground.
63 |
64 |
65 |
66 | `;
67 |
68 | export function polylineAverageHeight(polyline) {
69 | const positions = polyline.positions.getValue().map(v => {
70 | return Cesium.Cartographic.fromCartesian(v);
71 | });
72 | const heights = positions.map(p => p.height);
73 | return heights.reduce((acc, val) => acc + val) / heights.length;
74 | }
75 |
76 | Vue.component('polyline-editor', {
77 | props: ['entity', 'polyline', 'advanced'],
78 | data: () => ({
79 | avgHeight: null,
80 | }),
81 | template: template,
82 | methods: {
83 | inputHandler(...args) {
84 | this.$emit('update', ...args);
85 | },
86 | getAvgHeight: function(val) {
87 | this.avgHeight = polylineAverageHeight(val);
88 | }
89 | },
90 | created: function() {
91 | this.getAvgHeight(this.polyline);
92 | },
93 | watch: {
94 | polyline: function(newVal) {
95 | this.getAvgHeight(newVal);
96 | }
97 | }
98 | });
--------------------------------------------------------------------------------
/js/fields/angle.js:
--------------------------------------------------------------------------------
1 | const template = `
8 | `;
9 |
10 | Vue.component('angle-field', {
11 | props: ['entity', 'feature', 'field', 'label'],
12 | methods: {
13 | handleUpdate: function() {
14 | let val = undefined;
15 |
16 | if (this.entity[this.feature][this.field]) {
17 | val = this.entity[this.feature][this.field].getValue();
18 | }
19 | this.$emit('input', val, this.field, this.feature, this.entity);
20 | }
21 | },
22 | computed: {
23 | value: {
24 | get: function() {
25 | if (this.entity[this.feature][this.field]) {
26 | let val = this.entity[this.feature][this.field].getValue();
27 | if (!Number.isNaN(val)) {
28 | return Cesium.Math.toDegrees(val);
29 | }
30 | }
31 | return undefined;
32 | },
33 | set: function(value) {
34 | if (value === undefined || value === null || value === '') {
35 | let pd = Object.getOwnPropertyDescriptor(this.entity[this.feature].__proto__, this.field);
36 | pd.set.apply(this.entity[this.feature], [ undefined ]);
37 | }
38 | else {
39 | let val = Cesium.Math.toRadians(value);
40 | if (!Number.isNaN(val)) {
41 | this.entity[this.feature][this.field] = val;
42 | }
43 | }
44 | this.handleUpdate();
45 | }
46 | }
47 | },
48 | template: template
49 | });
--------------------------------------------------------------------------------
/js/fields/checkbox.js:
--------------------------------------------------------------------------------
1 | const template = ``;
4 |
5 | Vue.component('checkbox-field', {
6 | props: ['entity', 'feature', 'field', 'label'],
7 | template: template,
8 | methods: {
9 | change: function(value) {
10 | this.$emit('input', value, this.field, this.feature, this.entity);
11 | }
12 | },
13 | computed: {
14 | checked: {
15 | get: function() {
16 | let fld = this.entity[this.feature][this.field];
17 | return fld ? fld.valueOf() : undefined;
18 | },
19 | set: function(v) {
20 | if (v === null || v === undefined) {
21 | let pd = Object.getOwnPropertyDescriptor(this.entity[this.feature].__proto__, this.field);
22 | pd.set.apply(this.entity[this.feature], [ undefined ]);
23 | }
24 | this.entity[this.feature][this.field] = v;
25 | }
26 | }
27 | }
28 | });
--------------------------------------------------------------------------------
/js/fields/components.js:
--------------------------------------------------------------------------------
1 | const template = `
2 |
3 |
4 | {{ label }}
5 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
19 | set new
21 |
22 |
23 | `;
24 |
25 | Vue.component('components-field', {
26 | props: ['entity', 'feature', 'field', 'type', 'components', 'label'],
27 | data: function() {
28 | const values = this.components.reduce((a, b) => (a[b] = null, a), {});
29 |
30 | if (this.entity[this.feature][this.field]) {
31 | this.components.forEach(c => {
32 | values[c] = parseInt(this.entity[this.feature][this.field].getValue()[c]);
33 | });
34 | }
35 |
36 | return { values };
37 | },
38 | methods: {
39 | update: function() {
40 | // Synchronized values from local model data to Cesium
41 | const values = {};
42 |
43 | this.components.forEach(c => {
44 | values[c] = parseInt(this.values[c]);
45 | });
46 |
47 | let val = undefined;
48 | if (this.entity[this.feature][this.field]) {
49 | val = this.entity[this.feature][this.field].getValue();
50 | }
51 |
52 | if (this.components.every(c => !isNaN(values[c]))) {
53 | let args = this.components.map(c => values[c]);
54 | val = new Cesium[this.type](...args);
55 | this.entity[this.feature][this.field] = val;
56 | }
57 |
58 | this.$emit('input', val, this.field, this.feature, this.entity);
59 | },
60 | newValue: function() {
61 | let val = new Cesium[this.type]();
62 | this.entity[this.feature][this.field] = val;
63 | this.$emit('input', val, this.field, this.feature, this.entity);
64 | }
65 | },
66 | watch: {
67 | entity: function(newValue) {
68 | const values = this.components.reduce((a, b) => (a[b] = null, a), {});
69 |
70 | if (newValue[this.feature][this.field]) {
71 | this.components.forEach(c => {
72 | values[c] = parseInt(newValue[this.feature][this.field].getValue()[c]);
73 | });
74 | }
75 |
76 | this.values = values;
77 | }
78 | },
79 | template: template
80 | });
--------------------------------------------------------------------------------
/js/fields/direct.js:
--------------------------------------------------------------------------------
1 | const template = `
10 | `;
11 |
12 | Vue.component('direct-field', {
13 | props: ['entity', 'feature', 'field', 'label', 'rules', 'validator'],
14 | methods: {
15 | input: function(value) {
16 | if (value === undefined || value === null || value === '') {
17 | let pd = Object.getOwnPropertyDescriptor(this.entity[this.feature].__proto__, this.field);
18 | pd.set.apply(this.entity[this.feature], [ undefined ]);
19 | } else if (this.validator) {
20 | if (this.validator(value)) {
21 | this.entity[this.feature][this.field] = value;
22 | this.handleUpdate();
23 | }
24 | }
25 | else {
26 | this.entity[this.feature][this.field] = value;
27 | this.handleUpdate();
28 | }
29 | },
30 | handleUpdate: function() {
31 | let val = undefined;
32 |
33 | if (this.entity[this.feature][this.field]) {
34 | val = this.entity[this.feature][this.field].getValue();
35 | }
36 | this.$emit('input', val, this.field, this.feature, this.entity);
37 | }
38 | },
39 | template: template
40 | });
--------------------------------------------------------------------------------
/js/fields/enum.js:
--------------------------------------------------------------------------------
1 | const template = `
2 | `;
12 |
13 | Vue.component('enum-field', {
14 | props: ['entity', 'feature', 'field', 'enum', 'label'],
15 | data: function() {
16 | let value = 'undefined';
17 |
18 | if (this.entity[this.feature][this.field]) {
19 | let v = this.entity[this.feature][this.field].getValue();
20 | Object.keys(Cesium[this.enum]).forEach(k => {
21 | if( Cesium[this.enum][k] === v ) {
22 | value = k;
23 | }
24 | });
25 | }
26 |
27 | return {
28 | value: value,
29 | options: [...Object.keys(Cesium[this.enum])]
30 | };
31 | },
32 | methods: {
33 | update: function() {
34 | // Synchronized values from local model data to Cesium
35 | let val = Cesium[this.enum][this.value];
36 | if (val === undefined) {
37 | let pd = Object.getOwnPropertyDescriptor(this.entity[this.feature].__proto__, this.field);
38 | pd.set.apply(this.entity[this.feature], [ undefined ]);
39 | this.value = undefined;
40 | }
41 | else {
42 | this.entity[this.feature][this.field] = val;
43 | }
44 |
45 | this.$emit('input', val, this.field, this.feature, this.entity);
46 | }
47 | },
48 | watch: {
49 | entity: function(newValue) {
50 | if (newValue[this.feature][this.field]) {
51 | let v = newValue[this.feature][this.field].getValue();
52 | Object.keys(Cesium[this.enum]).forEach(k => {
53 | if( Cesium[this.enum][k] === v ) {
54 | this.value = k;
55 | }
56 | });
57 | }
58 | else {
59 | this.value = 'undefined';
60 | }
61 | }
62 | },
63 | template: template
64 | });
--------------------------------------------------------------------------------
/js/fields/extend-to-ground.js:
--------------------------------------------------------------------------------
1 | const template = `
2 |
3 |
Extension line
4 |
5 |
9 |
10 |
11 |
16 |
17 |
18 |
25 |
26 |
`
27 |
28 | Vue.component('extend-to-ground', {
29 | props: ['entity'],
30 | data: function() {
31 | return {
32 | extend: !!this.entity.cylinder
33 | }
34 | },
35 | template: template,
36 | methods: {
37 | handleChange() {
38 | if (this.extend) {
39 | this.createDropLine();
40 | }
41 | else {
42 | this.removeDropLine();
43 | }
44 | // This isn't a real feature and field of Cesium entity
45 | this.$emit('input', this.extend, 'extend-to-ground', 'billboard', this.entity);
46 | },
47 | createDropLine() {
48 | const position = this.entity.position.getValue();
49 | const cartographic = Cesium.Cartographic.fromCartesian(position);
50 |
51 | this.entity.cylinder = new Cesium.CylinderGraphics({
52 | fill: false,
53 | heightReference: this.entity.billboard.heightReference,
54 | numberOfVerticalLines: 1,
55 | outline: true,
56 | outlineColor: Cesium.Color.WHITE,
57 | slices: 3,
58 | length: cartographic.height,
59 | bottomRadius: 0.0001,
60 | topRadius: 0.0001
61 | });
62 | },
63 | removeDropLine() {
64 | this.entity.cylinder = null;
65 | }
66 | }
67 | });
--------------------------------------------------------------------------------
/js/lib/JsColor.js:
--------------------------------------------------------------------------------
1 | const template = `
2 |
5 |
6 | {{label}}
7 |
8 |
17 |
18 | `
19 | Vue.component('jscolor',{
20 | template,
21 | data(){
22 | return {
23 | color: '',
24 | picker: null
25 | }
26 | },
27 | props: {
28 | value: String,
29 | removeButton: {
30 | default: true
31 | },
32 | label: String,
33 | alphaChannel: {
34 | default: 'true' // 'true', 'false', 'auto'
35 | },
36 | /**
37 | 'auto' - automatically detect format from the initial color value and keep it in effect
38 | 'any' - user can enter a color code in any supported format (and it will stay in that format until different one is used)
39 | 'hex' - HEX color in standard CSS notation #RRGGBB
40 | 'rgb' - RGB color in standard CSS notation rgb(r,g,b)
41 | 'rgba' - RGBA color in standard CSS notation rgba(r,g,b,a
42 | */
43 | format: {
44 | default: 'any'
45 | },
46 | id: String
47 | },
48 | methods: {
49 | onChange(target){
50 | // this.color = target.jscolor.toHEXString();
51 | this.color = target.jscolor.channels;
52 | this.color.input = target;
53 | this.$refs.color_span.style.backgroundColor = this.color;
54 |
55 | let text = target.value;
56 |
57 | // Do not fire input and update while user enters values
58 | if (/\#[\dabcdef]{6}/ig.test(text) ||
59 | /rgb\s*\(\s*(\d{1,3})\,\s*(\d{1,3})\,\s*(\d{1,3})\s*\)/ig.test(text) ||
60 | /rgba\s*\(\s*(\d{1,3})\,\s*(\d{1,3})\,\s*(\d{1,3})\,\s*([\d\.]+)\s*\)/ig.test(text)) {
61 | this.$emit('input', this.color);
62 | }
63 |
64 | if (!text) {
65 | this.$emit('input', null);
66 | }
67 | },
68 | showColorPicker(){
69 | this.picker.show();
70 | }
71 | },
72 | mounted: function () {
73 | this.picker = new JSColor(this.$refs.color_input, {
74 | hash: true,
75 | format: 'any',
76 | value: this.value,
77 | valueElement: this.$refs.color_input,
78 | previewElement: this.$refs.color_span,
79 | onInput: () => {this.onChange(this.$refs.color_input);}
80 | });
81 | },
82 | updated: function () {
83 | this.$refs.color_span.style.backgroundColor = this.value;
84 | }
85 | });
86 |
--------------------------------------------------------------------------------
/js/util/czmzProviderMixin.js:
--------------------------------------------------------------------------------
1 | import * as zip from "https://deno.land/x/zipjs/index.js";
2 |
3 | export function czmlDataSourceMixin(CesiumCzmlDS) {
4 | CesiumCzmlDS.__load = CesiumCzmlDS.load;
5 |
6 | CesiumCzmlDS.load = function(czml, options) {
7 | if (isCzmz(czml)) {
8 | const url = new Cesium.Resource(czml).toString();
9 | const reader = new zip.ZipReader(new zip.BlobReader(file));
10 |
11 | reader.getEntries().then(async entries => {
12 | const entriesMap = new Map();
13 | for (let entry of entries) {
14 | const blob = await entry.getData(new zip.BlobWriter());
15 | const blobURL = URL.createObjectURL(blob);
16 |
17 | entriesMap.set(entry.filename, blobURL);
18 | entriesMap.set('/' + entry.filename, blobURL);
19 | }
20 |
21 | const documentEntry = entries.find(e => /\.czml$/i.test(e.filename));
22 | entriesMap.get(documentEntry.filename);
23 |
24 | const promise = CesiumCzmlDS.__load(new Cesium.Resource({
25 | url: URL.createObjectURL(blob),
26 | proxy: {
27 | getURL: url => {
28 | if (/^blob:/.test(url)) {
29 | const blobId = new URL(url.replace(/^blob:/, '')).pathname;
30 | const blobUrl = entriesMap.get(blobId);
31 | return blobUrl ? blobUrl : url;
32 | }
33 | console.warn('Url not found inside czmz', url);
34 | return url;
35 | }
36 | }
37 | }), options);
38 |
39 | promise.then(ds => {
40 | ds.destroy = function () {
41 | for (let blobUrl of entriesMap.values()) {
42 | URL.revokeObjectURL(blobUrl);
43 | }
44 | }
45 | });
46 |
47 | return promise;
48 |
49 | });
50 | }
51 | else {
52 | return CesiumCzmlDS.__load(czml, options);
53 | }
54 | }
55 | }
56 |
57 | // src { Resource | string | object }
58 | function isCzmz(src) {
59 |
60 | if (typeof src === 'string' || src instanceof String) {
61 | return /.czmz&/.test(new URL(src).pathname)
62 | }
63 |
64 | // If it's a resource
65 | if (src.url) {
66 | return /.czmz&/.test(new URL(src.url).pathname)
67 | }
68 |
69 | // if it's already loaded Czml object - it's czml
70 | return false;
71 | }
72 |
--------------------------------------------------------------------------------
/js/util/tileset-switch.js:
--------------------------------------------------------------------------------
1 | const svg = `M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4
2 | 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10
3 | 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z`;
4 |
5 | export default function TilesetSwitch(viewer) {
6 | var container = Cesium.getElement(document.querySelector('.cesium-viewer-toolbar'));
7 |
8 | var element = document.createElement("button");
9 | element.type = "button";
10 | element.className = "cesium-button cesium-toolbar-button cesium-home-button";
11 | element.setAttribute(
12 | "data-bind",
13 | "attr: { title: tooltip }, click: command, cesiumSvgPath: { path: _svgPath, width: 26, height: 26 }"
14 | );
15 |
16 | const viewModel = {
17 | _svgPath: svg,
18 | command: function() {
19 | viewer.scene.primitives.show = !viewer.scene.primitives.show;
20 | },
21 | tooltip: "Show/Hide 3d tilesets"
22 | };
23 |
24 | Cesium.knockout.applyBindings(viewModel, element);
25 |
26 | container.appendChild(element);
27 | }
--------------------------------------------------------------------------------