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.
Advertisement
Answer
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>