Calculating the percent overlap of two polygons in JavaScript

4.8k Views Asked by At

Here's the problem: I have geoJSON and topoJSON files that give me the polygons for Census block groups and voting precincts. I'm trying to see by how much a given Census block group overlaps with a given precinct.

I've seen a couple examples of what I'm after 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:

  1. Is there an NPM module (I've done a fair amount of Googling, but I haven't found one) that can spit out the percent overlap?
  2. Is there an algorithm, or an exmaple written in another language, that I should know about (I've looked, but I haven't the foggiest where to begin) and that I could port to JavaScript?
  3. Failing these, can someone explain to me how I would go about thinking about creating an algorithm for this?

In the end, the final product would look something like this—imagining that I have arrays of precincts and blockgroups, and each one is an object with a geometry property that contains the polygon data for the precinct or block group, and also imagining that I have a function called overlap that, when passed two polygons spits out the percent overlap:

// 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 that only gives if the polygons overlap, not by how much they do.)

3

There are 3 best solutions below

1
On BEST ANSWER

To compute the overlapping percentage

  1. Compute the intersection of the two polygons

    Intersection = intersect(Precinct, Block)
    
  2. Divide the area of Intersection by the area of the parent polygon of interest.

    Overlap = area(Intersection) / area(Parent)
    
  3. It is a little unclear what you mean by the percent overlap. The parent polygon could be one of several possibilities

    a) area(Intersection) / area(Precinct)
    
    b) area(Intersection) / area(Block)
    
    c) area(Intersection) / area(Precinct union Block)
    

As for a javascript library, this one seems to have what you need Intersection.js

There's also the JSTS Topology Suite which can do geospatial processing in JavaScript. See Node.js examples here.

2
On

You can do spatial overlaps with Turf js. It has the features of JSTS (and more), but is very modular.

0
On

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;