Created
July 7, 2012 00:04
-
-
Save max-mapper/3063504 to your computer and use it in GitHub Desktop.
geohash based spatial index on leveldb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var plumbdb = require('plumbdb') | |
var shp2json = require('shp2json') | |
var tako = require('tako') | |
var geohash = require('geohash').GeoHash | |
var JSONStream = require('JSONStream') | |
var async = require('async') | |
var gju = require('geostuff') | |
var t = tako() | |
t.plumb = plumbdb('data', function(err, db) { | |
t.db = db | |
}) | |
t.route('/', function (req, resp) { | |
if (!req.qs) return resp.end() | |
var lat = +req.qs.lat | |
var lon = +req.qs.lon | |
var radius = +req.qs.radius | |
if (!lat || !lon || !radius) return resp.end() | |
var range = geohashRange(lat, lon, radius) | |
var circle = gju.drawCircle(radius, {type: "Point", coordinates: [lon, lat]}) | |
resp.write('{"rows": [') | |
var sep = "" | |
t.plumb.rangeStream(range[0], range[1]) | |
.on('data', function(key, value) { | |
var hash = geohash.decodeGeoHash(key) | |
var point = {type: "Point", coordinates: [hash.longitude[2], hash.latitude[2]]} | |
if (!gju.pointInPolygon(point, circle)) return | |
resp.write(sep + JSON.stringify(point)) | |
sep = "," | |
}) | |
.on('end', function() { | |
resp.end("]}") | |
}) | |
}) | |
function geohashRange(lat, lon, radius) { | |
var diff = radius / 111034 // convert to degrees | |
diff = diff / 2 // square diameter -> radius | |
var upper = geohash.encodeGeoHash(lat + diff, lon + diff) | |
var lower = geohash.encodeGeoHash(lat - diff, lon - diff) | |
return [lower, upper] | |
} | |
t.route('/upload', function (req, resp) { | |
var parser = JSONStream.parse(['features', /./]) | |
shp2json(req).pipe(parser) | |
var q = queue( | |
store, | |
function(err) { | |
if (err) resp.end(err) | |
resp.end('ok') | |
} | |
) | |
parser.on('data', function(feature) { | |
q.push(feature, function(err) { | |
if (err) console.log(err) | |
}) | |
}) | |
}) | |
function queue(save, cb) { | |
var q = async.queue(save, 1) | |
q.drain = cb | |
return q | |
} | |
function store(feature, cb) { | |
var type = feature.geometry.type | |
if (type === "Polygon") feature = preparePoly(feature) | |
if (type === "Point") feature = preparePoint(feature) | |
cb(false) | |
// t.plumb._store(feature, function(err, json) { | |
// if (err) cb(err) | |
// cb(false, json) | |
// }) | |
} | |
function preparePoly(feature) { | |
var extent = gju.polygonExtent(feature.geometry) | |
console.log('extent', extent) | |
return feature | |
} | |
function preparePoint(feature) { | |
var lat = feature.geometry.coordinates[1] | |
var lon = feature.geometry.coordinates[0] | |
feature._id = geohash.encodeGeoHash(lat, lon) | |
return feature | |
} | |
t.httpServer.listen(8000, function () { | |
console.log('dun runnin') | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment