Created
August 11, 2012 00:14
-
-
Save max-mapper/3319214 to your computer and use it in GitHub Desktop.
geo queries on leveldb (geohash) (not really usable)
This file contains 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 // my fork (not on npm): https://github.com/maxogden/geohash-js | |
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
Hmmm, interesting - will be watching to see where you go with this :)