• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 19060241474

04 Nov 2025 06:46AM UTC coverage: 76.943% (+0.02%) from 76.92%
19060241474

Pull #11648

github

web-flow
Merge 763e0cf1e into 19e678788
Pull Request #11648: #11644: Implement dynamic request configurations

32057 of 49801 branches covered (64.37%)

201 of 222 new or added lines in 39 files covered. (90.54%)

4 existing lines in 3 files now uncovered.

39801 of 51728 relevant lines covered (76.94%)

39.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.86
/web/client/components/map/cesium/plugins/OverlayLayer.js
1
/**
2
 * Copyright 2015, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
 */
8

9
import Layers from '../../../../utils/cesium/Layers';
10
import * as Cesium from 'cesium';
11

12
import eventListener from 'eventlistener';
13
import isEqual from 'lodash/isEqual';
14
/**
15
 * Created by thomas on 27/01/14.
16
 */
17

18
const InfoWindow = (function() {
1✔
19
    function _(cesiumWidget) {
20
        this._destroyed = false;
3✔
21
        this._scene = cesiumWidget.scene;
3✔
22

23
        let div = document.createElement('div');
3✔
24
        div.className = 'infoWindow';
3✔
25
        this._div = div;
3✔
26
        let frame = document.createElement('div');
3✔
27
        frame.className = 'frame';
3✔
28
        this._div.appendChild(frame);
3✔
29
        let content = document.createElement('div');
3✔
30
        content.className = 'content';
3✔
31
        frame.appendChild(content);
3✔
32
        cesiumWidget.container.appendChild(div);
3✔
33
        this._content = content;
3✔
34
        this.setVisible(true);
3✔
35

36
        // set the position to absolute to correctly positioning the info window
37
        // based on left and top properties
38
        this._div.style.position = 'absolute';
3✔
39
    }
40

41
    // This is now required to make the InfoWindow compatible with Cesium Primitive interface
42
    // https://github.com/CesiumGS/cesium/blob/1.131/packages/engine/Source/Scene/Primitive.js#L2436
43
    _.prototype.isDestroyed = function() {
1✔
44
        return this._destroyed;
3✔
45
    };
46
    _.prototype.setVisible = function(visible) {
1✔
47
        this._visible = visible;
12✔
48
        this._div.style.display = visible ? 'block' : 'none';
12!
49
    };
50

51
    _.prototype.setContent = function(content) {
1✔
52
        if (typeof content === 'string') {
3!
53
            this._content.innerHTML = content;
×
54
        } else {
55
            while (this._content.firstChild) {
3✔
56
                this._content.removeChild(this._content.firstChild);
×
57
            }
58
            this._content.appendChild(content);
3✔
59
        }
60
    };
61

62
    _.prototype.setPosition = function(lat, lng) {
1✔
63
        this._position = this._scene.globe.ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(lng, lat, 0));
3✔
64
    };
65

66
    _.prototype.showAt = function(lat, lng, content) {
1✔
67
        this.setPosition(lat, lng);
3✔
68
        this.setContent(content);
3✔
69
        this.setVisible(true);
3✔
70
    };
71

72
    _.prototype.hide = function() {
1✔
73
        this.setVisible(false);
×
74
    };
75

76
    _.prototype.computeVisible = function() {
1✔
77
        // Ellipsoid radii - WGS84 shown here
78
        const rX = 6378137.0;
3✔
79
        const rY = 6378137.0;
3✔
80
        const rZ = 6356752.3142451793;
3✔
81
        // Vector CV
82
        const cameraPosition = this._scene.camera.position;
3✔
83
        const cvX = cameraPosition.x / rX;
3✔
84
        const cvY = cameraPosition.y / rY;
3✔
85
        const cvZ = cameraPosition.z / rZ;
3✔
86

87
        const vhMagnitudeSquared = cvX * cvX + cvY * cvY + cvZ * cvZ - 1.0;
3✔
88

89
        // Target position, transformed to scaled space
90

91
        const position = this._position;
3✔
92
        const tX = position.x / rX;
3✔
93
        const tY = position.y / rY;
3✔
94
        const tZ = position.z / rZ;
3✔
95

96
        // Vector VT
97
        const vtX = tX - cvX;
3✔
98
        const vtY = tY - cvY;
3✔
99
        const vtZ = tZ - cvZ;
3✔
100
        const vtMagnitudeSquared = vtX * vtX + vtY * vtY + vtZ * vtZ;
3✔
101

102
        // VT dot VC is the inverse of VT dot CV
103
        const vtDotVc = -(vtX * cvX + vtY * cvY + vtZ * cvZ);
3✔
104

105
        const isOccluded = vtDotVc > vhMagnitudeSquared &&
3!
106
            vtDotVc * vtDotVc / vtMagnitudeSquared > vhMagnitudeSquared;
107

108
        if (isOccluded) {
3!
109
            this.setVisible(false);
×
110
        } else {
111
            this.setVisible(true);
3✔
112
        }
113

114
    };
115

116
    _.prototype.update = function() {
1✔
117
        this.computeVisible();
3✔
118

119
        if (!this._visible || !this._position) {
3!
120
            return;
×
121
        }
122
        // get the position on the globe as screen coordinates
123
        // coordinates with origin at the top left corner
124
        let coordinates = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this._scene, this._position);
3✔
125
        if (coordinates) {
×
126
            let left = Math.floor(coordinates.x) - this._div.clientWidth / 2 + "px";
×
127
            let top = Math.floor(coordinates.y) - this._div.clientHeight + "px";
×
128
            this._div.tabIndex = 5;
×
129
            this._div.style.left = left;
×
130
            this._div.style.top = top;
×
131
        }
132
    };
