DBAtlas · Atlas d'exploitation des bases de données

Requête géographique / spatiale

Oracle

-- Oracle Spatial: SDO_GEOMETRY column and spatial index
CREATE INDEX location_sidx ON shop(location)
  INDEXTYPE IS MDSYS.SPATIAL_INDEX;
-- Shops within 5 km:
SELECT name FROM shop
WHERE SDO_WITHIN_DISTANCE(location,
  SDO_GEOMETRY(2001, 4326,
    SDO_POINT_TYPE(32.85, 39.92, NULL), NULL, NULL),
  'distance=5 unit=KM') = 'TRUE';

Oracle Spatial stocke les données géographiques dans le type SDO_GEOMETRY ; une entrée USER_SDO_GEOM_METADATA et un index spatial sont requis. Les opérateurs comme SDO_WITHIN_DISTANCE, SDO_RELATE et SDO_NN répondent aux requêtes de distance/intersection/plus proche voisin. Le SRID 4326 est le système WGS84 (latitude/longitude).

PostgreSQL

-- PostGIS extension:
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE INDEX location_gix ON shop USING GIST (location);
-- Shops within 5 km (geography, meters):
SELECT name FROM shop
WHERE ST_DWithin(location,
  ST_SetSRID(ST_MakePoint(32.85, 39.92), 4326)::geography,
  5000);

PostGIS fait de PostgreSQL une base spatiale complète. Il fournit les types geometry (planaire) et geography (sphérique) et des centaines de fonctions ST_ telles que ST_Distance/ST_DWithin/ST_Intersects/ST_Contains. Un index GiST/SP-GiST accélère les requêtes spatiales.

MySQL

-- Spatial column (with SRID) and SPATIAL index:
ALTER TABLE shop MODIFY location POINT NOT NULL SRID 4326;
ALTER TABLE shop ADD SPATIAL INDEX (location);
-- Compute distance (meters, geography):
SELECT name,
  ST_Distance(location,
    ST_SRID(POINT(32.85, 39.92), 4326)) AS distance
FROM shop
ORDER BY distance LIMIT 10;

MySQL (5.7+) prend en charge les types de données spatiales conformes OGC (POINT, POLYGON, etc.) et les fonctions ST_. Un index SPATIAL (R-tree) ne peut être créé que sur InnoDB/MyISAM et sur des colonnes NOT NULL ; pour que l'optimiseur l'utilise, la colonne doit être définie avec un attribut SRID (SRID 4326). Avec SRID 4326, ST_Distance renvoie la distance géodésique en mètres. Avec POINT(x, y) + ST_SRID, x est la longitude et y la latitude ; pour une entrée WKT (ST_GeomFromText) avec SRID 4326, l'ordre est latitude-longitude.

SQL Server

-- geography type and spatial index:
CREATE SPATIAL INDEX location_sidx ON dbo.shop(location);
-- Shops within 5 km (STDistance returns meters):
SELECT name FROM dbo.shop
WHERE location.STDistance(
  geography::Point(39.92, 32.85, 4326)) <= 5000;

SQL Server propose deux types spatiaux : geography (sphérique, latitude/longitude) et geometry (planaire). Des méthodes comme STDistance, STIntersects et STContains répondent aux requêtes. Un index spatial (basé sur une grille) améliore les performances. Attention à l'ordre des arguments de geography::Point(latitude, longitude, SRID).

MongoDB

// 2dsphere index (for GeoJSON):
db.shop.createIndex({ location: "2dsphere" })
// Shops nearest to a given point ($near):
db.shop.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [32.85, 39.92] },
      $maxDistance: 5000
    }
  }
})

MongoDB stocke les données géographiques au format GeoJSON et exécute des requêtes sphériques avec un index 2dsphere. Les opérateurs $near (tri par distance), $geoWithin (dans une zone) et $geoIntersects sont pris en charge. Les coordonnées sont dans l'ordre [longitude, latitude] ; $maxDistance est en mètres.

Redis

# Built-in geospatial commands (built on sorted sets):
GEOADD shops 32.85 39.92 "kizilay"
GEOADD shops 32.86 39.93 "cankaya"
# Search within 5 km of a point:
GEOSEARCH shops FROMLONLAT 32.85 39.92
  BYRADIUS 5 km ASC

Redis stocke les positions géographiques dans un sorted set avec GEOADD (longitude latitude membre). GEOSEARCH (Redis 6.2+, qui remplace l'ancien GEORADIUS) renvoie les membres situés dans un rayon ou un rectangle, triés par distance. GEODIST donne la distance entre deux points. C'est une fonctionnalité de base ; aucun module n'est nécessaire.

Elasticsearch

# Map the field as geo_point:
PUT shop
{ "mappings": { "properties": { "location": { "type": "geo_point" } } } }
# Query within 5 km:
GET shop/_search
{ "query": { "geo_distance": {
  "distance": "5km",
  "location": { "lat": 39.92, "lon": 32.85 } } } }

Elasticsearch prend en charge les types de champs geo_point (point) et geo_shape (polygone/ligne). Le filtrage se fait avec les requêtes geo_distance (rayon), geo_bounding_box (rectangle) et geo_polygon ; le tri avec geo_distance, et l'agrégation avec geohash_grid/geotile_grid. Les coordonnées sont données en lat/lon ou sous forme de tableau [lon, lat].

Ouvrir dans DBAtlas →