Reputation: 697
In mapbox-gl-js version: 2.10.0 I click on a point on a map and get all the features from 2 vector layers (application/vnd.mapbox-vector-tile) and one geojson layer data: 'http://localhost:8080/geoserver/mydata/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=mydata%3Acontexts&outputFormat=application%2Fjson' , , all served from GeoServer
In Geoserver's store I have Expose primary keys enabled, so in the features properties I have their IDs , coming from the database
I try to remove the duplicates that may created by mapbox based on their properties.id (sometimes mapbox creates duplicates of the same feature in vector and geojson, depending on zoom level)
Then I want to check if I have multiple features in the first vector layer. If I do, I create some objects, including data from other layers. To see what belongs to what feature from the first layer, I do it based on their properties.id , but sometimes its the same for both features, while feature id is different. I thought that properties.id always stays the same and its not duplicated on multiple features.
here is my code
map.current.on('click', (e) => {
//get point
const point = e.point;
//get all features from all layers from that point
let features = map.current.queryRenderedFeatures(point);
//separate features by layer
let excavations = features.filter(f => f.layer.id === 'excavations-layer');
let parts = features.filter(f => f.layer.id === 'excavation_parts-layer');
let contexts = features.filter(f => f.layer.id === 'contexts-layer');
//removing duplicates
excavations = excavations.filter((value, index, self) =>
index === self.findIndex((et) => (
et.properties.id === value.properties.id
))
)
parts = parts.filter((value, index, self) =>
index === self.findIndex((pt) => (
pt.properties.id === value.properties.id
))
)
contexts = contexts.filter((value, index, self) =>
index === self.findIndex((ct) => (
ct.properties.id === value.properties.id
))
)
//organize data per excavation, based on ids
excavations.forEach(e => {
ex_excavations = excavations.filter((value) =>
e.properties.id == value.properties.id
)
ex_parts = parts.filter((value) =>
e.properties.id = value.properties.excavation_id
)
ex_contexts = contexts.filter((value) =>
turf.booleanIntersects(value,e)
)
exgroupArray.push(
{
name:e.properties.name,
excavations:ex_excavations,
parts:ex_parts,
contexts:ex_contexts
}
)
console.log('e id loop ', e.id);
console.log('exgroupArray ', exgroupArray);
console.log('====================');
});
The original excavations array where I do the first forEach excavations.forEach(e => { has different feature ids (12,13) , but the same properties.id (12,12)
Other times has the same feature ids (12,12) , but different properties.id (12,13)
Check image
I though that properties.id comes from the Geoserver and should always be the different for each feature.
I try to base my code on that, but because it changes, it messes up my final exgroupArray and cannot loop it correctly in the HTML.
Any help how to fix this?
Thanks
Edit : It seems like if I am fully zoomed out, I get same feature id, different properties.id, check second image
Upvotes: 3
Views: 892
Reputation: 336
I encountered a similar problem. I believe what happens is until explicitly instructed mapbox generates unique IDs for each feature in a specific tile.
Hence features that are in different tiles will get the same numeric id.
But there's a way to fix it. You can go through the documentation over here. The promoteId config explcitly tells the mapbox to not generate new IDs but rather use a specific field from properties section.
Here's a sample code:
map.addSource('earthquakes', {
"type": "vector",
tiles: ["http://localhost:8081/api/asset/tile/{z}/{x}/{y}.pbf"],
"promoteId": {"LAYER_NAME": "id"}
});
In this sample code I'm overwriting the ID for only one cluster layer LAYER_NAME and the field I'm using from properties is named id
Upvotes: 0