Enlem ve boylam için hangi veri türü?


154

PostgreSQL ve PostGIS'e yeni başladım. Enlem ve boylam değerlerini PostgreSQL 9.1.1 veritabanı tablosunda saklamak istiyorum. İki nokta arasındaki mesafeyi hesaplayacağım, bu konum değerlerini kullanarak daha yakın noktaları bulacağım.

Enlem ve boylam için hangi veri türünü kullanmalıyım?


4
İki nokta (2D enlem / boylam haritası) yapıyorsanız, Geometri veri türünü kullanırdım. Mesafe hesaplarınızda dünyanın yüksekliğini veya eğriliğini tanıtmanız gerekiyorsa, Coğrafya gitmek istediğiniz yerdir.
Onikinci

4
Aşağıdaki cevaplardan herhangi biri sorunuza cevap verdi mi? Eğer öyleyse, cevap olarak birini seçmenizi tavsiye ederim :)
Volte

Yanıtlar:


140

Veri türünüzü kullanabilirsiniz point- birleştirmeler (x,y)enlem / boylamınız olabilir. 16 bayt: float8dahili olarak 2 sayı.

Veya iki tür sütun float(= float8veya double precision) yapın. Her biri 8 bayt.
Veya real(= float4) ek hassasiyet gerekmiyorsa. Her biri 4 bayt.
Veya numericmutlak hassasiyete ihtiyacınız olsa bile . 4 basamaklı her grup için 2 bayt artı 3 - 8 bayt ek yükü.

Sayısal türler ve geometrik türler hakkındaki ince el kitabını okuyun .


geometryVe geographyveri türleri ek modül tarafından sağlanan PostGIS ve işgal tek Tablonuzdaki sütunu. Her biri bir nokta için 32 bayt kaplar. Orada bir SRID gibi ek yük var. Bu türler depolanır (uzun / lat), değil (lat / uzun).

PostGIS kılavuzunu buradan okumaya başlayın .


5
Ben floatveri türü kullanmanızı tavsiye etmem . Koordinatlarla hesaplamayı çok karmaşık hale getirir. Bu geographytür hesaplamalar için PostGIS ve veri tipini kullanmalısınız .
m13r

9
Gerçekten güzel bir el kitabı değil mi? Dokümantasyonda parlayan bir örnek.
otocan

1
Orijinal uzun lat için geog ayrıştırmayı denerken uzun, lat ve geog'yi depolamak daha hızlı olur mu?
Dan

1
@ Dan: Bağlıdır. Lütfen ayrıntılarla birlikte yeni bir soru sorun . Bağlam için her zaman buna bağlayabilirsiniz. Yorumlar yeni soruların yeri değildir.
Erwin Brandstetter

40

PostGIS'te, enlem ve boylamlı noktalar için coğrafya veri türü vardır.

Sütun eklemek için:

alter table your_table add column geog geography;

Veri eklemek için:

insert into your_table (geog) values ('SRID=4326;POINT(longitude latitude)');

4326, GPS'deki gibi derece boylam ve enlem cinsinden veri olduğunu söyleyen Mekansal Referans Kimliği'dir. Bununla ilgili daha fazla bilgi: http://epsg.io/4326

Sıra Boylam, Enlem - yani harita olarak çizerseniz (x, y) olur.

En yakın noktayı bulmak için önce uzamsal dizin oluşturmanız gerekir:

create index on your_table using gist (geog);

ve daha sonra belirli bir noktaya en yakın 5'i talep edin:

select * 
from your_table 
order by geog <-> 'SRID=4326;POINT(lon lat)' 
limit 5;

1
Açıklama SRID 4326, bu sırada enlem boylamını ister. Ancak PostGIS'in SRID 4326'yı yorumlaması, bu sırada boylam enlemi ister. PostGIS kullanımı için örnek doğrudur. postgis.net/2013/08/18/tip_lon_lat
hamedmed

26

PostGis'i şiddetle savunuyorum . Bu tür bir veri tipine özeldir ve gelecekte yararlı bulabileceğiniz diğer CBS işlemleri arasında noktalar arasındaki mesafeyi hesaplamak için kutudan çıkmış yöntemleri vardır.


5

PostGIS'in sunduğu tüm işlevlere ihtiyacınız yoksa, Postgres (günümüzde) earthdistance adlı bir genişletme modülü sunmaktadır . Mesafe hesaplamaları için doğruluk gereksinimlerinize bağlı olarak nokta veya küp veri türünü kullanır .

Artık bir konumun belirli bir mesafesindeki noktalar için -örnek- sorgulamak için earth_box işlevini kullanabilirsiniz .


2

PostGIS'te Geometri Coğrafya'ya (yuvarlak dünya modeli) tercih edilir, çünkü hesaplamalar çok daha basittir, bu nedenle daha hızlıdır. Ayrıca çok daha fazla fonksiyona sahiptir, ancak çok uzun mesafelerde daha az doğrudur.

CSV'nizi uzun lat alanlarına DECIMAL(10,6)sütunlara aktarın . 6 basamak 10cm hassasiyettedir, çoğu kullanım durumunda bol olmalıdır.

Ardından içe aktarılan verilerinizi yayınlayın

SELECT 
    --ST_SetSRID(ST_Point(long, lat),4326) geom -- the wrong way because SRID not set in geometry_columns table
    ST_Point(long, lat)::geometry(Geometry, 4326) geom
INTO target_table
FROM source_table;

SRID'nin sıfır olmadığını doğrulayın!

SELECT * FROM public.geometry_columns WHERE f_table_name = 'target_table';

WKT görüntüleyici ve ile uzun lat parametrenizin sırasını doğrulayın ST_AsEWKT(target_table.geom).

Ardından en iyi performans için dizine ekleyin

CREATE INDEX idx_target_table_geom_gist
    ON target_table USING gist(geom);
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.