MySQL ile yarıçapta fermuar alma sorunu


9

Her posta kodu için orta lat, lng içeren posta kodları bir tablo var. Herhangi bir keyfi noktadan belirli bir mil yarıçapı içinde posta kodları listesi almak için kullanın.

Sadece bir fermuarın merkez noktasının belirli bir yarıçap içinde olmaması nedeniyle fermuarın yarıçap içinde olmadığı anlamına gelmedi.

Süper gelişmiş sanat becerilerimi buradaki konuyu göstermek için kullandım:

resim açıklamasını buraya girin

  • Yeşil çizgili lekeler A, B ve C posta kodlarını temsil eder.

  • Kırmızı lekeler, her posta kodu için coğrafi merkezlerdir

  • Fuşya noktası hedef konumdur ve ..

  • Topaklı mavi daire, hedef konumdan 1 mil yarıçaptır

Pembe lekeden 1 mil yarıçap içindeki tüm posta kodları için bir sorgu çalıştırırsam, pembe lekenin kendisi olsa bile, A zipinin merkez noktası bir mil yarıçapı içinde olmadığından, yalnızca B ve C posta kodları döndürülür. açıkça A kodunda.

SELECT *,
        p.distance_unit
                 * DEGREES(ACOS(COS(RADIANS(p.latpoint))
                 * COS(RADIANS(z.y))
                 * COS(RADIANS(p.longpoint) - RADIANS(z.x))
                 + SIN(RADIANS(p.latpoint))
                 * SIN(RADIANS(z.y)))) AS dist
  FROM standard_zip AS z
  JOIN (   /* these are the query parameters */
        SELECT  $lat  AS latpoint,  $lng AS longpoint,
                $miles AS radius,      69 AS distance_unit
    ) AS p ON 1=1
  WHERE z.y
     BETWEEN p.latpoint  - (p.radius / p.distance_unit)
         AND p.latpoint  + (p.radius / p.distance_unit)
    AND z.x
     BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
         AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
  ORDER BY dist

Sonuçlarda zip A'yı içeren bir sorguyu nasıl yazarım?

Gerekirse tabloya ekleyebileceğiniz her posta kodu için uzamsal / geometriye erişimim var, ancak MySQL'de bu amaç için nasıl kullanacağım hakkında hiçbir fikrim yok.


Düzenleme : Mekansal veriler için Oracle ve MySQL belgelerini okumak için bir gün geçirdim ve uzamsal verilerimi MySQL'e başarıyla dönüştürmeyi başardım . Lat ve long yerine geometri sütununu kullanan benzer bir sorguyu yazmaya nasıl devam edebilirim? 2D veri kullanıyorum .. geometri sadece çokgenler ve çokgenler ..

Sanırım bir türlü çözdüm ..

select
  *
from
  (
    select
      MIN(st_distance(geom, POINT(-82.765136, 28.0914015))) * 69 as miles,
      zip
    from
      zip_spatial
    group by
      zip
    order by
      miles asc
  ) d
where
  d.miles < 5

Birisinin daha iyi, daha verimli bir çözümü olması durumunda şimdilik ödülü açık bırakacağım.

Yanıtlar:


7

Gönderen Oracle dizin oluşturma ve sorgulama Mekansal Veri Oracle Spatial Geliştirici Kılavuzu 11g Release 2 (11.2) 'de:

Uzamsal Verileri Sorgulama

Spatial, uzamsal sorguları ve uzamsal birleştirmeleri çözmek için birincil ve ikincil filtre işlemlerine sahip iki katmanlı bir sorgu modeli kullanır. İki katmanlı terimi, sorguları çözmek için iki ayrı işlemin gerçekleştirildiğini belirtir. Her iki işlem de gerçekleştirilirse, kesin sonuç kümesi döndürülür.

Bu tabloda bir uzamsal dizin tanımlanmışsa, sorgudaki uzamsal tablonun adına veritabanı bağlantısı (dblink) adı ekleyemezsiniz.

Mekansal Sorgu

Bir uzamsal R-ağacı indeksinde, her geometri minimum sınırlayıcı dikdörtgeni (MBR) ile temsil edilir. Şekil1'de birkaç nesne içeren aşağıdaki katmanı düşünün. Her nesne, geometri adıyla (çizgi dizesi için geom_1, dört taraflı çokgen için geom_2, üçgen çokgen için geom_3 ve elips için geom_4) ile etiketlenir ve her nesnenin etrafındaki MBR kesikli bir çizgiyle temsil edilir.

