Jenis data apa untuk lintang dan bujur?

154

Saya pemula untuk PostgreSQL dan PostGIS. Saya ingin menyimpan nilai lintang dan bujur dalam tabel database PostgreSQL 9.1.1. Saya akan menghitung jarak antara dua titik, menemukan titik yang lebih dekat dengan menggunakan nilai lokasi ini.

Jenis data mana yang harus saya gunakan untuk lintang dan bujur?

pengguna1008404
sumber
4
Jika Anda melakukan dua titik (peta lat / 2D 2D), saya akan menggunakan tipe data Geometri. Jika Anda perlu memperkenalkan ketinggian atau kelengkungan bumi dalam kalibrasi jarak Anda, Geografi adalah tujuan yang ingin Anda tuju.
Keduabelas
4
Apakah ada jawaban di bawah ini yang menjawab pertanyaan Anda? Jika demikian, saya mendorong Anda untuk memilih satu sebagai jawabannya :)
Volte

Jawaban:

140

Anda dapat menggunakan tipe data point- gabungan (x,y)yang bisa menjadi lat / panjang Anda. Menempati 16 byte: 2 float8angka secara internal.

Atau buat dua kolom tipe float(= float8atau double precision). Masing-masing 8 byte.
Atau real(= float4) jika presisi tambahan tidak diperlukan. Masing-masing 4 byte.
Atau bahkan numericjika Anda membutuhkan ketelitian mutlak. 2 byte untuk setiap grup yang terdiri dari 4 digit, ditambah overhead 3 - 8 byte.

Baca manual bagus tentang tipe numerik dan tipe geometris .


Tipe geometrydan geographydata disediakan oleh modul tambahan PostGIS dan menempati satu kolom di tabel Anda. Masing-masing menempati 32 byte untuk satu titik. Ada beberapa overhead tambahan seperti SRID di sana. Jenis ini menyimpan (long / lat), bukan (lat / long).

Mulailah membaca manual PostGIS di sini .

Erwin Brandstetter
sumber
5
Saya tidak akan merekomendasikan menggunakan floattipe data. Itu membuat perhitungan dengan koordinat sangat rumit. Anda harus menggunakan PostGIS dan geographytipe data untuk perhitungan seperti itu.
m13r
8
Ini benar-benar manual yang bagus bukan? Contoh cemerlang dalam dokumentasi.
otocan
1
Akankah lebih cepat menyimpan long, lat, dan geog daripada mencoba parse geog untuk lat panjang asli?
Dan
1
@Dan: Tergantung. Silakan tanyakan pertanyaan baru dengan detail. Anda selalu dapat menautkan ini untuk konteks. Komentar bukan tempat untuk pertanyaan baru.
Erwin Brandstetter
40

Di PostGIS, untuk titik dengan lintang dan bujur ada datatype geografi.

Untuk menambahkan kolom:

alter table your_table add column geog geography;

Untuk memasukkan data:

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

4326 adalah ID Referensi Tata Ruang yang mengatakan datanya dalam derajat bujur dan lintang, sama seperti pada GPS. Lebih lanjut tentang itu: http://epsg.io/4326

Urutan adalah Bujur, Lintang - jadi jika Anda memplotnya sebagai peta, itu adalah (x, y)

Untuk menemukan titik terdekat Anda perlu terlebih dahulu membuat indeks spasial:

create index on your_table using gist (geog);

dan kemudian meminta, katakan, 5 paling dekat ke titik tertentu:

select * 
from your_table 
order by geog <-> 'SRID=4326;POINT(lon lat)' 
limit 5;
Darafei Praliaskouski
sumber
1
Klarifikasi SRID 4326 ingin garis bujur lintang dalam urutan itu. Tetapi interpretasi PostGIS tentang SRID 4326 menginginkan garis bujur dalam urutan itu. Contohnya benar untuk penggunaan PostGIS. postgis.net/2013/08/18/tip_lon_lat
hahmed
26

Saya sangat menganjurkan untuk PostGis . Ini spesifik untuk tipe data seperti itu dan memiliki metode di luar kotak untuk menghitung jarak antar titik, di antara operasi GIS lainnya yang dapat Anda temukan berguna di masa depan

tvieira
sumber
5

Jika Anda tidak memerlukan semua fungsionalitas yang ditawarkan PostGIS, Postgres (saat ini) menawarkan modul ekstensi yang disebut earthdistance . Menggunakan tipe data titik atau kubus tergantung pada kebutuhan akurasi Anda untuk perhitungan jarak.

Anda sekarang dapat menggunakan fungsi earth_box untuk -misalnya- permintaan untuk poin dalam jarak tertentu dari lokasi.

Hans Bouwmeester
sumber
2

Dalam PostGIS Geometri lebih disukai daripada Geografi (model pembumian bulat) karena perhitungannya lebih sederhana sehingga lebih cepat. Ini juga memiliki BANYAK fungsi yang lebih banyak tersedia tetapi kurang akurat untuk jarak yang sangat jauh.

Impor CSV Anda ke bidang lat panjang ke DECIMAL(10,6)kolom. 6 digit adalah presisi 10cm, harus banyak untuk kebanyakan kasus penggunaan.

Lalu masukkan data Anda yang diimpor

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;

Verifikasi SRID bukan nol!

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

Validasi urutan parameter panjang lat Anda menggunakan penampil WKT dan ST_AsEWKT(target_table.geom).

Kemudian indeks untuk kinerja terbaik

CREATE INDEX idx_target_table_geom_gist
    ON target_table USING gist(geom);
golfalot
sumber