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

iTowns / itowns / 9318814291

31 May 2024 01:17PM UTC coverage: 89.593% (+0.2%) from 89.36%
9318814291

push

github

Desplandis
fix(deps): update babel and add @babel/core dependency

2706 of 3580 branches covered (75.59%)

Branch coverage included in aggregate %.

23294 of 25440 relevant lines covered (91.56%)

342.31 hits per line

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

77.05
/src/Process/LayeredMaterialNodeProcessing.js
1
import { chooseNextLevelToFetch } from 'Layer/LayerUpdateStrategy';
1✔
2
import LayerUpdateState from 'Layer/LayerUpdateState';
1✔
3
import handlingError from 'Process/handlerNodeError';
1✔
4

1✔
5
export const SIZE_TEXTURE_TILE = 256;
1✔
6
export const SIZE_DIAGONAL_TEXTURE = (2 * (SIZE_TEXTURE_TILE * SIZE_TEXTURE_TILE)) ** 0.5;
1✔
7

1✔
8
function materialCommandQueuePriorityFunction(material) {
1✔
9
    // We know that 'node' is visible because commands can only be
9✔
10
    // issued for visible nodes.
9✔
11
    // TODO: need priorization of displayed nodes
9✔
12
    // Then prefer displayed node over non-displayed one
9✔
13
    return material.visible ? 100 : 10;
1!
14
}
1✔
15

1✔
16
function refinementCommandCancellationFn(cmd) {
1✔
17
    if (!cmd.requester.parent || !cmd.requester.material) {
1!
18
        return true;
1✔
19
    }
1✔
20
    // Cancel the command if the tile already has a better texture.
1✔
21
    // This is only needed for elevation layers, because we may have several
1✔
22
    // concurrent layers but we can only use one texture.
1✔
23
    if (cmd.layer.isElevationLayer && cmd.requester.material.getElevationLayer() &&
1!
24
        cmd.targetLevel <= cmd.requester.material.getElevationLayer().level) {
1!
25
        return true;
1✔
26
    }
1✔
27

1✔
28
    // Cancel the command if the layer was removed between command scheduling and command execution
1✔
29
    if (!cmd.requester.layerUpdateState[cmd.layer.id]
1✔
30
        || !cmd.layer.source._featuresCaches[cmd.layer.crs]) {
1!
31
        return true;
1✔
32
    }
9✔
33

9✔
34
    return !cmd.requester.material.visible;
9✔
35
}
9✔
36

9✔
37
function buildCommand(view, layer, extentsSource, extentsDestination, requester) {
9✔
38
    return {
9✔
39
        view,
9✔
40
        layer,
9✔
41
        extentsSource,
9✔
42
        extentsDestination,
9✔
43
        requester,
9✔
44
        priority: materialCommandQueuePriorityFunction(requester.material),
1✔
45
        earlyDropFunction: refinementCommandCancellationFn,
15✔
46
    };
15✔
47
}
15✔
48

