Skip to content

Commit

Permalink
split into 2 tsconfig.json files
Browse files Browse the repository at this point in the history
  • Loading branch information
psnider committed Jul 4, 2016
1 parent 5e997cc commit 58b51f4
Show file tree
Hide file tree
Showing 11 changed files with 449 additions and 185 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store
npm-debug.log
node_modules/**
123 changes: 44 additions & 79 deletions geo-find-close-polylines.d.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,53 @@
declare namespace Geo {

type LatLongPt = GeoJSON.Feature<GeoJSON.Point>
type Path = GeoJSON.Feature<GeoJSON.LineString>
// A bounding box (from turf.js) as an array in WSEN order (west, south, east, north)
type IBoundingBox = Array<number>


// TODO: convert this to a segment feature
interface CloseSegment {
segment_index: number
distance_to_path: number
pt_on_segment: LatLongPt
}


interface PathSegments {
// segment index into path of start of this indexed section
start: number
// segment index into path of end of this indexed section
end: number
}


interface SpatialIndexOnPath extends PathSegments {
bbox: IBoundingBox
// an index on the leading portion of this subpath
// head and tail must be used together
head?: SpatialIndexOnPath
// an index on the trailing portion of this subpath
tail?: SpatialIndexOnPath
}

/// <reference path="./typings/geojson/geojson.d.ts"/>



export const METERS_PER_DEGREE_AT_EQUATOR: number
export function radiansToDegrees(radians: number): number
export function degreeToRadians(degrees: number): number
export function metersToLatitudeDistance(meters: number, latitude: number)
export function metersToLongitudeDistance(meters: number)
export function latitudeDistanceToMeters(latitude_distance: number, latitude: number)
export function longitudeDistanceToMeters(longitude_distance: number)

export class BoundingBox {
bbox: GFCP.IBoundingBox
constructor(bbox: BoundingBox | GFCP.IBoundingBox, query_distance?: number)
constructor(point: GFCP.LatLongPt | Position, query_distance?: number)
constructor(points: GeoJSON.Position[], query_distance?: number)
extend(bbox: BoundingBox | GFCP.IBoundingBox)
extend(point: GFCP.LatLongPt | Position)
extend(points: GeoJSON.Position[])
extend(distance_m: number)
intersects(bbox: BoundingBox | GFCP.IBoundingBox, query_distance?: number): boolean
intersects(point: GFCP.LatLongPt | GeoJSON.Position, query_distance?: number): boolean
}


declare module 'geo-find-close-polylines' {

const METERS_PER_DEGREE_AT_EQUATOR: number
function radiansToDegrees(radians: number): number
function degreeToRadians(degrees: number): number
function metersToLatitudeDistance(meters: number, latitude: number)
function metersToLongitudeDistance(meters: number)
function latitudeDistanceToMeters(latitude_distance: number, latitude: number)
function longitudeDistanceToMeters(longitude_distance: number)

class BoundingBox {
bbox: Geo.IBoundingBox
constructor(bbox: BoundingBox | Geo.IBoundingBox, query_distance?: number)
constructor(point: Geo.LatLongPt | Position, query_distance?: number)
constructor(points: GeoJSON.Position[], query_distance?: number)
extend(bbox: BoundingBox | Geo.IBoundingBox)
extend(point: Geo.LatLongPt | Position)
extend(points: GeoJSON.Position[])
extend(distance_m: number)
intersects(bbox: BoundingBox | Geo.IBoundingBox, query_distance?: number): boolean
intersects(point: Geo.LatLongPt | GeoJSON.Position, query_distance?: number): boolean
}

function mergeBoundingBoxes(a: Geo.IBoundingBox, b: Geo.IBoundingBox): Geo.IBoundingBox
export function mergeBoundingBoxes(a: GFCP.IBoundingBox, b: GFCP.IBoundingBox): GFCP.IBoundingBox


// @param path: The path to index. Normally, this is the only argument.
// @param max_unindexed_length: The maximum number of segments to remain unindexed.
// Defaults to 32.
// @param start: The index of the first segment to index.
// A segment N is bounded by points N and N+1
// @param end: The index of the last segment to index.
// @return: The spatial index for this path.
function createSpatialIndexForPath(path: GeoJSON.Position[], max_unindexed_length?: number, start?: number, end?: number): Geo.SpatialIndexOnPath
// @param path: The path to index. Normally, this is the only argument.
// @param max_unindexed_length: The maximum number of segments to remain unindexed.
// Defaults to 32.
// @param start: The index of the first segment to index.
// A segment N is bounded by points N and N+1
// @param end: The index of the last segment to index.
// @return: The spatial index for this path.
export function createSpatialIndexForPath(path: GeoJSON.Position[], max_unindexed_length?: number, start?: number, end?: number): GFCP.SpatialIndexOnPath

// @param index: The spatial index to search.
// @param query_pt: The point to search for.
// @param query_distance: The distance within which to search for the point.
// @return: Indexes to the segments from the index that match the query.
function findPathSegmentsFromPointInIndex(index: Geo.SpatialIndexOnPath, query_pt: Geo.LatLongPt | GeoJSON.Position, query_distance?: number): Geo.PathSegments[]
// @param index: The spatial index to search.
// @param query_pt: The point to search for.
// @param query_distance: The distance within which to search for the point.
// @return: Indexes to the segments from the index that match the query.
export function findPathSegmentsFromPointInIndex(index: GFCP.SpatialIndexOnPath, query_pt: GFCP.LatLongPt | GeoJSON.Position, query_distance?: number): GFCP.PathSegments[]

// @param path: The path to index. Normally, this is the only argument.
// @param query_pt: The point near which to find path segments.
// @param distance_m: The distance in meters within which the query point must lie of the segments.
// @return: An array of the segments that match the query.
function findCloseSegmentsNearPoint(path: Geo.Path, index: Geo.SpatialIndexOnPath, query_pt: Geo.LatLongPt | GeoJSON.Position, distance_m?: number): Geo.CloseSegment[]
// @param path: The path to index. Normally, this is the only argument.
// @param query_pt: The point near which to find path segments.
// @param distance_m: The distance in meters within which the query point must lie of the segments.
// @return: An array of the segments that match the query.
export function findCloseSegmentsNearPoint(path: GFCP.Path, index: GFCP.SpatialIndexOnPath, query_pt: GFCP.LatLongPt | GeoJSON.Position, distance_m?: number): GFCP.CloseSegment[]


var test: {
findCloseSegments: (path: Geo.Path, base_index: number, query_pt: Geo.LatLongPt, query_distance: number) => Geo.CloseSegment[]
}
export var test: {
findCloseSegments: (path: GFCP.Path, base_index: number, query_pt: GFCP.LatLongPt, query_distance: number) => GFCP.CloseSegment[]
}
3 changes: 2 additions & 1 deletion geo-find-close-polylines.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use strict";
/// <reference path="../types.d.ts"/>
var turf = require('turf');
exports.METERS_PER_DEGREE_AT_EQUATOR = 111111;
function radiansToDegrees(radians) {
Expand Down Expand Up @@ -136,7 +137,7 @@ var BoundingBox = (function () {
}
};
// TODO: requires line segment math
// TODO: intersects(pts: Geo.LatLongPt[]): boolean
// TODO: intersects(pts: GFCP.LatLongPt[]): boolean
BoundingBox.prototype.intersects = function (obj, query_distance) {
var _this = this;
var intersectsIBoundingBox = function (bbox, query_distance) {
Expand Down
57 changes: 29 additions & 28 deletions geo-find-close-polylines.tests.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
"use strict";
/// <reference path="../types.d.ts"/>
var CHAI = require('chai');
var expect = CHAI.expect;
var turf = require('turf');
var geo = require('./geo-find-close-polylines');
var Geo = require('../geo-find-close-polylines');
describe('geo', function () {
describe('conversion', function () {
var LAT_DISTANCE_TO_METERS = {
equator: {
'1': geo.METERS_PER_DEGREE_AT_EQUATOR,
'0.5': geo.METERS_PER_DEGREE_AT_EQUATOR / 2,
'1': Geo.METERS_PER_DEGREE_AT_EQUATOR,
'0.5': Geo.METERS_PER_DEGREE_AT_EQUATOR / 2,
},
'60-degrees': {
'1': geo.METERS_PER_DEGREE_AT_EQUATOR / 2,
'0.5': (geo.METERS_PER_DEGREE_AT_EQUATOR / 2) / 2,
'1': Geo.METERS_PER_DEGREE_AT_EQUATOR / 2,
'0.5': (Geo.METERS_PER_DEGREE_AT_EQUATOR / 2) / 2,
}
};
describe('metersToLatitudeDistance', function () {
it('should work at the equator', function () {
var lat_distance = geo.metersToLatitudeDistance(LAT_DISTANCE_TO_METERS['equator']['0.5'], 0);
var lat_distance = Geo.metersToLatitudeDistance(LAT_DISTANCE_TO_METERS['equator']['0.5'], 0);
expect(lat_distance).to.be.closeTo(0.5, 0.00001);
});
it('should work at 60 degrees', function () {
var lat_distance = geo.metersToLatitudeDistance(LAT_DISTANCE_TO_METERS['60-degrees']['0.5'], 60);
var lat_distance = Geo.metersToLatitudeDistance(LAT_DISTANCE_TO_METERS['60-degrees']['0.5'], 60);
expect(lat_distance).to.be.closeTo(0.5, 0.00001);
});
});
describe('latitudeDistanceToMeters', function () {
it('should work at the equator', function () {
var meters = geo.latitudeDistanceToMeters(0.5, 0);
var meters = Geo.latitudeDistanceToMeters(0.5, 0);
expect(meters).to.be.closeTo(LAT_DISTANCE_TO_METERS['equator']['0.5'], 1);
});
it('should work at 60 degrees', function () {
var meters = geo.latitudeDistanceToMeters(0.5, 60);
var meters = Geo.latitudeDistanceToMeters(0.5, 60);
expect(meters).to.be.closeTo(LAT_DISTANCE_TO_METERS['60-degrees']['0.5'], 1);
});
});
Expand All @@ -40,21 +41,21 @@ describe('geo', function () {
it('should merge box contained in box', function () {
var contained = [-1, 1, 1, 1];
var container = [-2, -2, 2, 2];
var merged = geo.mergeBoundingBoxes(contained, container);
var merged = Geo.mergeBoundingBoxes(contained, container);
var expected = [-2, -2, 2, 2];
expect(merged).to.deep.equal(expected);
});
it('should merge boxes that overlap', function () {
var a = [-2, -2, 2, 2];
var b = [1, 1, 3, 3];
var merged = geo.mergeBoundingBoxes(a, b);
var merged = Geo.mergeBoundingBoxes(a, b);
var expected = [-2, -2, 3, 3];
expect(merged).to.deep.equal(expected);
});
it('should merge boxes that dont overlap', function () {
var a = [-2, -2, -1, -1];
var b = [1, 1, 2, 2];
var merged = geo.mergeBoundingBoxes(a, b);
var merged = Geo.mergeBoundingBoxes(a, b);
var expected = [-2, -2, 2, 2];
expect(merged).to.deep.equal(expected);
});
Expand All @@ -68,12 +69,12 @@ describe('geo', function () {
[4, 1]
];
it('should not create a sub-index for a line that is shorter than the max_unindexed_length', function () {
var index = geo.createSpatialIndexForPath(pts);
var index = Geo.createSpatialIndexForPath(pts);
var expected = { bbox: [0, 0, 4, 1], start: 0, end: 3 };
expect(index).to.deep.equal(expected);
});
it('should create a sub-index for a line that is longer than the max_unindexed_length', function () {
var index = geo.createSpatialIndexForPath(pts, 2);
var index = Geo.createSpatialIndexForPath(pts, 2);
var expected = { bbox: [0, 0, 4, 1], start: 0, end: 3 };
var head = { bbox: [0, 0, 2, 0], start: 0, end: 1 };
var tail = { bbox: [2, 0, 4, 1], start: 2, end: 3 };
Expand All @@ -85,13 +86,13 @@ describe('geo', function () {
describe('intersects', function () {
describe('when query_distance isn\'t specified', function () {
it('should be true for a point inside the bounds', function () {
var bbox = new geo.BoundingBox([-10, -10, 10, 10]);
var bbox = new Geo.BoundingBox([-10, -10, 10, 10]);
expect(bbox.intersects([5, 5])).to.be.true;
});
});
describe('when query_distance is specified', function () {
it('should be true for a point just outside the bounds', function () {
var bbox = new geo.BoundingBox([-10, -10, 10, 10]);
var bbox = new Geo.BoundingBox([-10, -10, 10, 10]);
expect(bbox.intersects([-10.001, 0], 150)).to.be.true;
});
});
Expand All @@ -112,37 +113,37 @@ describe('geo', function () {
};
describe('when query_distance isn\'t specified', function () {
it('should return null, when there are no matches', function () {
var match = geo.findPathSegmentsFromPointInIndex(INDEX, [0, 11]);
var match = Geo.findPathSegmentsFromPointInIndex(INDEX, [0, 11]);
expect(match).to.be.null;
});
it('should return one match, when the only match is in the head', function () {
var match = geo.findPathSegmentsFromPointInIndex(INDEX, [-5, 5]);
var match = Geo.findPathSegmentsFromPointInIndex(INDEX, [-5, 5]);
expect(match).to.deep.equal([{ start: 0, end: 50 }]);
});
it('should return one match, when the only match is in the tail', function () {
var match = geo.findPathSegmentsFromPointInIndex(INDEX, [5, -5]);
var match = Geo.findPathSegmentsFromPointInIndex(INDEX, [5, -5]);
expect(match).to.deep.equal([{ start: 51, end: 100 }]);
});
});
describe('when query_distance is specified', function () {
it('should return one match, when the only match just outside the head, but within the query_distance', function () {
// the query_pt is left of the top-left point
var match = geo.findPathSegmentsFromPointInIndex(INDEX, [-10.001, 10.001], 150);
var match = Geo.findPathSegmentsFromPointInIndex(INDEX, [-10.001, 10.001], 150);
expect(match).to.deep.equal([{ start: 0, end: 50 }]);
});
it('should return null, when the only match just outside the head, but outside the query_distance', function () {
// the query_pt is left of the top-left point
var match = geo.findPathSegmentsFromPointInIndex(INDEX, [-10.001, 10.001], 80);
var match = Geo.findPathSegmentsFromPointInIndex(INDEX, [-10.001, 10.001], 80);
expect(match).to.be.null;
});
it('should return one match, when the only match just outside the tail, but within the query_distance', function () {
// the query_pt is right of the bottom-right point
var match = geo.findPathSegmentsFromPointInIndex(INDEX, [10.001, 0], 120);
var match = Geo.findPathSegmentsFromPointInIndex(INDEX, [10.001, 0], 120);
expect(match).to.deep.equal([{ start: 51, end: 100 }]);
});
it('should return null, when the only match just outside the head, but outside the query_distance', function () {
// the query_pt is right of the bottom-right point
var match = geo.findPathSegmentsFromPointInIndex(INDEX, [10.001, 0], 80);
var match = Geo.findPathSegmentsFromPointInIndex(INDEX, [10.001, 0], 80);
expect(match).to.be.null;
});
});
Expand All @@ -161,12 +162,12 @@ describe('geo', function () {
};
it('should return segments when pt is closer than distance', function () {
var query_pt = turf.point([0.5, 0.001]);
var close_segments = geo.test.findCloseSegments(line, 0, query_pt, 112);
var close_segments = Geo.test.findCloseSegments(line, 0, query_pt, 112);
expect(close_segments).to.have.lengthOf(1);
});
it('should not return segments when pt is farther than distance', function () {
var query_pt = turf.point([0.5, 0.001]);
var close_segments = geo.test.findCloseSegments(line, 0, query_pt, 110);
var close_segments = Geo.test.findCloseSegments(line, 0, query_pt, 110);
expect(close_segments).to.have.lengthOf(0);
});
});
Expand Down Expand Up @@ -196,17 +197,17 @@ describe('geo', function () {
}
};
it('should not return segments when pt is farther than distance', function () {
var segments = geo.findCloseSegmentsNearPoint(line, INDEX, [1, 0.001], 80);
var segments = Geo.findCloseSegmentsNearPoint(line, INDEX, [1, 0.001], 80);
expect(segments).to.have.lengthOf(0);
});
it('should return a segment when pt is closer than distance', function () {
var segments = geo.findCloseSegmentsNearPoint(line, INDEX, [0.5, 0.001], 120);
var segments = Geo.findCloseSegmentsNearPoint(line, INDEX, [0.5, 0.001], 120);
expect(segments).to.have.lengthOf(1);
expect(segments[0].segment_index).to.equal(0);
expect(segments[0].distance_to_path).to.be.closeTo(111, 0.5);
});
it('should return 2 segments when pt is close to 2 segments', function () {
var segments = geo.findCloseSegmentsNearPoint(line, INDEX, [1, 0.001], 120);
var segments = Geo.findCloseSegmentsNearPoint(line, INDEX, [1, 0.001], 120);
expect(segments).to.have.lengthOf(2);
expect(segments[0].segment_index).to.equal(0);
expect(segments[1].segment_index).to.equal(1);
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Quickly find the closest line segments of a polyline on the earth's surface.",
"main": "geo-find-close-polylines.js",
"scripts": {
"build": "tsc --project .",
"build": "tsc --project src; tsc --project test",
"clean": "rm -f geo-find-close-polylines.js geo-find-close-polylines.tests.js",
"test": "mocha ./geo-find-close-polylines.tests.js"
},
Expand All @@ -20,5 +20,6 @@
"devDependencies": {
"chai": "^3.5.0",
"typescript": "^1.8.10"
}
},
"typings": "geo-find-close-polylines.d.ts"
}
Loading

0 comments on commit 58b51f4

Please sign in to comment.