如何将GPS坐标和搜索位置存储在NoSQL DBMS的半径中(如DynamoDB)
-
12-12-2019 - |
题
我的团队需要dynamodb等dbms来存储大量数据,主要是地方和坐标。 我考虑使用一些基于GIS的DBMS(如PRODGIS),并在该点上具有索引,但DynamoDB似乎很好。
存储坐标的最佳方法是什么,快速检索特定半径中的所有对象?
在postgis中,它很容易,如此:SELECT *
FROM places
WHERE ST_DWithin(coordinate, ST_GeomFromText('POINT(45.07085 7.68434)', 4326), 100.0);
.
如何在NoSQL DBMS中做一些这样的事情?
解决方案
我们有同样的问题,我们特别使用AWS和DynamoDB。
我们通过使用CloudSearch服务解决了这个问题,每次在我们的数据库中存储一些“地理可搜索的”数据时,我们将使用Lat,Lon作为过滤器索引CloudSearch实例中的数据(为此,您必须在LAT上进行转换lon将它变成一个uint)。
然后让我们假设要在特定的LAT / LON和RADIUS上进行搜索,您可以计算相应的Geobox(Latmin,Latmax,Lonmin,Lonmax)并使用特定筛选器查询CloudSearch实例以检索您的键模式数据,您可以查询DynamoDB以获取信息。
java中的一些代码只做以上:
从com.javadocmd.simplelatlng.window包的使用rentangularwindows by tyler Coles,计算边界框并进行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);
.
然后在CloudSearch实例上查询的示例:
http:// [searchurl] / 2011-02-01 /搜索?BQ=(和拉特:22300347..22309340(和LON:28379282..28391589))
我不确定它是最好的解决方案,但这就是我们提出的
其他提示
您可以使用Geohash基于字符串而不是计算进行附近对象的查询。
geohash将允许将节点的位置存储到“存储桶”中,然后可以通过使用字符串作为DynamoDB中的范围或散列键查询。
这是一个很好的例子 https://github.com/davetroy/gehash-js 在JavaScript中完成,可以轻松地以其他语言重写。
我目前自己正在研究这个主题。我正在使用MongoDB(我知道你要求你的DynamoDB,但你还要求普通NoSQL使用情况),我的代码如下所示:
记录结构:
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; }
}
.
连接和确保索引:
MongoServer server = MongoServer.Create(connectionString);
MongoDatabase database = server.GetDatabase(databaseName);
database.GetCollection(collectionName).EnsureIndex(IndexKeys.GeoSpatial("coordinates.loc"));
.
写:
var items = database.GetCollection(collectionName);
items.InsertBatch(itemsToInsert);
.
搜索:
double[,] points; // define you search coordinates
var items = database.GetCollection<FrameDocument>(collectionName);
var query = Query.WithinPolygon("coordinates.loc", points);
var cursor = items.Find(query);
. 不隶属于 StackOverflow