How to store GPS coordinate and search places in a radius from a NoSQL DBMS (like DynamoDB)

末鹿安然 提交于 2019-12-03 07:21:21

We had the same issue, we're using AWS and DynamoDB in particular. We solved that problem by using CloudSearch Service, every time we store some 'geo-searchable' data in our database we index the data in a CloudSearch instance with lat,lon as filters ( to do this you have to do a transformation on lat and lon to turn it into a uint ).

Then let's say you want to do a search on a particular lat/lon and radius you compute the corresponding geobox ( latmin, latmax , lonmin, lonmax ) and query your CloudSearch instance with the specific filters to retrieve the key schema of your data, you can then query DynamoDB to get the information.

Some code in Java to do just the above :

Using RectangularWindows from the com.javadocmd.simplelatlng.window package by Tyler Coles, computing the bounding box and doing the transformation for lat / lon .

RectangularWindow rectangularWindow = new RectangularWindow(newLatLng(location.getLat().doubleValue(), location.getLon().doubleValue()), radius.doubleValue(), radius.doubleValue(), LengthUnit.KILOMETER);
latMin = (long) ((180 + rectangularWindow.getMinLatitude()) * 100000);     
latMax = (long) ((180 + rectangularWindow.getMaxLatitude()) * 100000);
lonMin = (long) ((360 + rectangularWindow.getLeftLongitude()) * 100000);
lonMax = (long) ((360 + rectangularWindow.getRightLongitude()) * 100000);

Then an example of a query on the CloudSearch instance :

http://[SEARCHURL]/2011-02-01/search?bq=(and lat:22300347..22309340 (and lon:28379282..28391589))

I'm not sure it's the best solution but that's what we came up with

You could use geohashing to do queries of nearby objects based on strings rather than calculations.

Geohash will allow you store the location of nodes into "buckets" which can then be queried by using strings as a range or hash key in dynamodb.

Here is a good example https://github.com/davetroy/geohash-js done in javascript which can easily be rewritten in other languages.

I'm currently researching this subject myself. I'm using MongoDb (I know you asked for DynamoDb, but you also asked for general NoSql usage) and my code looks like this:

record structure:

public class FrameDocument
{
    [BsonId]
    public Guid Id { get; set; }

    [BsonElement("coordinates")]
    public Point[] Polygon { get; set; }
}

public class Point
{
    [BsonElement("name")]
    public string Orientation { get; set; }

    [BsonElement("loc")]
    public double[] Location { get; set; }
}

connecting and ensuring index:

MongoServer server = MongoServer.Create(connectionString);
MongoDatabase database = server.GetDatabase(databaseName);
database.GetCollection(collectionName).EnsureIndex(IndexKeys.GeoSpatial("coordinates.loc"));

writing:

var items = database.GetCollection(collectionName);
items.InsertBatch(itemsToInsert);

searching:

double[,] points; // define you search coordinates
var items = database.GetCollection<FrameDocument>(collectionName);
var query = Query.WithinPolygon("coordinates.loc", points);
var cursor = items.Find(query);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!