sparc-commons
Advanced tools
Comparing version 0.2.2 to 0.2.3
@@ -57,3 +57,3 @@ /*jshint multistr: true */ | ||
//all representations back and forth | ||
es.convert = function convert(opts){ | ||
var convert = es.convert = function convert(opts){ | ||
var repr = _.get(opts, "representation", "latlon") | ||
@@ -127,3 +127,3 @@ var handleObj = function(coordinates, fn){ | ||
es.distanceFromLine = function distanceFromLine(b, e, p){ | ||
var distanceFromLine = es.distanceFromLine = function distanceFromLine(b, e, p){ | ||
var px = e.lon - b.lon | ||
@@ -134,4 +134,4 @@ var py = e.lat - b. lat | ||
if(u > 1) u = 1 | ||
else if(u < 0) u = 0 | ||
var x = b.lon + u * px | ||
else if(u < 0) u = 0 | ||
var x = b.lon + u * px | ||
var y = b.lat + u * py | ||
@@ -144,30 +144,101 @@ var dx = x - p.lon | ||
es.spliceVector = function spliceVector(segment, point, opts){ | ||
var self = this | ||
var convert = this.convert(opts) | ||
var convPoint = convert(point) | ||
if(segment && segment.length > 0){ | ||
var result = _.reduce(_.rest(segment), function(current, end, idx){ | ||
var convEnd = convert(end) | ||
var convBegin = current.begin | ||
var proximity = self.distanceFromLine(convBegin, convEnd, convPoint) | ||
if(proximity < current.proximity){ | ||
current.proximity = proximity, | ||
current.idx = idx + 1 | ||
} | ||
current.begin = convEnd | ||
return current | ||
var calculateTrend = (coordCur, coordPrev) => { | ||
var diffLat = coordCur.lat - coordPrev.lat | ||
var diffLon = coordCur.lon - coordPrev.lon | ||
return [diffLat < 0, diffLon < 0] | ||
} | ||
var quadrant = (coordCur, coordPrev) => { | ||
var currentTrend = calculateTrend(coordCur, coordPrev) | ||
if(currentTrend[0] && currentTrend[1]){ | ||
//quadrant 1 => lat ascendent, lon ascendent | ||
return trend => { | ||
return !trend[0] | ||
} | ||
} else if(currentTrend[0] && !currentTrend[1]){ | ||
//quadrant 2 => lat ascendent, lon descendent | ||
return trend => { | ||
return !trend[0] | ||
} | ||
} else if(!currentTrend[0] && !currentTrend[1]) { | ||
//quadrant 3 => lat descendent, lon descendent | ||
return trend => { | ||
return trend[0] | ||
} | ||
} | ||
//quadrant 4 => lat descendent, lon ascendent | ||
return trend => { | ||
return trend[0] | ||
} | ||
} | ||
//-1 descendent +1 ascendent 0 neither | ||
var calculateQuadrant = (current, previous, opts) => { | ||
if(previous){ | ||
var conversion = convert(opts) | ||
var cur = conversion(current) | ||
var prev = conversion(previous) | ||
return quadrant(cur, prev) | ||
} | ||
return null | ||
} | ||
var splicePoint = es.splicePoint = (segment, point, opts) => { | ||
if(_.isUndefined(segment) || segment.length < 2){ | ||
throw Error('Cannot process a segment with less than two coordinates') | ||
} | ||
var conversion = convert(opts) | ||
var convPoint = conversion(point) | ||
var begin = conversion(segment[0]) | ||
var end = conversion(_.last(segment)) | ||
var proximityList = _.sortBy(_.reduce(segment, (acc, coords, index) => { | ||
var proximity = distance([coords, convPoint], convert(opts)).dist | ||
acc.push({ | ||
index: index, | ||
proximity: proximity, | ||
coords: conversion(coords), | ||
isBetween: calculateQuadrant(coords, _.get(_.last(acc), 'coords'), opts) | ||
}) | ||
return acc | ||
}, []), 'proximity') | ||
var closest = _.sortBy(proximityList, 'proximity').slice(0, 2) | ||
var trend = calculateTrend(closest[0].coords, convPoint) | ||
if(closest[1].isBetween(trend)){ | ||
segment.splice(closest[0].index + 1, 0, point) | ||
return closest[0].index + 1 | ||
} | ||
segment.splice(closest[0].index, 0, point) | ||
return closest[0].index | ||
} | ||
es.spliceSegment = function spliceSegment(segment, points, opts){ | ||
var arePointsSequential = _.get(opts, 'sequential', false) | ||
if(arePointsSequential){ | ||
var reduced = _.reduce(points, (acc, point) => { | ||
var rest = acc.rest | ||
var index = splicePoint(rest, point, opts) | ||
acc.before = acc.before.concat(rest.slice(0, index)) | ||
acc.rest = rest.slice(index) | ||
return acc | ||
}, { | ||
begin: convert(_.first(segment)), | ||
proximity: Number.MAX_VALUE, | ||
idx: 1 | ||
rest: segment, | ||
before: [] | ||
}) | ||
segment.splice(result.idx, 0, point) | ||
return result.idx | ||
return reduced.before.concat(reduced.rest) | ||
} | ||
return [point] | ||
return _.reduce(points, (seg, point) => { | ||
splicePoint(seg, point, opts) | ||
return seg | ||
}, segment) | ||
} | ||
es._distance = function _distance(coords, conversionFn){ | ||
var distance = es._distance = function _distance(coords, conversionFn){ | ||
return _.reduce(coords, function(acc, current){ | ||
@@ -174,0 +245,0 @@ if(!_.isEmpty(acc.lastCoord)){ |
{ | ||
"name": "sparc-commons", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"description": "Library with all small time common stuff used across the SPARC echosystem", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -19,3 +19,3 @@ { | ||
}, | ||
"replaceConsole": "true" | ||
"replaceConsole": false | ||
}, | ||
@@ -22,0 +22,0 @@ |
@@ -1,9 +0,4 @@ | ||
var chai = require('chai'), | ||
_ = require('lodash'), | ||
log = require('../libs').log, | ||
sinon = require('sinon'), | ||
geo = require('..'), | ||
polyline = require('polyline'), | ||
geocode = require('../libs/geocode').reverseGeocode, | ||
resources = require('../libs').resources | ||
var chai = require('chai') | ||
var _ = require('lodash') | ||
var geo = require('..') | ||
@@ -86,3 +81,3 @@ var assert = chai.assert; | ||
_.each(coordinates, function(coord){ | ||
var result = geo.findClosest(polylineArray, coord, {representation: "lonlat"}) | ||
geo.findClosest(polylineArray, coord, {representation: "lonlat"}) | ||
}) | ||
@@ -110,60 +105,323 @@ }) | ||
describe("[INSERT INTO VECTOR]", function(){ | ||
it("Inserts into a negative progression vector", function(){ | ||
it("Real-life (buggy) segment progression", function(){ | ||
var segment = [ | ||
[ | ||
2.3675537109375, | ||
47.77625204393236 | ||
], | ||
[ | ||
3.636474609375, | ||
47.62467785241324 | ||
], | ||
[ | ||
2.5653076171875, | ||
47.2195681123155 | ||
], | ||
[ | ||
3.0926513671875, | ||
47.27177506640826 | ||
], | ||
[ | ||
2.08740234375, | ||
46.84140712700584 | ||
] | ||
[ 4.92031479, 52.36303553 ], | ||
[ 4.92027212, 52.36301908 ], | ||
[ 4.92021261, 52.36299439 ], | ||
[ 4.92012839, 52.36295325 ], | ||
[ 4.91999477, 52.36287096 ], | ||
[ 4.91978647, 52.36272285 ], | ||
[ 4.91936988, 52.36244308 ], | ||
[ 4.91902627, 52.36222914 ], | ||
[ 4.91871523, 52.362092 ], | ||
[ 4.91844967, 52.3620152 ], | ||
[ 4.91821611, 52.36196857 ], | ||
[ 4.91785959, 52.36192194 ], | ||
[ 4.91714599, 52.36188628 ], | ||
[ 4.91694274, 52.36187805 ], | ||
[ 4.91650762, 52.36184788 ], | ||
[ 4.91625553, 52.36181222 ], | ||
[ 4.91543863, 52.36160376 ], | ||
[ 4.9153589, 52.36158182 ], | ||
[ 4.91526739, 52.36155713 ], | ||
[ 4.91521349, 52.36154342 ], | ||
[ 4.91517643, 52.36153245 ], | ||
[ 4.91511973, 52.36151599 ], | ||
[ 4.91504168, 52.36149405 ], | ||
[ 4.91494287, 52.36146662 ], | ||
[ 4.9145987, 52.36138159 ], | ||
[ 4.91412765, 52.36127736 ], | ||
[ 4.91351343, 52.3611841 ], | ||
[ 4.91237986, 52.36109632 ], | ||
[ 4.91213114, 52.36107987 ], | ||
[ 4.91190993, 52.36102775 ], | ||
[ 4.91166233, 52.36092078 ] | ||
] | ||
var first = [ | ||
3.328857421875, | ||
47.66168780332917 | ||
var sequenceToAdd = [ | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.920315, 52.363037], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "1" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.9190264,52.36223], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "2" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.9169106,52.361877], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "3" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.9156775,52.361664], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "4" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.91566, 52.36166], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "5" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.91569,52.361668], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "6" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.914374, 52.361332], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "7" | ||
} | ||
} | ||
] | ||
var second = [ | ||
3.3343505859375, | ||
47.52091047852614 | ||
var ordered = geo.spliceSegment(segment, sequenceToAdd, {sequential: false, representation: 'lonlat'}) | ||
var expectation = [ | ||
[ 4.920315, 52.363037 ], | ||
[ 4.92031479, 52.36303553 ], | ||
[ 4.92027212, 52.36301908 ], | ||
[ 4.92021261, 52.36299439 ], | ||
[ 4.92012839, 52.36295325 ], | ||
[ 4.91999477, 52.36287096 ], | ||
[ 4.91978647, 52.36272285 ], | ||
[ 4.91936988, 52.36244308 ], | ||
[ 4.9190264, 52.36223 ], | ||
[ 4.91902627, 52.36222914 ], | ||
[ 4.91871523, 52.362092 ], | ||
[ 4.91844967, 52.3620152 ], | ||
[ 4.91821611, 52.36196857 ], | ||
[ 4.91785959, 52.36192194 ], | ||
[ 4.91714599, 52.36188628 ], | ||
[ 4.91694274, 52.36187805 ], | ||
[ 4.9169106, 52.361877 ], | ||
[ 4.91650762, 52.36184788 ], | ||
[ 4.91625553, 52.36181222 ], | ||
[ 4.91569, 52.361668 ], | ||
[ 4.9156775, 52.361664 ], | ||
[ 4.91566, 52.36166 ], | ||
[ 4.91543863, 52.36160376 ], | ||
[ 4.9153589, 52.36158182 ], | ||
[ 4.91526739, 52.36155713 ], | ||
[ 4.91521349, 52.36154342 ], | ||
[ 4.91517643, 52.36153245 ], | ||
[ 4.91511973, 52.36151599 ], | ||
[ 4.91504168, 52.36149405 ], | ||
[ 4.91494287, 52.36146662 ], | ||
[ 4.9145987, 52.36138159 ], | ||
[ 4.914374, 52.361332 ], | ||
[ 4.91412765, 52.36127736 ], | ||
[ 4.91351343, 52.3611841 ], | ||
[ 4.91237986, 52.36109632 ], | ||
[ 4.91213114, 52.36107987 ], | ||
[ 4.91190993, 52.36102775 ], | ||
[ 4.91166233, 52.36092078 ] | ||
] | ||
var third = [ | ||
2.9718017578125, | ||
47.26432008025478 | ||
_.each(_.zip(ordered, expectation), _.spread((lx, rx) => { | ||
if(_.get(lx, "geometry.coordinates")) lx = lx.geometry.coordinates | ||
expect(lx).to.deep.equal(rx) | ||
})) | ||
}) | ||
it("Real-life (buggy) segment progression with (supposedly) ordered points", function(){ | ||
var segment = [ | ||
[ 4.92031479, 52.36303553 ], | ||
[ 4.92027212, 52.36301908 ], | ||
[ 4.92021261, 52.36299439 ], | ||
[ 4.92012839, 52.36295325 ], | ||
[ 4.91999477, 52.36287096 ], | ||
[ 4.91978647, 52.36272285 ], | ||
[ 4.91936988, 52.36244308 ], | ||
[ 4.91902627, 52.36222914 ], | ||
[ 4.91871523, 52.362092 ], | ||
[ 4.91844967, 52.3620152 ], | ||
[ 4.91821611, 52.36196857 ], | ||
[ 4.91785959, 52.36192194 ], | ||
[ 4.91714599, 52.36188628 ], | ||
[ 4.91694274, 52.36187805 ], | ||
[ 4.91650762, 52.36184788 ], | ||
[ 4.91625553, 52.36181222 ], | ||
[ 4.91543863, 52.36160376 ], | ||
[ 4.9153589, 52.36158182 ], | ||
[ 4.91526739, 52.36155713 ], | ||
[ 4.91521349, 52.36154342 ], | ||
[ 4.91517643, 52.36153245 ], | ||
[ 4.91511973, 52.36151599 ], | ||
[ 4.91504168, 52.36149405 ], | ||
[ 4.91494287, 52.36146662 ], | ||
[ 4.9145987, 52.36138159 ], | ||
[ 4.91412765, 52.36127736 ], | ||
[ 4.91351343, 52.3611841 ], | ||
[ 4.91237986, 52.36109632 ], | ||
[ 4.91213114, 52.36107987 ], | ||
[ 4.91190993, 52.36102775 ], | ||
[ 4.91166233, 52.36092078 ] | ||
] | ||
var fourth= [ | ||
2.9168701171875, | ||
47.19717795172789 | ||
var sequenceToAdd = [ | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.920315, 52.363037], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "1" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.9190264,52.36223], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "2" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.9169106,52.361877], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "3" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.9156775,52.361664], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "4" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.91566, 52.36166], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "5" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.91569,52.361668], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "6" | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"coordinates": [4.914374, 52.361332], | ||
"type": "Point" | ||
}, | ||
"properties":{ | ||
"id": "7" | ||
} | ||
} | ||
] | ||
var fifth=[ | ||
2.274169921875, | ||
46.924007100770275 | ||
var ordered = geo.spliceSegment(segment, sequenceToAdd, {sequential: false, representation: 'lonlat'}) | ||
var expectation = [ | ||
[ 4.920315, 52.363037 ], | ||
[ 4.92031479, 52.36303553 ], | ||
[ 4.92027212, 52.36301908 ], | ||
[ 4.92021261, 52.36299439 ], | ||
[ 4.92012839, 52.36295325 ], | ||
[ 4.91999477, 52.36287096 ], | ||
[ 4.91978647, 52.36272285 ], | ||
[ 4.91936988, 52.36244308 ], | ||
[ 4.9190264, 52.36223 ], | ||
[ 4.91902627, 52.36222914 ], | ||
[ 4.91871523, 52.362092 ], | ||
[ 4.91844967, 52.3620152 ], | ||
[ 4.91821611, 52.36196857 ], | ||
[ 4.91785959, 52.36192194 ], | ||
[ 4.91714599, 52.36188628 ], | ||
[ 4.91694274, 52.36187805 ], | ||
[ 4.9169106, 52.361877 ], | ||
[ 4.91650762, 52.36184788 ], | ||
[ 4.91625553, 52.36181222 ], | ||
[ 4.91569, 52.361668 ], | ||
[ 4.9156775, 52.361664 ], | ||
[ 4.91566, 52.36166 ], | ||
[ 4.91543863, 52.36160376 ], | ||
[ 4.9153589, 52.36158182 ], | ||
[ 4.91526739, 52.36155713 ], | ||
[ 4.91521349, 52.36154342 ], | ||
[ 4.91517643, 52.36153245 ], | ||
[ 4.91511973, 52.36151599 ], | ||
[ 4.91504168, 52.36149405 ], | ||
[ 4.91494287, 52.36146662 ], | ||
[ 4.9145987, 52.36138159 ], | ||
[ 4.914374, 52.361332 ], | ||
[ 4.91412765, 52.36127736 ], | ||
[ 4.91351343, 52.3611841 ], | ||
[ 4.91237986, 52.36109632 ], | ||
[ 4.91213114, 52.36107987 ], | ||
[ 4.91190993, 52.36102775 ], | ||
[ 4.91166233, 52.36092078 ] | ||
] | ||
var index = geo.spliceVector(segment, first, {representation: "lonlat"}) | ||
expect(segment[index][0]).to.be.equal(first[0]) | ||
index = geo.spliceVector(segment, second, {representation: "lonlat"}) | ||
expect(segment[index][0]).to.be.equal(second[0]) | ||
index = geo.spliceVector(segment, third, {representation: "lonlat"}) | ||
expect(segment[index][0]).to.be.equal(third[0]) | ||
index = geo.spliceVector(segment, fourth, {representation: "lonlat"}) | ||
expect(segment[index][0]).to.be.equal(fourth[0]) | ||
index = geo.spliceVector(segment, fifth, {representation: "lonlat"}, true) | ||
expect(segment[index][0]).to.be.equal(fifth[0]) | ||
_.each(_.zip(ordered, expectation), _.spread((lx, rx) => { | ||
if(_.get(lx, "geometry.coordinates")) lx = lx.geometry.coordinates | ||
expect(lx).to.deep.equal(rx) | ||
})) | ||
}) | ||
}) | ||
}); |
40369
929