4

So I want to merge adjacent polygons in javascript this is what I actually have with my code:

map

I want to remove inside stroke but keep border stroke.

So I want to go from this:

map2

To this:

map3

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:

map4

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)
Robin Mackenzie
  • 18,801
  • 7
  • 38
  • 56
user10863293
  • 770
  • 4
  • 11
  • 32

1 Answers1

8

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: '&copy; <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>
Robin Mackenzie
  • 18,801
  • 7
  • 38
  • 56