Calculating percentage overlap of two polygons in JavaScript
Here's the problem: I have geoJSON and topoJSON files that give me polygons for census block groups and polling stations. I am trying to understand how a given census block group overlaps with a given parcel.
I've seen a couple of examples of what I need in other languages ββ- i.e. R and in some GIS tools, but I'm trying to write this as a Node.js script. A few questions:
- Is there an NPM module (I've done quite a bit of Googling, but I haven't found one) that can spit out a percentage match?
- Is there an algorithm or exmaple written in another language that I should be aware of (I've looked, but I don't have the most vague where to start) and what I could port to JavaScript?
- Otherwise, can anyone explain to me how I am going to think about creating an algorithm for this?
In the end, the final product will look something like this: imagining that I have arrays of polling stations and block groups, and each of them is an object with a geometry property that contains polygonal data for a group of parcels or blocks, as well as imagining that I have a function called overlap
that splashes out the percentage overlap when passing two polygons:
// Iterate over each precinct.
_.each( precincts, function ( precinct ) {
// Iterate over each blockgroup.
_.each( blockgroups, function ( blockgroup ) {
// Get the overlap for the current precinct and blockgroup.
var o = overlap( precinct.geometry, blockgroup.geometry );
// If they overlap at all...
if ( o > 0 ) {
// ...Add information about the overlap to the precinct.
precinct.overlaps.push({
blockgroup: blockgroup.id,
overlap: o
});
}
}
}
(I've seen this module , but it only gives if the polygons overlap, not how much they do.)
source to share
To calculate the percentage of overlap
-
Calculate the intersection of two polygons
Intersection = intersect(Precinct, Block)
-
Divide the intersection area into the parent polygon area of ββinterest.
Overlap = area(Intersection) / area(Parent)
-
It is a bit confusing what you mean by percentage overlap. The parent polygon can be one of several possibilities
a) area(Intersection) / area(Precinct) b) area(Intersection) / area(Block) c) area(Intersection) / area(Precinct union Block)
As far as the javascript library goes, it looks like you have what you need Intersection.js
There is also the JSTS Topology Suite , which can do geospatial processing in JavaScript. Node.js examples are here .
source to share
turf-intersect takes two polygons and returns a polygon representing the intersection.
geojson-area takes a polygon and returns the area in square meters.
npm install turf
npm install geojson-area
var turf = require('turf');
var geojsonArea = require('geojson-area');
var poly1 = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[-122.801742, 45.48565],
[-122.801742, 45.60491],
[-122.584762, 45.60491],
[-122.584762, 45.48565],
[-122.801742, 45.48565]
]]
}
}
var poly2 = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[-122.520217, 45.535693],
[-122.64038, 45.553967],
[-122.720031, 45.526554],
[-122.669906, 45.507309],
[-122.723464, 45.446643],
[-122.532577, 45.408574],
[-122.487258, 45.477466],
[-122.520217, 45.535693]
]]
}
}
var intersection = turf.intersect(poly1, poly2);
var area_intersection = geojsonArea.geometry(intersection.geometry);
var area_poly1 = geojsonArea.geometry(poly1.geometry);
var percent_poly1_covered_by_poly2 = (area_intersection / area_poly1)*100;
source to share