Cómo almacenar coordenadas GPS y lugares de búsqueda en un radio de un DBMS NOSQL (como Dynamodb)

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

Pregunta

Mi equipo necesita un DBMS como Dynamodb para almacenar una gran cantidad de datos, principalmente lugares y coordenadas. He considerado que usé algunos DBMS basados en GIS (como PostGIS) con un índice en el punto, pero DynDanDB parece ideal para nuestro uso.

¿Cuál es el mejor método para almacenar la coordenada y recuperar rápidamente todos los objetos en un radio particular?

En Postgis es fácil, algo así:

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

¿Cómo puedo hacer algo así en un DBMS NOSQL?

¿Fue útil?

Solución

Tuvimos el mismo problema, estamos usando AWS y Dynamodb en particular. Resolvimos ese problema mediante el uso del servicio de CloudSearch, cada vez que almacenamos algunos datos 'Geo-Searchable' en nuestra base de datos. Indicemos los datos en una instancia de CloudSearch con Lat, Lon como filtros (para hacer esto, tiene que hacer una transformación en Lat y Lon para convertirlo en una uinta).

Luego digamos que desea realizar una búsqueda en un Lat / Lon y Radius en particular, calcule el geobox correspondiente (Longmin, Latmax, Lonmin, Lonmax) y consulta su instancia de CloudSearch con los filtros específicos para recuperar el esquema de la clave de su Datos, puede entonces consultar Dynamodb para obtener la información.

Algún código en Java para hacer lo anterior:

Uso de vientos rectangulares del paquete com.javadocmd.simplelatlng.window por Tyler Coles, calculando el cuadro delimitador y haciendo la transformación para 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);

Entonces, un ejemplo de una consulta en la instancia de CloudSearch:

http:// [sexturl] / 2011-02-01 / Buscar? BQ= (y Lat: 22300347..22309340 (y Lon: 28379282..28391589))

No estoy seguro de que sea la mejor solución, pero eso es lo que vinimos con

Otros consejos

Podría usar GeoHashing para realizar consultas de objetos cercanos basados en cadenas en lugar de cálculos.

GEOHASH le permitirá almacenar la ubicación de los nodos en "cubos" que luego se pueden consultar utilizando cadenas como un rango o la llave de hash en DynDoDB.

Aquí hay un buen ejemplo https://github.com/davetroy/geohash-js hecho en JavaScript que se puede reescribir fácilmente en otros idiomas.

Yo mismo estoy investigando este tema.Estoy usando Mongodb (Sé que solicitó Dynamodb, pero también solicitó el uso general de NOSQL) y mi código se ve así:

estructura de registro:

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

Conexión y garantía del índice:

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

Escritura:

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

Buscando:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top