sql >> Databasteknik >  >> RDS >> Mysql

Markera alla geospatiala punkter inuti en begränsningsram

Förmodligen x- och y-objekten i din POINT-data i din geometry kolumnen är i grader av latitud och longitud.

För att göra den här sökningen effektivt i MySQL behöver du några saker.

  • En MyISAM-tabell (eller MySQL version 5.7 och senare och antingen InnoDB eller MyISAM)
  • EN INTE NULL-kvalifikation i din geometrikolumn
  • Ett rumsligt index ALTER TABLE flags ADD SPATIAL INDEX (coordinates)
  • Kod för att skapa en textrepresentation av rektangeln du vill söka efter
  • Användning av funktionerna GeomFromText och MBRContains / MBRWithin i din SELECT-sats.

Anta att din lat/lång ruta är en rektangel som är en grads omfattning centrerad kring Winchester Cathedral (51.0606, -1.3131) . Du behöver en begränsningsruta runt den punkten. Den här MySQL-frågan kommer att generera en LINESTRING (text) för en linje som går diagonalt över den begränsningsrutan.

SELECT 
       CONCAT('LINESTRING(',
              latitude-0.5,' ',longitude-0.5,
              ',', 
              latitude+0.5 ,' ',longitude +0.5,
              ')') AS box
   FROM (
      SELECT 51.0606 AS latitude, -1.3131 AS longitude
   ) AS coord

Frågan ger dig detta:

LINESTRING(50.5606 -1.8131,51.5606 -0.8131)

Du kan också använda strängbearbetning på ett värdspråk för att komma fram till en liknande typ av textsträng. Formatet du behöver är detta.

 LINESTRING(lat1 long1, lat2 long2) 

Sedan kan du använda den för att söka i din rumsliga tabell enligt följande:

SELECT whatever, whatever 
  FROM flags
 WHERE MBRContains(
        GeomFromText( 'LINESTRING(50.5606 -1.8131,51.5606 -0.8131)' ),
        flags.coordinates)     

Detta kommer att utnyttja det rumsliga indexet och hitta varje rad med flags vars koordinater ligger inom den diagonala linjens begränsningsram.

Här är lite dokumentation .

Om dina flags tabell innehåller färre än några hundra tusen rader, kan du upptäcka att en vanlig tabell (inte en rumslig tabell) med latitud- och longitudkolumner (FLOAT-datatyper, indexerade) fungerar lika bra och är lättare att utveckla och felsöka.

Jag har skrivit en handledning om den tekniken. http://www.plumislandmedia.net/mysql/haversine-mysql- närmaste-loc/



  1. Bästa praxisfråga för MySQL:beställa efter id eller datum?

  2. Spårning på kolumnnivå och radnivå i sammanslagningsreplikering

  3. RANK, DENSE_RANK och ROW_NUMBER funktioner i Oracle

  4. Komma igång med PostgreSQL 11 på Ubuntu 18.04