Şekil1 MBR'li Geometriler

"Şekil 1 MBR'li Geometriler"

Tipik bir uzamsal sorgu, bir sorgu penceresinde, yani tanımlanmış bir çit veya pencerede bulunan tüm nesneleri istemektir. Dinamik sorgu penceresi, veritabanında tanımlı olmayan ancak kullanılmadan önce tanımlanması gereken dikdörtgen bir alanı belirtir. Şekil2, Şekil 1'dekiyle aynı geometrileri gösterir, ancak ağır noktalı çizgi kutusuyla temsil edilen bir sorgu penceresi ekler.

Şekil2 Sorgu Pencereli Katman

"Şekil2 Sorgu Pencereli Katman" açıklaması

Şekil 2'de, sorgu penceresi geom_1 ve geom_2 geometrilerinin parçalarının yanı sıra geom_3 için MBR'nin bir bölümünü kapsar, ancak gerçek geom_3 geometrisinin hiçbirini kapsamaz. Sorgu penceresi geom_4 geometrisinin veya MBR'sinin herhangi bir bölümünü kapsamaz.

Birincil Filtre Operatörü

SDO_FILTER operatörü, Oracle Spatial sorgu işleme modelinde yer alan iki aşamalı sürecin birincil filtre bölümünü uygular. Birincil filtre, yalnızca bir dizi aday nesne çiftinin etkileşimde bulunup bulunamayacağını belirlemek için dizin verilerini kullanır. Özellikle, birincil filtre, nesnelerin kendilerinin etkileşip etkileşmediğini değil, aday nesnelerin MBR'lerinin etkileşip etkileşmediğini kontrol eder. SDO_FILTER operatör sözdizimi aşağıdaki gibidir:

SDO_FILTER(geometry1 SDO_GEOMETRY, geometry2 SDO_GEOMETRY, param VARCHAR2)

Önceki sözdiziminde:

  • geometry1, bir tabloda SDO_GEOMETRY tipinde bir sütundur. Bu sütun uzamsal olarak dizine eklenmelidir.

  • geometry2, SDO_GEOMETRY türünde bir nesnedir. Bu nesne bir tablodan gelebilir veya gelmeyebilir. Bir tablodan geliyorsa, uzamsal olarak dizine eklenebilir veya eklenmeyebilir.

  • param, VARCHAR2 türünde isteğe bağlı bir dizedir. Min_resolution ve max_resolution anahtar kelimelerinden birini veya her ikisini birden belirtebilir.

Aşağıdaki örnekler yalnızca birincil filtre işlemini gerçekleştirir (ikincil filtre işlemi olmadan). Şekil2'de gösterilen ve sorgu penceresiyle etkileşime giren bir MBR'ye sahip tüm geometrileri döndürürler. Aşağıdaki örneklerin sonucu geom_1, geom_2 ve geom_3 geometrileridir.

Örnek1, sorgu penceresini tabloya eklemeden birincil filtre işlemini gerçekleştirir. Pencere bellekte endekslenecek ve performans çok iyi olacaktır.

Örnek1 Geçici Sorgu Pencereli Birincil Filtre

SELECT A.Feature_ID FROM TARGET A  WHERE sdo_filter(A.shape, SDO_geometry(2003,NULL,NULL,
                                       SDO_elem_info_array(1,1003,3),
                                       SDO_ordinate_array(x1,y1, x2,y2))
                           ) = 'TRUE';   

Örnek1'de, (x1, y1) ve (x2, y2) sorgu penceresinin sol alt ve sağ üst köşeleridir.


1
Harika .. Bu yüzden yarıçapı temsil eden daire geometrisini oluşturmalı ve sonra hangi çokgenlerin kesiştiğini görmeliyim .. ilginç .. bilgi için thx
Bir kez bir ayı güreştim.

Evet ... hadi ... Umarım senin için iyi çalışır.
l.lijith

5

A'yı dahil etmeye yönelik herhangi bir girişim muhtemelen D, E, F, G'yi içerecektir. Sorun, her bir posta kodu alanını tanımlayan kesin bir yol olmadan çözülemez.

Böyle bir veritabanı bulun, sonra SPATIALböyle rasgele çokgenler kullanarak bir dizin oluşturun.


Ben uzamsal verilere ihtiyacım biliyorum (ve ben var, ama bir Oracle tablo ve ben nasıl dönüştürmek hakkında çok fazla bilgi bulamıyorum) .. sorun nasıl veri sorgulama anlamaya.
Bir ayı güreştim.

