Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix order of 3D features in query results (fix #7883) #7953

Merged
merged 1 commit into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions src/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -942,32 +942,68 @@ class Style extends Evented {
}

_flattenAndSortRenderedFeatures(sourceResults: Array<any>) {
const features = [];
// Feature order is complicated.
// The order between features in two 2D layers is always determined by layer order.
// The order between features in two 3D layers is always determined by depth.
// The order between a feature in a 2D layer and a 3D layer is tricky:
// Most often layer order determines the feature order in this case. If
// a line layer is above a extrusion layer the line feature will be rendered
// above the extrusion. If the line layer is below the extrusion layer,
// it will be rendered below it.
//
// There is a weird case though.
// You have layers in this order: extrusion_layer_a, line_layer, extrusion_layer_b
// Each layer has a feature that overlaps the other features.
// The feature in extrusion_layer_a is closer than the feature in extrusion_layer_b so it is rendered above.
// The feature in line_layer is rendered above extrusion_layer_a.
// This means that that the line_layer feature is above the extrusion_layer_b feature despite
// it being in an earlier layer.

const isLayer3D = layerId => this._layers[layerId].type === 'fill-extrusion';

const layerIndex = {};
const features3D = [];
for (let l = this._order.length - 1; l >= 0; l--) {
const layerId = this._order[l];
for (const sourceResult of sourceResults) {
const layerFeatures = sourceResult[layerId];
if (layerFeatures) {
if (this._layers[layerId].type === 'fill-extrusion') {
if (isLayer3D(layerId)) {
layerIndex[layerId] = l;
for (const sourceResult of sourceResults) {
const layerFeatures = sourceResult[layerId];
if (layerFeatures) {
for (const featureWrapper of layerFeatures) {
features3D.push(featureWrapper);
}
} else {
for (const featureWrapper of layerFeatures) {
features.push(featureWrapper.feature);
}
}
}
}
}

features3D.sort((a, b) => {
return a.intersectionZ - b.intersectionZ;
return b.intersectionZ - a.intersectionZ;
});

for (const featureWrapper of features3D) {
features.push(featureWrapper.feature);
const features = [];
for (let l = this._order.length - 1; l >= 0; l--) {
const layerId = this._order[l];

if (isLayer3D(layerId)) {
// add all 3D features that are in or above the current layer
for (let i = features3D.length - 1; i >= 0; i--) {
const topmost3D = features3D[i].feature;
if (layerIndex[topmost3D.layer.id] < l) break;
features.push(topmost3D);
features3D.pop();
}
} else {
for (const sourceResult of sourceResults) {
const layerFeatures = sourceResult[layerId];
if (layerFeatures) {
for (const featureWrapper of layerFeatures) {
features.push(featureWrapper.feature);
}
}
}
}
}

return features;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
[
{
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-30.0146484375,
0
],
[
-30.0146484375,
50.00773901463688
],
[
30.0146484375,
50.00773901463688
],
[
30.0146484375,
0
],
[
-30.0146484375,
0
]
]
]
},
"type": "Feature",
"properties": {
"layer": "upper"
},
"source": "fill-upper",
"state": {}
},
{
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-10.01953125,
-20.01464544534136
],
[
-10.01953125,
40.01078714046551
],
[
39.990234375,
40.01078714046551
],
[
39.990234375,
-20.01464544534136
],
[
-10.01953125,
-20.01464544534136
]
]
]
},
"type": "Feature",
"properties": {
"layer": "extrusion_closer"
},
"source": "extrusion_closer",
"state": {}
},
{
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-39.990234375,
-40.01078714046552
],
[
-39.990234375,
40.01078714046551
],
[
10.01953125,
40.01078714046551
],
[
10.01953125,
-40.01078714046552
],
[
-39.990234375,
-40.01078714046552
]
]
]
},
"type": "Feature",
"properties": {
"layer": "extrusion_further"
},
"source": "extrusion",
"state": {}
},
{
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-50.009765625,
-50.00773901463686
],
[
-50.009765625,
50.00773901463688
],
[
50.009765625,
50.00773901463688
],
[
50.009765625,
-50.00773901463686
],
[
-50.009765625,
-50.00773901463686
]
]
]
},
"type": "Feature",
"properties": {
"layer": "fill-lower"
},
"source": "fill-lower",
"state": {}
}
]
Loading