En sol olsun | right | top | kutusunda bulunan dip noktası

1 Cevap php

Ben PostgreSQL veritabanına İlgi (POI), depolama ve Android uygulama PHP script ile onları almak ediyorum. Ben herhangi bir puan anda görüntülenen alanın mahallede varsa benim mobil uygulaması bilmek isteyen internet kullanımını azaltmak için.

Benim fikrim zaten alınan tüm noktaları içeren dikdörtgenin sınırları saklamak için (diğer bir deyişle: Çoğu batı sol (Batı) üzerine yakın nokta zaten alınır, vb zaten alınan en kuzeyde (Kuzey) yukarıdaki yakın nokta) ve ben olacak Ekranın herhangi bir kenarı dışında bu sınırların gittiğinde sonraki sorgu yapmak.

Şu anda ben kullanıyorum (şu anda görüntülenen haritanın kapsadığı alanı) "tek bir ekranda" olan noktaları alabilirsiniz:

SELECT * FROM ch WHERE loc <@ (box '((".-$latSpan.", ".$lonSpan."),(".$latSpan.", ".-$lonSpan."))' + point '".$loc."')

Şimdi ben önümüzdeki dört "daha uzak" puan almak mümkün olacak daha, her yönde dört en uzak noktaları bilmek gerekiyor.

(Belki fonksiyonu "kutu toplam puan" kısmını kullanarak) doğrudan PostgreSQL'den bu puan (veya kutu) almak için herhangi bir olasılık var mı?

1 Cevap

Böylece bazı {ile satır için diğer sütunları bulma problemini azaltarak, operatör mesafe için (<->) en yakın mesafeyi bulmak için MIN toplama işlevi ile birlikte kullanabilirsiniz [(2)]}. Kesinlikle / üst / operatörleri altında (<<, >>, |>>, <<|) sınırlamak için kullanılabilir ve sağ / sol Kutunun bir tarafa sayı. Iki farklı sayı aynı mesafe var olabilir bu yana, 1 satır için limit sonuç olacak. Koveyadinatları aşağı ve (Kuzey ve Doğu artırır yerine harita yönüne göre) sağa artırmak ekran yönünü, varsayarsak, biz olsun:

-- Above, veya Nveyath
SELECT * FROM ch WHERE loc <<| screen AND (loc <-> screen) = (
  SELECT MIN(loc <-> screen) AS mindist FROM ch
    WHERE loc <<| screen
) LIMIT 1

-- Right, veya East
SELECT * FROM ch WHERE loc >> screen AND (loc <-> screen) = (
  SELECT MIN(loc <-> screen) AS mindist FROM ch 
    WHERE loc >> screen
) LIMIT 1

-- Below, veya South
SELECT * FROM ch WHERE loc |>> screen AND (loc <-> screen) = (
  SELECT MIN(loc <-> screen) AS mindist FROM ch
    WHERE loc |>> screen
) LIMIT 1

-- Left, veya West
SELECT * FROM ch WHERE loc << screen AND (loc <-> screen) = (
  SELECT MIN(loc <-> screen) AS mindist FROM ch 
    WHERE loc << screen
) LIMIT 1

Yatay bir yönde en yakın noktası da dikey yönde en yakın nokta olabileceğini not edin; yani, yukarıdaki dört tabloların sendika az dört satır olabilir.

Biz dört yakın puan alabilirsiniz:

SELECT *, (loc <-> screen) AS distance FROM ch 
  WHERE NOT loc <@ screen
  ORDER BY distance
  LIMIT 4

Bununla birlikte, yakın noktalardan bazıları birbirleriyle aynı yönde olabileceğini not edin.

Biz, genel yakın noktası alabilirsiniz

SELECT *, (loc <-> screen) AS distance FROM ch 
  WHERE distance = (
      SELECT MIN(loc <-> screen) AS mindist FROM ch
  )
  LIMIT 1

veya

SELECT *, (loc <-> screen) AS distance FROM ch 
  WHERE NOT loc <@ screen
  ORDER BY distance
  LIMIT 1

When calculating the minimum (veya maximum) of a column, the first would be preferable, since the DBMS could use an index on the column (if any) and not need to scan the table. Since the distance is a calculated value, a table scan is always needed and the queries will have similar perfveyamance. A query analysis might turn up some other reason to prefer a statement, so you should do so befveyae picking an approach.