15✔
49
export function updateLayeredMaterialNodeImagery(context, layer, node, parent) {
15!
50
    const material = node.material;
15✔
51
    if (!parent || !material) {
15✔
52
        return;
15✔
53
    }
15✔
54
    const extentsDestination = node.getExtentsByProjection(layer.crs);
15!
55

×
56
    const zoom = extentsDestination[0].zoom;
15✔
57
    if (zoom > layer.zoom.max || zoom < layer.zoom.min) {
15✔
58
        return;
15✔
59
    }
15✔
60

15✔
61
    let nodeLayer = material.getLayer(layer.id);
15✔
62

9✔
63
    // Initialisation
9✔
64
    if (node.layerUpdateState[layer.id] === undefined) {
9✔
65
        node.layerUpdateState[layer.id] = new LayerUpdateState();
9!
66

×
67
        if (!layer.source.extentInsideLimit(node.extent, zoom)) {
×
68
            // we also need to check that tile's parent doesn't have a texture for this layer,
×
69
            // because even if this tile is outside of the layer, it could inherit it's
×
70
            // parent texture
×
71
            if (!layer.noTextureParentOutsideLimit &&
×
72
                parent.material &&
×
73
                parent.material.getLayer &&
×
74
                parent.material.getLayer(layer.id)) {
9✔
75
                // ok, we're going to inherit our parent's texture
2✔
76
            } else {
2✔
77
                node.layerUpdateState[layer.id].noMoreUpdatePossible();
2!
78
                return;
2✔
79
            }
2✔
80
        }
2✔
81

2✔
82
        if (!nodeLayer) {
9✔
83
            // Create new raster node
9✔
84
            nodeLayer = layer.setupRasterNode(node);
9✔
85

9✔
86
            // Init the node by parent
9✔
87
            const parentLayer = parent.material?.getLayer(layer.id);
9✔
88
            nodeLayer.initFromParent(parentLayer, extentsDestination);
9✔
89
        }
9✔
90

9✔
91
        // Proposed new process, two separate processes:
9✔
92
        //      * FIRST PASS: initNodeXXXFromParent and get out of the function
9✔
93
        //      * SECOND PASS: Fetch best texture
15✔
94

11✔
95
        // The two-step allows you to filter out unnecessary requests
15!
96
        // Indeed in the second pass, their state (not visible or not displayed) can block them to fetch
11✔
97
        if (nodeLayer.level >= layer.source.zoom.min) {
15✔
98
            context.view.notifyChange(node, false);
15!
99
            return;
×
100
        }
×
101
    }
×
102

×
103
    // Node is hidden, no need to update it
×
104
    if (!material.visible) {
15✔
105
        return;
7✔
106
    }
7✔
107

7✔
108
    // An update is pending / or impossible -> abort
15!
109
    if (!layer.visible || !node.layerUpdateState[layer.id].canTryUpdate()) {
7✔
110
        return;
7✔
111
    }
7✔
112

7✔
113
    if (nodeLayer.level >= extentsDestination[0].zoom) {
15!
114
        // default decision method
15✔
115
        node.layerUpdateState[layer.id].noMoreUpdatePossible();
15✔
116
        return;
15✔
117
    }
15✔
118

15✔
119
    // is fetching data from this layer disabled?
15✔
120
    if (layer.frozen) {
15✔
121
        return;
15!
122
    }
×
123

×
124
    const failureParams = node.layerUpdateState[layer.id].failureParams;
×
125
    const destinationLevel = extentsDestination[0].zoom || node.level;
×
126
    const targetLevel = chooseNextLevelToFetch(layer.updateStrategy.type, node, destinationLevel, nodeLayer.level, layer, failureParams);
15!
127

×
128
    if ((!layer.source.isVectorSource && targetLevel <= nodeLayer.level) || targetLevel > destinationLevel) {
7✔
129
        if (failureParams.lowestLevelError != Infinity) {
7✔
130
            // this is the highest level found in case of error.
7✔
131
            node.layerUpdateState[layer.id].noMoreUpdatePossible();
7✔
132
        }
7✔
133
        return;
7✔
134
    } else if (!layer.source.extentInsideLimit(node.extent, targetLevel)) {
7✔
135
        node.layerUpdateState[layer.id].noData({ targetLevel });
×
136
        context.view.notifyChange(node, false);
×
137
        return;
×
138
    }
×
139

×
140
    const extentsSource = extentsDestination.map(e => e.tiledExtentParent(targetLevel));
×
141
    node.layerUpdateState[layer.id].newTry();
×
142
    const command = buildCommand(context.view, layer, extentsSource, extentsDestination, node);
×
143

×
144
    return context.scheduler.execute(command).then(
×
145
        (result) => {
7✔
146
            // Does nothing if the layer has been removed while command was being or waiting to be executed
1✔
147
            if (!node.layerUpdateState[layer.id]) {
3✔
148
                return;
3✔
149
            }
3✔
150
            // TODO: Handle error : result is undefined in provider. throw error
3!
151
            const pitchs = extentsDestination.map((ext, i) => ext.offsetToParent(result[i].extent, nodeLayer.offsetScales[i]));
3✔
152
            nodeLayer.setTextures(result, pitchs);
3✔
153
            node.layerUpdateState[layer.id].success();
3✔
154
        },
3✔
155
        err => handlingError(err, node, layer, targetLevel, context.view));
3✔
156
}
3✔
157

