So I want to merge adjacent polygons in javascript this is what I actually have with my code:
I want to remove inside stroke but keep border stroke.
So I want to go from this:
To this:
I want to keep the hole for Paris - I can defined which polygons have to be grouped but I cannot merge them with this code:
var map = L.map('map', {
center: [46.52863469527167, 2.43896484375],
zoom: 6,
maxZoom: 18,
minZoom: 7
});
$http.get("france.json").then(function (response) {
$scope.communeFr = response.data.features
$http.get(apiult).then(function (response) {
$scope.showCommune = response.data.Liste
$scope.communeFr.map(x => {
x.show = false
for (let i = 0; i < $scope.showCommune .length; i++) {
if (x.properties.insee == $scope.showCommune[i].insee) {
x.show = true
return
}
}
})
L.geoJson($scope.communeFr, {
filter: function (feature, latlng) {
return feature.show
}
}).addTo(map);
});
});
UPDATE - I tried with turf.union
but the output is not right:
This is my code
var GroupPolygons = [];
$scope.communeFr.map(x => {
x.show = false
for (let i = 0; i < $scope.showCommune .length; i++) {
if (x.properties.insee == $scope.showCommune[i].insee) {
GroupPolygons.push(x)
}
}
})
var union = turf.union(...GroupPolygons)
L.geoJson(union).addTo(map)
There seems to be an ambiguity in the turf docs concerning union
regarding the number of polygons that can be passed as arguments. See here and here. Looks like it has to be two at a time - so this will work:
// feature ids to remove e.g. central Paris
var removeIds = [868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887];
// filter features to remove central Paris
var hole = fc.features.filter(f => !removeIds.includes(f.properties.ID_APUR))
// do the union over each feature
var union = hole[0];
for (let i=1; i<hole.length; i++) {
union = turf.union(union, hole[i]);
}
I selected a bunch of central Paris to remove and then from the remaining features I start with feature 0 and then turf.join
all the other features (from index 1 onward) to this one. Seems inefficient but works...
Small gotcha here:
// new Feature collection with unioned features
var fc2 = {
"type": "FeatureCollection",
"features": [union] // note features has to be an array
}
Remember to pass a FeatureCollection to L.geoJson
and that the features
property needs to be an array - even though in this case it contains a single feature of the merged areas.
Working example:
// center map on Paris
var map = L.map('mapid', {
center: [48.856, 2.352],
zoom: 9,
maxZoom: 18,
minZoom: 1
});
// add tiles
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
var url = "https://gist.githubusercontent.com/robinmackenzie/937e5bd42a0412c21281f69b8f0c8614/raw/fbed7c2783366463a250e4bb0ebcf3c5f6d54dfe/greaterParis.geo.json";
// get greater Paris definition
fetch(url)
.then(response => response.json())
.then(fc => {
// feature ids to remove e.g. central Paris
var removeIds = [868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887];
// filter features to remove central Paris
var hole = fc.features.filter(f => !removeIds.includes(f.properties.ID_APUR))
// do the union over each feature
var union = hole[0];
for (let i=1; i<hole.length; i++) {
union = turf.union(union, hole[i]);
}
// new Feature collection with unioned features
var fc2 = {
"type": "FeatureCollection",
"features": [union] // note features has to be an array
}
// add to map
L.geoJson(fc2).addTo(map);
});
#mapid { height: 200px; }
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<script src='https://unpkg.com/@turf/turf@6.3.0/turf.min.js'></script>
<div id="mapid"></div>