diff --git a/js/rtree/geojson.js b/js/rtree/geojson.js new file mode 100644 index 0000000..ec291ef --- /dev/null +++ b/js/rtree/geojson.js @@ -0,0 +1,213 @@ +'use strict'; +var rectangle = Require('rtree/rectangle'); +var bbox = function (ar, obj) { + if (obj && obj.bbox) { + return { + leaf: obj, + x: obj.bbox[0], + y: obj.bbox[1], + w: obj.bbox[2] - obj.bbox[0], + h: obj.bbox[3] - obj.bbox[1] + }; + } + var len = ar.length; + var i = 0; + var a = new Array(len); + while (i < len) { + a[i] = [ar[i][0], ar[i][1]]; + i++; + } + var first = a[0]; + len = a.length; + i = 1; + var temp = { + min: [].concat(first), + max: [].concat(first) + }; + while (i < len) { + if (a[i][0] < temp.min[0]) { + temp.min[0] = a[i][0]; + } + else if (a[i][0] > temp.max[0]) { + temp.max[0] = a[i][0]; + } + if (a[i][1] < temp.min[1]) { + temp.min[1] = a[i][1]; + } + else if (a[i][1] > temp.max[1]) { + temp.max[1] = a[i][1]; + } + i++; + } + var out = { + x: temp.min[0], + y: temp.min[1], + w: (temp.max[0] - temp.min[0]), + h: (temp.max[1] - temp.min[1]) + }; + if (obj) { + out.leaf = obj; + } + return out; +}; +var geoJSON = {}; +geoJSON.point = function (obj, self) { + return (self.insertSubtree({ + x: obj.geometry.coordinates[0], + y: obj.geometry.coordinates[1], + w: 0, + h: 0, + leaf: obj + }, self.root)); +}; +geoJSON.multiPointLineString = function (obj, self) { + return (self.insertSubtree(bbox(obj.geometry.coordinates, obj), self.root)); +}; +geoJSON.multiLineStringPolygon = function (obj, self) { + return (self.insertSubtree(bbox(Array.prototype.concat.apply([], obj.geometry.coordinates), obj), self.root)); +}; +geoJSON.multiPolygon = function (obj, self) { + return (self.insertSubtree(bbox(Array.prototype.concat.apply([], Array.prototype.concat.apply([], obj.geometry.coordinates)), obj), self.root)); +}; +geoJSON.makeRec = function (obj) { + return rectangle(obj.x, obj.y, obj.w, obj.h); +}; +geoJSON.geometryCollection = function (obj, self) { + if (obj.bbox) { + return (self.insertSubtree({ + leaf: obj, + x: obj.bbox[0], + y: obj.bbox[1], + w: obj.bbox[2] - obj.bbox[0], + h: obj.bbox[3] - obj.bbox[1] + }, self.root)); + } + var geos = obj.geometry.geometries; + var i = 0; + var len = geos.length; + var temp = []; + var g; + while (i < len) { + g = geos[i]; + switch (g.type) { + case 'Point': + temp.push(geoJSON.makeRec({ + x: g.coordinates[0], + y: g.coordinates[1], + w: 0, + h: 0 + })); + break; + case 'MultiPoint': + temp.push(geoJSON.makeRec(bbox(g.coordinates))); + break; + case 'LineString': + temp.push(geoJSON.makeRec(bbox(g.coordinates))); + break; + case 'MultiLineString': + temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([], g.coordinates)))); + break; + case 'Polygon': + temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([], g.coordinates)))); + break; + case 'MultiPolygon': + temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([], Array.prototype.concat.apply([], g.coordinates))))); + break; + case 'GeometryCollection': + geos = geos.concat(g.geometries); + len = geos.length; + break; + } + i++; + } + var first = temp[0]; + i = 1; + len = temp.length; + while (i < len) { + first.expand(temp[i]); + i++; + } + return self.insertSubtree({ + leaf: obj, + x: first.x(), + y: first.y(), + h: first.h(), + w: first.w() + }, self.root); +}; +exports.geoJSON = function (prelim) { + var that = this; + var features, feature; + if (Array.isArray(prelim)) { + features = prelim.slice(); + } + else if (prelim.features && Array.isArray(prelim.features)) { + features = prelim.features.slice(); + } + else if (prelim instanceof Object) { + features = [prelim]; + } else { + throw ('this isn\'t what we\'re looking for'); + } + var len = features.length; + var i = 0; + while (i < len) { + feature = features[i]; + if (feature.type === 'Feature') { + switch (feature.geometry.type) { + case 'Point': + geoJSON.point(feature, that); + break; + case 'MultiPoint': + geoJSON.multiPointLineString(feature, that); + break; + case 'LineString': + geoJSON.multiPointLineString(feature, that); + break; + case 'MultiLineString': + geoJSON.multiLineStringPolygon(feature, that); + break; + case 'Polygon': + geoJSON.multiLineStringPolygon(feature, that); + break; + case 'MultiPolygon': + geoJSON.multiPolygon(feature, that); + break; + case 'GeometryCollection': + geoJSON.geometryCollection(feature, that); + break; + } + } + i++; + } +}; +exports.bbox = function () { + var x1, y1, x2, y2; + switch (arguments.length) { + case 1: + x1 = arguments[0][0][0]; + y1 = arguments[0][0][1]; + x2 = arguments[0][1][0]; + y2 = arguments[0][1][1]; + break; + case 2: + x1 = arguments[0][0]; + y1 = arguments[0][1]; + x2 = arguments[1][0]; + y2 = arguments[1][1]; + break; + case 4: + x1 = arguments[0]; + y1 = arguments[1]; + x2 = arguments[2]; + y2 = arguments[3]; + break; + } + + return this.search({ + x: x1, + y: y1, + w: x2 - x1, + h: y2 - y1 + }); +};