Yeni kodun performansından memnunsanız, muhtemelen en iyisi budur. Not: Sorgu her zip'e olan mesafeyi listeler, bu nedenle muhtemelen bir optimizasyon potansiyeli yoktur. (Daha iyi kod alırsanız hoş bir sürpriz yapacağım.)
Rick James

Ben de öyle düşünüyorum. Zaman aşımına uğramadan sana ödül vereceğim ve yarısını yine de elde edeceksin .. Sadece ilk olarak başka hangi cevapları alabileceğimi görmek istiyorum.
Bir ayı güreştim.

3

Yanlış yapıyorsun. İlk olarak, mümkünse, Mekansal çözümle önde gelen RDMBS olan PostGIS kullanın.

O zaman bu adımları takip etmek istersiniz.

  1. Nüfus Sayımının TIGER veri kümesinden ZCTA'yı (Posta Kodu Tablolama Alanları) aşağı çekin . Posta kodları kesin olarak bilinmemektedir. Resmi olarak, posta kodları yalnızca USPS tarafından dahili kullanım içindir. Hükümet de dahil olmak üzere herkes onları kullandığından, en yetkili ikinci kaynak ZCTA şekil dosyaları haline geldi.
  2. Bu şekil dosyalarını veritabanınıza aktarın, PostgreSQL ile kolayca kullanabilirsiniz shp2pgsql
  3. İçe aktardığınız geometriyi indeksleyin.

    CREATE INDEX ON census_zcta USING gist (geog);
    ANALYZE census_zcta;
  4. Şekil dosyalarına karşı bir İlgi Çekici Nokta (POI) sorgusu çalıştırın. Davanızdaki ilgi çekici nokta Giriş Kabloları, bu şöyle görünecek,

    SELECT *
    FROM census_zcta AS zcta
      WHERE ST_Intersects( zcta, ST_MakePoint(long,lat)::geog );

ℹ 1609.344 Metre = 1 Mil

MySQL

MySQL ile

  1. Sayım Shapefile için MySQL insert deyimlerinin çıktısını almak için ogr2ogr komutunu kullanın.
  2. MBRIntersectsUzamsal dizini kullanmak için kullanın . Son sorgu aşağıdaki gibi görünmelidir

    SELECT *
    FROM zcta
    WHERE MBRIntersects( geom, Point(long,lat) )
      AND ST_Intersects ( geom, Point(long,lat) );

3
1) Yanlış yaptığımı biliyorum. bu yüzden sordum. 2) Çalıştığım şirket usps dahili posta kodu sınırlarına erişim ödedi. bu proje için doğrudan usps ile çalıştık ve 3) genel olarak OP'nin tamamen farklı bir araç seti kullandığını öne sürmek doğru bir cevap değildir.
Bir ayı güreştim.

1
@iwrestledabearonce Tüm bu şeyleri MySQL 8 ST_DWithinile de yapabilirsinizMBRIntersects
Evan Carroll

1
"usps dahili posta kodu sınırlarına ücretli erişim" Bu ürünün adını biliyor musunuz? AFAIK böyle bir şey yok. (USPS, kod çözme için 2 veri ürünü ve bazı API'ler sunmasına rağmen)
Evan Carroll

1
mysql hakkında bilgi eklediğiniz için teşekkür ederiz. +1. api genel değildir ve herhangi bir web sitesinde listelenmez, aslında uç nokta url'sinin bir etki alanı adı bile yoktur, doğrudan ip adresinden talep ederiz. ancak, sadece api var olduğunu kanıtlamak için bu belgede listelenmiştir (EDDM'ye atıfta bulunduğum 3 tanesi bahsettiğim) usps.com/business/web-tools-apis/archive/…
Bir ayı

1
EDDM / SelectZIP uç noktasını çıkarırsanız bu gerçekten meşru görünüyor. Bu amaçla değil, bu son noktayı bulmak için kudos reklamı yapılır.
Evan Carroll

1

GreatData.com'dan bu veri kümesine göz atın (bunun açık kaynak değil ücretli bir hizmet olduğunu unutmayın).

Zip merkezi yerine nüfus yoğunluğu kullanırlar.

Ve hızlı doğru sonuçlar almak için sql sunucusu uzamsal veri türünü kullanma.

Bu yardımcı olur umarım.


Bu veri kümesi MySQL için mi yoksa sadece SQL Server için mi?
ypercubeᵀᴹ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.