Come memorizzare le coordinate GPS e cercare posti in un raggio da un NOSQL DBMS (come DynamODB)

StackOverflow https://stackoverflow.com//questions/10691547

Domanda

Il mio team ha bisogno di un DBMS come DynamoDB per memorizzare una grande quantità di dati, principalmente luoghi e coordinate. Ho considerato di utilizzare alcuni DBMS basati su GIS (come PostGis) con un indice sul punto, ma DynamoDB sembra eccezionale per il nostro uso.

Qual è il metodo migliore per memorizzare la coordinata e recuperare rapidamente tutti gli oggetti in un determinato raggio?

In PostGis è facile, qualcosa del genere:

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

Come posso fare qualcosa del genere in un DBMS NOSQL?

È stato utile?

Soluzione

Abbiamo avuto lo stesso problema, stiamo usando in particolare AWS e DYNAMODB. Abbiamo risolto questo problema utilizzando il servizio Cloudsearch, ogni volta che memorizziamo alcuni dati "Geo-ricercabili" nel nostro database indicizziamo i dati in un'istanza di cloudsearch con lat, lon come filtri (per fare questo devi fare una trasformazione su Lat e Lon per trasformarlo in un UINT).

Allora diciamo che vuoi fare una ricerca su un particolare Lat / Lon and Radius, calcoli il corrispondente GeoBox (LatMin, Latmax, Lonmin, Lonmax) e interrogano la tua istanza di Cloudsearch con i filtri specifici per recuperare lo schema chiave del tuo Dati, è quindi possibile interrogare DynamODB per ottenere le informazioni.

Alcuni codici in Java per fare solo quanto sopra:

Utilizzo di rettangolariwindows dal pacchetto com.javadocmd.simplelatlng.window da Tyler Coles, calcolando il riquadro di delimitazione e facendo la trasformazione per 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);
.

Allora un esempio di una query sull'istanza Cloudsearch:

http:// [Searchadrl] / 2011-02-01 / Ricerca? BQ= (e Lat: 22300347..22309340 (e lon: 28379282..28391589))

Non sono sicuro che sia la soluzione migliore, ma è quello che siamo venuti

Altri suggerimenti

È possibile utilizzare Geohashing per fare query degli oggetti vicini in base alle stringhe piuttosto che sui calcoli.

Geohash ti consentirà di memorizzare la posizione dei nodi in "secchi" che possono quindi essere interrogati utilizzando le stringhe come portata o chiave di hash in DynamoDB.

Ecco un buon esempio https://github.com/davetroy/geohash-js Fatto in JavaScript che può essere facilmente riscritto in altre lingue.

Attualmente sto cercando questo argomento.Sto usando mongodb (so che hai chiesto DynamoDB, ma hai anche chiesto un utilizzo generale NOSQL) e il mio codice sembra questo:

Struttura record:

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; }
}
.

Collegamento e assicurazione indice:

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

Scrittura:

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

Ricerca:

double[,] points; // define you search coordinates
var items = database.GetCollection<FrameDocument>(collectionName);
var query = Query.WithinPolygon("coordinates.loc", points);
var cursor = items.Find(query);
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top