From f1b3f03399732d438ffdc30983aa07783dd30816 Mon Sep 17 00:00:00 2001 From: Tim Channell Date: Mon, 23 Nov 2015 11:29:22 -0500 Subject: [PATCH 1/2] added bbox test --- index.js | 13 ++++++++++++- test/test.js | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index ae302c4..b101aae 100644 --- a/index.js +++ b/index.js @@ -22,13 +22,24 @@ function whichPolygon(data) { var tree = rbush().load(bboxes); - return function query(p) { + function query(p) { var result = tree.search([p[0], p[1], p[0], p[1]]); for (var i = 0; i < result.length; i++) { if (insidePolygon(result[i][4], p)) return result[i][5]; } return null; + } + + query.tree = tree; + query.bbox = function queryBbox(bbox) { + var result = tree.search(bbox); + if (result.length === 1) return result[0][5]; + return result.map(function (el) { + return el[5]; + }); }; + + return query; } // ray casting algorithm for detecting if point is in polygon diff --git a/test/test.js b/test/test.js index bf6a015..b8c4917 100644 --- a/test/test.js +++ b/test/test.js @@ -7,9 +7,20 @@ var data = require('./fixtures/states.json'); var query = whichPolygon(data); -test('queries polygons', function (t) { +test('queries polygons with a point', function (t) { t.equal(query([-100, 45]).name, "South Dakota"); t.equal(query([-90, 30]).name, "Louisiana"); t.equal(query([-50, 30]), null); t.end(); }); + + +test('queries polygons with a bbox', function (t) { + t.equal(query.bbox([-100, 45, -99.5, 45.5]).name, "South Dakota"); + + var qq = query.bbox([-95, 38, -94, 39]); + var names = qq.map(function (el) { return el.name; }).sort(); + t.equal(qq.length, 2); + t.equal(names[0], "Kansas"); + t.end(); +}); \ No newline at end of file From 08cec043c2143cd97f5ccef87931440ea389300b Mon Sep 17 00:00:00 2001 From: Tim Channell Date: Mon, 23 Nov 2015 12:55:59 -0500 Subject: [PATCH 2/2] fixed to use lineclip --- index.js | 14 +++++++++++--- package.json | 1 + test/test.js | 4 ++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index b101aae..78eefc7 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ 'use strict'; var rbush = require('rbush'); +var lineclip = require('lineclip'); module.exports = whichPolygon; @@ -32,11 +33,18 @@ function whichPolygon(data) { query.tree = tree; query.bbox = function queryBbox(bbox) { - var result = tree.search(bbox); - if (result.length === 1) return result[0][5]; - return result.map(function (el) { + var result = tree.search(bbox).filter(function (el) { + // bbox is (possibly) completely inside the polygon. Keep it. + if (insidePolygon(el[4], [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2])) return true; + // polygon crosses or is totally inside the bbox. Keep it. + // Todo: account for holes. + if (lineclip(el[4][0], bbox).length > 0) return true; + return false; + }).map(function (el) { return el[5]; }); + + return (result.length === 1) ? result[0] : result; }; return query; diff --git a/package.json b/package.json index 4c2bb32..c27dae8 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Index for matching points against a set of GeoJSON polygons", "main": "index.js", "dependencies": { + "lineclip": "^1.1.5", "rbush": "^1.4.1" }, "devDependencies": { diff --git a/test/test.js b/test/test.js index b8c4917..a071876 100644 --- a/test/test.js +++ b/test/test.js @@ -18,9 +18,9 @@ test('queries polygons with a point', function (t) { test('queries polygons with a bbox', function (t) { t.equal(query.bbox([-100, 45, -99.5, 45.5]).name, "South Dakota"); - var qq = query.bbox([-95, 38, -94, 39]); + var qq = query.bbox([-104.2, 44, -103, 45]); var names = qq.map(function (el) { return el.name; }).sort(); t.equal(qq.length, 2); - t.equal(names[0], "Kansas"); + t.like(names, ["South Dakota", "Wyoming"]); t.end(); }); \ No newline at end of file