I have a GeoJson file which has multiple polygons. Something like this.
I use Leaflet to render this GeoJson in a website.
I want to draw an outline around the polygoins that envelopes all the polygons. Something like this.
Format of GeoJSOn i am using :
{
"features": [
{
"geometry": {
"coordinates": [
[
[
1074.426,
-1136.986
],
[
1088.241,
-1123.171
]
]
],
"type": "Polygon"
},
"properties": {
"number": "2009",
"type": "",
"spaceid": null,
"alias": null,
"roomkey": "5/2009"
},
"type": "Feature"
}
],
"bbox": [
2445.578,
2445.578
],
"crs": {
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
},
"type": "name"
},
"type": "FeatureCollection"
}
Any pointers will be helpful :) Thanks
I have a GeoJson file which has multiple polygons. Something like this.
I use Leaflet to render this GeoJson in a website.
I want to draw an outline around the polygoins that envelopes all the polygons. Something like this.
Format of GeoJSOn i am using :
{
"features": [
{
"geometry": {
"coordinates": [
[
[
1074.426,
-1136.986
],
[
1088.241,
-1123.171
]
]
],
"type": "Polygon"
},
"properties": {
"number": "2009",
"type": "",
"spaceid": null,
"alias": null,
"roomkey": "5/2009"
},
"type": "Feature"
}
],
"bbox": [
2445.578,
2445.578
],
"crs": {
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
},
"type": "name"
},
"type": "FeatureCollection"
}
Any pointers will be helpful :) Thanks
Share Improve this question asked Sep 5, 2017 at 9:37 Shaswat RungtaShaswat Rungta 3,8152 gold badges21 silver badges26 bronze badges 1- Do the polygons you wish to envelop share edges? If not, a convex hull is your primary option (as described in the other answer). If your polygons share edges, there are potential solutions that can assemble the outer polygon (and internal rings) based on the edges that are not shared (and therefore the outer limit of the bined polygon). – Andrew Reid Commented Sep 14, 2017 at 23:12
3 Answers
Reset to default 9Your looking for the "convex hull":
In mathematics, the convex hull or convex envelope of a set X of points in the Euclidean plane or in a Euclidean space (or, more generally, in an affine space over the reals) is the smallest convex set that contains X.
Reference: https://en.wikipedia/wiki/Convex_hull
You can do that with Turf.js convex
method:
Takes a Feature or a FeatureCollection and returns a convex hull Polygon.
Reference: http://turfjs/docs/#convex
Example:
var map = new L.Map('leaflet', {center: [0, 0], zoom: 0});
var collection = turf.featureCollection([
turf.polygon([[[-80,-80],[-40,-80],[-40,-40],[-80,-40],[-80,-80]]]),
turf.polygon([[[80,80],[40,80],[40,40],[80,40],[80,80]]])
]);
new L.GeoJSON(collection, {color: 'red'}).addTo(map);
var polygon = turf.convex(collection);
new L.GeoJSON(polygon, {color: 'black', 'fill': false }).addTo(map);
body {
margin: 0;
}
html, body, #leaflet {
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<title>Leaflet 1.2.0</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link type="text/css" rel="stylesheet" href="//unpkg./[email protected]/dist/leaflet.css" />
</head>
<body>
<div id="leaflet"></div>
<script type="application/javascript" src="//unpkg./[email protected]/dist/leaflet.js"></script>
<script type="application/javascript" src="//npmcdn./@turf/turf/turf.min.js"></script>
</script>
</body>
</html>
@Shaswat, you are right about convex hull missing inner point. So I tried with turf.union:
const turf = require('@turf/turf')
const originGeojson = require('./SECCIONES_13_geo.json')
const totalUnion = originGeojson.features.reduce((union, feature, index) => {
if (!union) {
return turf.polygon(feature.geometry.coordinates)
}
try {
return turf.union(union, turf.polygon(feature.geometry.coordinates))
} catch (err) {
return union
}
})
console.log(JSON.stringify(totalUnion))
But it produces somethin like this, lots of holes inside.
The code itself is not correct, for the catch block, which is just a way to get through the entire list. The error in the catch is:
Error: Each LinearRing of a Polygon must have 4 or more Positions.
I'd really appreciate if someone can share the correct way to resolve this.
I managed to do that, but using TopoJSON. I post a video here.
First I tried using the "union" function in tuffjs. But it is extremely slow (I have a very detailed geojson).
So I switched to topojson. First you need to convert your geojson to topojson. Then use the "merge" function in topojson-client library. The merge returns multipolygon, but it is way simpler than the original geometries.
Then you need to do additional processings in the code, to remove some polygon that falls within other polygons.
- https://github./topojson/topojson-client
- https://github./topojson/topojson-simplify
- https://github./topojson/topojson-server