geojson-js-utils/geojson-utils.js

88 lines
2.7 KiB
JavaScript

exports.init = function() {
var g = {};
g.scalarMultiply = function(xy, scalar) {
return [xy[0] * scalar, xy[1] * scalar];
}
g.subtractVector = function(xy, vector) {
return g.add(xy, g.scalarMultiply(vector, -1));
}
g.addVector = function(xy, vector) {
return [xy[0] + vector[0], xy[1] + vector[1]];
}
g.crossProduct = function(v1, v2) {
return v1[0] * v2[1] - v2[0] * v1[1];
}
g.linesIntersect = function(seg1, seg2) {
var p = seg1[0],
r = g.subtractVector(seg1[1], p),
q = seg2[0],
s = g.subtractVector(seg2[1], q);
var rCrossS = g.crossProduct(r, s);
var t = g.cross(g.subtractVector(q,p), s) / rCrossS;
var u = g.cross(g.subtractVector(q,p), r) / rCrossS;
if (0 <= u && u <= 1 && 0 <= t && t <= 1) {
var intersectionPoint = g.addVector(p, g.scalarMultiply(r, t));
return intersectionPoint;
} else {
return false;
}
}
g.pointInPolygon = function(pt, poly) {
for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1] < poly[i][1]))
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
&& (c = !c);
return c;
}
g.numberToRadius = function(number) {
return number * Math.PI / 180;
}
g.numberToDegree = function(number) {
return number * 180 / Math.PI;
}
g.drawCircle = function(radius, center) {
// convert degree/km to radiant
var dist = radius / 6371;
var radCenter = [g.numberToRadius(center[0]), g.numberToRadius(center[1])];
// 15 sided circle; the larger the radius the more inaccurate it will be
var steps = 15;
var poly = [[center[0], center[1]]];
for (var i = 0; i < steps; i++) {
var brng = 2 * Math.PI * i / steps;
var lat = Math.asin(Math.sin(radCenter[0]) * Math.cos(dist) +
Math.cos(radCenter[0]) * Math.sin(dist) * Math.cos(brng));
var lng = radCenter[1] + Math.atan2(Math.sin(brng) * Math.sin(dist) *
Math.cos(radCenter[0]),
Math.cos(dist) - Math.sin(radCenter[0]) *
Math.sin(lat));
poly[i] = [];
poly[i][0] = g.numberToDegree(lat);
poly[i][1] = g.numberToDegree(lng);
}
return poly;
}
g.rectangleCentroid = function(bbox) {
var xmin = bbox[0], ymin = bbox[1], xmax = bbox[2], ymax = bbox[3];
var xwidth = xmax - xmin;
var ywidth = ymax - ymin;
return [xmin + xwidth/2, ymin + ywidth/2];
}
g.metersToDegrees = function(meters) {
//non spherical; the larger the area the more innaccurate it will be
return meters/111319.9;
}
return g;
}