Вопрос по database – Как хранить координаты GPS и искать места в радиусе от СУБД NoSQL (например, DynamoDB)

7

Моей команде нужна СУБД, такая как DynamoDB, для хранения большого количества данных, главным образом, мест и координат. Я решил использовать некоторые СУБД на основе ГИС (например, PostGIS) с индексом POINT, но DynamoDB, по-видимому, отлично подходит для нашего использования.

What is the best method to store the coordinate and quickly retrieve all objects in a particular radius?

В PostGIS это легко, примерно так:

SELECT *
FROM places
WHERE ST_DWithin(coordinate, ST_GeomFromText('POINT(45.07085 7.68434)', 4326), 100.0);

Как я могу сделать что-то подобное в СУБД NoSQL?

Ваш Ответ

3   ответа
1

что вы просили 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);
5

Мы решили эту проблему, используя CloudSearch Service, каждый раз, когда мы храним некоторые «гео-поиска» Данные в нашей базе данных мы индексируем данные в экземпляре CloudSearch, используя lat, lon в качестве фильтров (для этого вам нужно выполнить преобразование в lat и lon, чтобы превратить его в uint).

Затем предположим, что вы хотите выполнить поиск по определенному широту и долготе, а для радиуса вы вычисляете соответствующий геобокс (latmin, latmax, lonmin, lonmax) и запросите свой экземпляр CloudSearch с помощью специальных фильтров, чтобы получить схему ключей ваших данных. Затем вы можете запросить DynamoDB, чтобы получить информацию.

Некоторый код в Java, чтобы сделать только что выше:

Использование RectangularWindows из пакета com.javadocmd.simplelatlng.window от 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 / search? bq = (и широта: 22300347..22309340 (и lon: 28379282..28391589))

Я не уверен, что это лучшее решение, но это то, что мы придумали

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededforums.aws.amazon.com/ann.jspa?annID=1770
Error: User Rate Limit Exceeded
4

ктам на основе строк, а не расчетов.

Geohash позволит вам сохранить расположение узлов в «корзинах» который затем может быть запрошен с использованием строк в качестве ключа диапазона или хеша в DynamodB.

Вот хороший примерhttps://github.com/davetroy/geohash-js сделано в JavaScript, который может быть легко переписан на других языках.

Похожие вопросы