3✔
158
export function updateLayeredMaterialNodeElevation(context, layer, node, parent) {
3✔
159
    const material = node.material;
3!
160
    if (!parent || !material) {
3✔
161
        return;
3✔
162
    }
3✔
163

3✔
164
    // TODO: we need either
3✔
165
    //  - compound or exclusive layers
3✔
166
    //  - support for multiple elevation layers
3!
167

×
168
    // Elevation is currently handled differently from color layers.
3✔
169
    // This is caused by a LayeredMaterial limitation: only 1 elevation texture
3✔
170
    // can be used (where a tile can have N textures x M layers)
1!
171
    const extentsDestination = node.getExtentsByProjection(layer.crs);
1✔
172
    const zoom = extentsDestination[0].zoom;
1!
173
    if (zoom > layer.zoom.max || zoom < layer.zoom.min) {
3✔
174
        return;
3✔
175
    }
3✔
176
    // Init elevation layer, and inherit from parent if possible
3✔
177
    let nodeLayer = material.getElevationLayer();
3✔
178
    if (!nodeLayer) {
3✔
179
        nodeLayer = layer.setupRasterNode(node);
3✔
180
    }
2✔
181

2✔
182
    if (node.layerUpdateState[layer.id] === undefined) {
2✔
183
        node.layerUpdateState[layer.id] = new LayerUpdateState();
2✔
184

2✔
185
        const parentLayer = parent.material?.getLayer(layer.id);
2✔
186
        nodeLayer.initFromParent(parentLayer, extentsDestination);
3✔
187

3✔
188
        if (nodeLayer.level >= layer.source.zoom.min) {
×
189
            context.view.notifyChange(node, false);
3✔
190
            return;
2✔
191
        }
2✔
192
    }
2✔
193

2✔
194
    // Possible conditions to *not* update the elevation texture
×
195
    if (layer.frozen ||
×
196
            !material.visible ||
×
197
            !node.layerUpdateState[layer.id].canTryUpdate()) {
2✔
198
        return;
2✔
199
    }
2✔
200

2✔
201
    const failureParams = node.layerUpdateState[layer.id].failureParams;
2✔
202
    const targetLevel = chooseNextLevelToFetch(layer.updateStrategy.type, node, extentsDestination[0].zoom, nodeLayer.level, layer, failureParams);
2✔
203

1✔
204
    if (targetLevel <= nodeLayer.level || targetLevel > extentsDestination[0].zoom) {
1✔
205
        node.layerUpdateState[layer.id].noMoreUpdatePossible();
1!
206
        return;
1✔
207
    } else if (!layer.source.extentInsideLimit(node.extent, targetLevel)) {
1✔
208
        node.layerUpdateState[layer.id].noData({ targetLevel });
1✔
209
        context.view.notifyChange(node, false);
1✔
210
        return;
1✔
211
    }
1✔
212

1✔
213
    const extentsSource = extentsDestination.map(e => e.tiledExtentParent(targetLevel));
1!
214
    node.layerUpdateState[layer.id].newTry();
1✔
215
    const command = buildCommand(context.view, layer, extentsSource, extentsDestination, node);
1✔
216

1✔
217
    return context.scheduler.execute(command).then(
1✔
218
        (result) => {
1✔
219
            // Does nothing if the layer has been removed while command was being or waiting to be executed
1✔
220
            if (!node.layerUpdateState[layer.id]) {
×
221
                return;
×
222
            }
×
223

×
224
            // Do not apply the new texture if its level is < than the current
×
225
            // one.  This is only needed for elevation layers, because we may
×
226
            // have several concurrent layers but we can only use one texture.
×
227
            if (targetLevel <= nodeLayer.level) {
×
228
                node.layerUpdateState[layer.id].noMoreUpdatePossible();
×
229
                return;
×
230
            }
×
231
            const pitchs = extentsDestination.map((ext, i) => ext.offsetToParent(result[i].extent, nodeLayer.offsetScales[i]));
1✔
232
            nodeLayer.setTextures(result, pitchs);
1✔
233
            node.layerUpdateState[layer.id].success();
1✔
234
        },
1✔
235
        err => handlingError(err, node, layer, targetLevel, context.view));
1✔
236
}
1✔
237

1✔
238
export function removeLayeredMaterialNodeLayer(layerId) {
1✔
239
    /**
1✔
240
     * @param {TileMesh} node - The node to udpate.
1✔
241
     */
1✔
242
    return function removeLayeredMaterialNodeLayer(node) {
1✔
243
        if (node.material?.removeLayer) {
1✔
244
            if (node.material.elevationLayerIds.indexOf(layerId) > -1) {
1✔
245
                node.setBBoxZ({ min: 0, max: 0 });
1✔
246
            }
1✔
247
            node.material.removeLayer(layerId);
1✔
248
        }
1✔
249
        if (node.layerUpdateState && node.layerUpdateState[layerId]) {
1✔
250
            delete node.layerUpdateState[layerId];
1✔
251
        }
1✔
252
    };
1✔
253
}
1✔
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

© 2025 Coveralls, Inc