I have a list of geojson features that each have an asset ID in their properties. I want to manipulate the geojson so I am left with only a single feature per asset ID, with the properties from each feature found added to the feature properties.
As an example, the following geojson has 4 features; 2 of them have an asset ID of 100 and 2 of them have an asset ID of 200:-
{
"type":"FeatureCollection",
"title":"map_features",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525408,
162788
]
},
"properties":{
"CASENO":"CASE29302",
"CASE_TYPE":"litterBin",
"ASSETID":"100",
"DESCRIPTION":"Bin is full"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525408,
162788
]
},
"properties":{
"CASENO":"CASE56843",
"CASE_TYPE":"litterBin",
"ASSETID":"100",
"NOTES":"Bin needs emptying"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525177,
164509
]
},
"properties":{
"CASENO":"CASE77112",
"CASE_TYPE":"litterBin",
"ASSETID":"200",
"NOTES":"Bin cleaned"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525177,
164509
]
},
"properties":{
"CASENO":"CASE04393",
"CASE_TYPE":"litterBin",
"ASSETID":"200",
"NOTES":"Bin full"
}
}
]
}
I am looking to be left with just two features for asset ID 100 and 200, and have the properties grouped together from the duplicate features:-
{
"type":"FeatureCollection",
"title":"map_features",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525408,
162788
]
},
"properties":[
{
"CASENO":"CASE29302",
"CASE_TYPE":"litterBin",
"ASSETID":"100",
"DESCRIPTION":"Bin is full"
},
{
"CASENO":"CASE56843",
"CASE_TYPE":"litterBin",
"ASSETID":"100",
"NOTES":"Bin needs emptying"
}
]
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525408,
162788
]
},
"properties":[
{
"CASENO":"CASE56843",
"CASE_TYPE":"litterBin",
"ASSETID":"100",
"NOTES":"Bin needs emptying"
},
{
"CASENO":"CASE04393",
"CASE_TYPE":"litterBin",
"ASSETID":"200",
"NOTES":"Bin full"
}
]
}
]
}
I am not sure if there is a javascript / jquery method that might help with this? Would I need to use a for loop?
Any pointers would be appreciated.
CodePudding user response:
If you're confident that the duplicate features have the same geometry you can use this approach:
- Group the features by
ASSETID
you can use aMap
withreduce
to do this where each key is a uniqueASSETID
and the value is an array that fills up with features. - For each item in the
Map
, use the first feature in the array for thegeometry
and then forproperties
replace the array of features with an array of just theproperties
. - Create a new
featureCollection
with the new features resolved in step 2.
See the comments in the working code below:
// group features by ASSETID
const assets = Array.from(
fc.features.reduce((a, c) => {
const id = c.properties.ASSETID;
if (!a.has(id)) a.set(id, []); // <-- initialise each entry with an empty array
a.get(id).push(c); // <-- add the feature to the array for that ASSETID
return a;
}, new Map()) // <-- the accumulator is a Map
);
// create new features
const newFeatures = assets.reduce((a, c) => {
a.push({
"type": "Feature",
"geometry": c[1][0].geometry, // <-- take geometry from first array entry
"properties": c[1].map(f => f.properties) // <-- just retain the properties of the feature
});
return a;
}, []);
// create new feature collection
const newFc = {
"type":"FeatureCollection",
"title":"map_features",
"features": newFeatures
}
// output
console.log(newFc);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script>
const fc = {
"type":"FeatureCollection",
"title":"map_features",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525408,
162788
]
},
"properties":{
"CASENO":"CASE29302",
"CASE_TYPE":"litterBin",
"ASSETID":"100",
"DESCRIPTION":"Bin is full"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525408,
162788
]
},
"properties":{
"CASENO":"CASE56843",
"CASE_TYPE":"litterBin",
"ASSETID":"100",
"NOTES":"Bin needs emptying"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525177,
164509
]
},
"properties":{
"CASENO":"CASE77112",
"CASE_TYPE":"litterBin",
"ASSETID":"200",
"NOTES":"Bin cleaned"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
525177,
164509
]
},
"properties":{
"CASENO":"CASE04393",
"CASE_TYPE":"litterBin",
"ASSETID":"200",
"NOTES":"Bin full"
}
}
]
}
</script>