Вычисление процента перекрытия двух полигонов в JavaScript

Вот проблема: у меня есть файлы geoJSON и topoJSON, которые дают мне полигоны для групп блоков переписи и избирательных участков. Я пытаюсь увидеть, насколько данная группа блоков переписи перекрывается с данным участком.

Я видел пару примеров того, что мне нужно на других языках, т.е. R и в некоторых инструментах ГИС, но Я пытаюсь написать это как скрипт Node.js. Несколько вопросов:

  1. Есть ли модуль NPM (я много гуглил, но так и не нашел), который может выдать процентное перекрытие?
  2. Есть ли алгоритм или пример, написанный на другом языке, о котором я должен знать (я просмотрел, но не знаю, с чего начать) и который я мог бы перенести на JavaScript?
  3. В противном случае кто-нибудь может объяснить мне, как я буду думать о создании алгоритма для этого?

В конце концов, конечный продукт будет выглядеть примерно так: представьте, что у меня есть массивы участков и групп блоков, и каждый из них является объектом со свойством геометрии, которое содержит данные полигона для участка или группы блоков, а также представьте, что я есть функция с именем 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
            });

        }

    }

}

(Я видел этот модуль, но он дает только if полигоны перекрываются, а не насколько.)


person jwest    schedule 21.06.2015    source источник


Ответы (3)


Чтобы вычислить процент перекрытия

  1. Вычислите пересечение двух многоугольников

    Intersection = intersect(Precinct, Block)
    
  2. Разделите площадь пересечения на площадь интересующего родительского полигона.

    Overlap = area(Intersection) / area(Parent)
    
  3. Немного непонятно, что вы подразумеваете под процентным перекрытием. Родительский полигон может быть одним из нескольких возможных

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

Что касается библиотеки javascript, то в ней есть то, что вам нужно Intersection.js

Существует также JSTS Topology Suite, который может выполнять геопространственную обработку в JavaScript. См. примеры Node.js здесь.

person dpmcmlxxvi    schedule 21.06.2015
comment
Это выглядит великолепно. Благодарю вас! И вы совершенно правы в том, что неясно, что я имел в виду под процентным перекрытием. Я что-то имел в виду б). - person jwest; 22.06.2015

turf-intersect принимает два полигона и возвращает полигон, представляющий пересечение.

geojson-area берет многоугольник и возвращает площадь в квадратных метрах.

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;
person Mike Fabrikant    schedule 29.08.2015

Вы можете создавать пространственные перекрытия с помощью Turf js. Он имеет функции JSTS (и многое другое), но очень модульный.

person jmk    schedule 22.06.2015
comment
Бесполезно, если вы не описываете, как это сделать. - person Gajus; 19.08.2015