Comment stocker GPS Coordonnées et rechercher des endroits dans un rayon d'un SGBD NOSQL (comme DynamoDB)

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

Question

Mon équipe a besoin d'un SGBD comme DynamoDB pour stocker une grande quantité de données, principalement des lieux et des coordonnées. J'ai envisagé d'utiliser des SGBD basés sur SIG (comme PostGis) avec un index sur le point, mais DynamoDB semble super pour notre utilisation.

Quelle est la meilleure méthode pour stocker la coordonnée et récupérer rapidement tous les objets d'un rayon particulier?

en postgis c'est facile, quelque chose comme ceci:

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

Comment puis-je faire quelque chose comme ça dans un SGBD NOSQL?

Était-ce utile?

La solution

Nous avions le même problème, nous utilisons des AWS et DynamoDB en particulier. Nous avons résolu ce problème en utilisant le service de CloudSearch, chaque fois que nous stockons des données «géo-consultables» dans notre base de données, nous indiquons les données d'une instance de CloudSearch avec Lat, Lon sous forme de filtres (pour le faire, vous devez faire une transformation sur la Lat et lon pour le transformer en uint).

Ensuite, disons que vous voulez faire une recherche sur un lat / lon et un rayon particulier, vous calculez la géobox (Latmin, Latmax, Lonmin, Lonmax) et interrogeez votre instance CloudSearch avec les filtres spécifiques pour récupérer le schéma clé de votre Données, vous pouvez ensuite interroger dynamodb pour obtenir les informations.

Certains code en Java pour faire exactement ce qui précède:

Utilisation de rectangularwindows du package COM.JAVADOCMD.SIMPLLNATLNG.Window par Tyler Coles, calculant la boîte de sélection et faire la transformation pour la / 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);

ALORS UN EXEMPLE DE QUESTION SUR LA INSTANCE DE CLOUDSEARCH:

http:// [searchurl] / 2011-02-01 / Recherche? BQ= (et lat: 22300347..22309340 (et lon: 28379282..28391589))

Je ne suis pas sûr que ce soit la meilleure solution, mais c'est ce que nous avons proposé

Autres conseils

Vous pouvez utiliser Geohashing pour faire des requêtes d'objets à proximité basés sur des cordes plutôt que sur des calculs.

Geohash vous permettra de stocker l'emplacement des nœuds dans les "godets" qui peuvent ensuite être interrogés à l'aide de chaînes comme une plage ou une clé de hachage dans DynamoDB.

Voici un bon exemple https://github.com/davetroy/geohashs-js Fait en JavaScript qui peut facilement être réécrit dans d'autres langues.

Je suis en train de rechercher ce sujet moi-même.J'utilise mongodb (je sais que vous avez demandé dynamodb, mais vous avez également demandé une utilisation générale de Nosql) et mon code ressemble à ceci:

Structure d'enregistrement:

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

Connexion et assurant l'index:

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

Écriture:

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

Recherche:

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top