133

134
    _.prototype.destroy = function() {
1✔
135
        this._div.parentNode.removeChild(this._div);
×
136
        this._destroyed = true;
×
137
    };
138

139
    return _;
1✔
140

141
})();
142

143
const removeIds = (items) => {
1✔
144
    if (items.length !== 0) {
5✔
145
        for (let i = 0; i < items.length; i++) {
2✔
146
            let item = items.item(i);
2✔
147
            item.removeAttribute('data-reactid');
2✔
148
            removeIds(item.children || []);
2!
149
        }
150
    }
151
};
152

153
const cloneOriginalOverlay = (original, options) => {
1✔
154
    let cloned = original.cloneNode(true);
3✔
155
    cloned.id = options.id + '-overlay';
3✔
156
    cloned.className = (options.className || original.className) + "-overlay";
3✔
157
    cloned.removeAttribute('data-reactid');
3✔
158
    // remove reactjs generated ids from cloned object
159
    removeIds(cloned.children || []);
3!
160
    // handle optional close button on overlay
161
    const closeClassName = options.closeClass || 'close';
3✔
162
    if (options.onClose && cloned.getElementsByClassName(closeClassName).length === 1) {
3✔
163
        const close = cloned.getElementsByClassName(closeClassName)[0];
1✔
164
        const onClose = (e) => {
1✔
165
            options.onClose(e.target.getAttribute('data-overlayid'));
1✔
166
        };
167
        eventListener.add(close, 'click', onClose);
1✔
168
    }
169
    return cloned;
3✔
170
};
171

172
Layers.registerType('overlay', {
1✔
173
    create: (options, map) => {
174

175
        if (!options.visibility) {
3!
176
            return {
×
177
                detached: true,
178
                info: undefined,
179
                remove: () => {}
180
            };
181
        }
182
        const original = document.getElementById(options.id);
3✔
183
        // use a div fallback to avoid error if the original element does not exist
184
        const cloned = original ? cloneOriginalOverlay(original, options) : document.createElement('div');
3!
185

186
        let infoWindow = new InfoWindow(map);
3✔
187
        infoWindow.showAt(options?.position?.y || 0, options?.position?.x || 0, cloned);
3!
188
        infoWindow.setVisible(true);
3✔
189

190
        let info = map.scene.primitives.add(infoWindow);
3✔
191

192
        return {
3✔
193
            detached: true,
194
            info: info,
195
            remove: () => {
196
                map.scene.primitives.remove(info);
×
197
            }
198
        };
199
    },
200
    update: function(layer, newOptions, oldOptions, map) {
NEW
201
        if (!isEqual(newOptions.position, oldOptions.position) || !isEqual(oldOptions.security, newOptions.security)) {
×
202
            return this.create(newOptions, map);
×
203
        }
204
        return null;
×
205
    }
206
});
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc