sql >> Databáze >  >> RDS >> Oracle

Oracle prostorové vyhledávání na dálku

Máte tam docela dobrou referenci pro vyhledávání vzdálenosti mySQL.

Zapomeňte na věci Oracle Spatial. Příliš mnoho kódu, příliš mnoho složitosti, nedostatečná přidaná hodnota.

Zde je dotaz, který vám pomůže. Toto používá vzdálenosti v mílích podle zákona. UPRAVIT Toto opravuje chybu zmíněnou mdarwinem za cenu kontroly rozdělení, pokud se pokusíte použít pro umístění na severním nebo jižním pólu.

  SELECT id, city, LATITUDE, LONGITUDE, distance
    FROM
  (
    SELECT id, 
           city, 
           LATITUDE, LONGITUDE,
           (3959 * ACOS(COS(RADIANS(LATITUDE)) 
                 * COS(RADIANS(mylat)) 
                 * COS(RADIANS(LONGITUDE) - RADIANS(mylng)) 
                 + SIN(RADIANS(LATITUDE)) 
                 * SIN(RADIANS(mylat)) 
               ))
           AS distance,
           b.mydst
      FROM Cities
      JOIN (
        SELECT :LAT AS mylat,
               :LONG AS mylng,
               :RADIUS_LIMIT AS mydst
          FROM DUAL
      )b ON (1 = 1)
     WHERE LATITUDE >=  mylat -(mydst/69)
       AND LATITUDE <=  mylat +(mydst/69)
       AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
       AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
  )a
   WHERE distance <= mydst
   ORDER BY distance

Pokud pracujete v kilometrech, změňte mydst/69 na mydst/111,045 a změňte 3959 na 6371,4. (1/69 převádí míle na stupně; 3959 je hodnota pro poloměr planety.)

Nyní budete pravděpodobně v pokušení použít tento velký dotaz jako „kouzelnou černou skříňku“. Nedělej to! Není těžké to pochopit, a pokud to pochopíte, budete moci dělat lepší práci. Tady je to, co se děje.

Tato klauzule je srdcem toho, co dělá dotaz rychlým. Vyhledá ve vaší tabulce měst města v okolí do bodu, který jste zadali.

     WHERE LATITUDE >=  mylat -(mydst/69)
       AND LATITUDE <=  mylat +(mydst/69)
       AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
       AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))

Aby to fungovalo, určitě potřebujete index ve sloupci LATITUDE. Trochu pomůže i index ve vašem sloupci LONGITUDE. Provádí přibližné vyhledávání, hledá řádky, které se nacházejí v kvazi pravoúhlém poli na povrchu Země poblíž vašeho bodu. Vybírá příliš mnoho měst, ale ne příliš mnoho.

Tato klauzule vám umožňuje odstranit další města z vaší sady výsledků:

   WHERE distance <= mydst

Tato klauzule je havrsinovým vzorcem, který vypočítává vzdálenost po velkém kruhu mezi každým městem a vaším bodem.

           (3959 * ACOS(COS(RADIANS(LATITUDE)) 
                 * COS(RADIANS(mylat)) 
                 * COS(RADIANS(LONGITUDE) - RADIANS(mylng)) 
                 + SIN(RADIANS(LATITUDE)) 
                 * SIN(RADIANS(mylat)) 

Tato klauzule vám umožňuje zadat bod a limit poloměru pouze jednou jako vázané proměnné k vašemu dotazu. Je to užitečné, protože různé vzorce používají tyto proměnné vícekrát.

        SELECT :LAT AS mylat,
               :LONG AS mylng,
               :RADIUS_LIMIT AS mydst
          FROM DUAL

Zbytek dotazu jednoduše uspořádá věci, takže můžete vybírat a objednávat podle vzdálenosti.

Zde je úplnější vysvětlení:http://www.plumislandmedia.net /mysql/haversine-mysql-nearest-loc/



  1. Jaký je nejlepší způsob, jak snížit počet dotazů, když má třída DAO metody, které používají stejný výsledek?

  2. PHP a Oracle - oci_connect() ORA-12705:Nelze získat přístup k datovým souborům NLS

  3. Načíst celý řádek, ale chybí první záznam

  4. automatické dělení databáze mysql