ข้อมูลชนิดใดสำหรับละติจูดและลองจิจูด?


154

ฉันเป็นมือใหม่กับ PostgreSQL และ PostGIS ฉันต้องการเก็บค่าละติจูดและลองจิจูดในตารางฐานข้อมูล PostgreSQL 9.1.1 ฉันจะคำนวณระยะทางระหว่างสองจุดหาจุดที่ใกล้กว่าโดยใช้ค่าที่ตั้งนี้

ฉันควรใช้ประเภทข้อมูลใดสำหรับละติจูดและลองจิจูด?


4
หากคุณทำสองจุด (แผนที่ lat / 2D แบบ 2D) ฉันจะใช้ประเภทข้อมูลเรขาคณิต หากคุณต้องการแนะนำระดับความสูงหรือความโค้งของโลกในระยะห่างของคุณภูมิศาสตร์เป็นที่ที่คุณต้องการไป
สิบสอง

4
คำตอบใด ๆ ด้านล่างตอบคำถามของคุณหรือไม่ ถ้าเป็นเช่นนั้นฉันขอแนะนำให้คุณเลือกหนึ่งคำตอบ :)
Volte

คำตอบ:


140

คุณสามารถใช้ประเภทข้อมูลpoint- ผสมผสาน(x,y)ซึ่งสามารถ lat / ยาวของคุณ ตรง 16 ไบต์: 2 float8ตัวเลขภายใน

หรือทำให้เป็นสองคอลัมน์ประเภทfloat(= float8หรือdouble precision) แต่ละ 8 ไบต์
หรือreal(= float4) หากไม่ต้องการความแม่นยำเพิ่มเติม 4 ไบต์ละ
หรือแม้กระทั่งnumericคุณต้องการความแม่นยำแน่นอน 2 ไบต์สำหรับแต่ละกลุ่มของตัวเลข 4 หลักบวกกับ 3 - 8 ไบต์ค่าใช้จ่าย

อ่านคู่มือที่ดีเกี่ยวกับชนิดของตัวเลขและประเภทเรขาคณิต


geometryและgeographyชนิดข้อมูลที่ให้บริการโดยโมดูลเพิ่มเติมPostGISและครอบครองหนึ่งคอลัมน์ในตารางของคุณ แต่ละอันมี 32 ไบต์สำหรับหนึ่งจุด มีค่าใช้จ่ายเพิ่มเติมบางอย่างเช่น SRID อยู่ในนั้น ที่เก็บประเภทเหล่านี้ (ยาว / lat) ไม่ใช่ (lat / ยาว)

เริ่มอ่านคู่มือ PostGIS ที่นี่


5
ฉันจะไม่แนะนำให้ใช้floatประเภทข้อมูล มันทำการคำนวณด้วยพิกัดที่ซับซ้อนมาก คุณควรใช้ PostGIS และgeographyประเภทข้อมูลสำหรับการคำนวณดังกล่าว
m13r

9
มันเป็นคู่มือที่ดีจริง ๆ ใช่ไหม? ตัวอย่างที่ส่องแสงในเอกสารประกอบ
otocan

1
การเก็บ long, lat, และ geog ให้เร็วกว่าการลองแยกวิเคราะห์ geog สำหรับ lat ที่มีความยาวดั้งเดิมหรือไม่
ด่าน

1
@Dan: ขึ้นอยู่กับ กรุณาถามคำถามใหม่พร้อมรายละเอียด คุณสามารถเชื่อมโยงกับบริบทนี้ได้ตลอดเวลา ความคิดเห็นไม่ใช่ที่สำหรับคำถามใหม่
Erwin Brandstetter

40

ใน PostGIS สำหรับจุดที่มีละติจูดและลองจิจูดจะมีประเภทข้อมูลทางภูมิศาสตร์

ในการเพิ่มคอลัมน์:

alter table your_table add column geog geography;

ในการแทรกข้อมูล:

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

4326 คือ ID อ้างอิงเชิงพื้นที่ที่ระบุว่าเป็นข้อมูลในองศาลองจิจูดและละติจูดเหมือนกับใน GPS เพิ่มเติมเกี่ยวกับมัน: http://epsg.io/4326

คำสั่งซื้อคือลองจิจูด, ละติจูด - ดังนั้นถ้าคุณพล็อตมันเป็นแผนที่มันคือ (x, y)

เพื่อหาจุดที่ใกล้เคียงที่สุดคุณต้องสร้างดัชนีเชิงพื้นที่ก่อน:

create index on your_table using gist (geog);

แล้วขอพูด 5 ใกล้เคียงกับจุดที่กำหนด:

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

1
ชี้แจง SRID 4326 ต้องการลองจิจูดลองจิจูดตามลำดับ แต่การตีความของ PostGIS ของ SRID 4326 ต้องการละติจูดลองจิจูดในลำดับนั้น ตัวอย่างถูกต้องสำหรับการใช้งาน PostGIS postgis.net/2013/08/18/tip_lon_lat
hahmed

26

ผมขอสนับสนุนให้PostGIS มันมีความเฉพาะสำหรับประเภทข้อมูลประเภทนั้นและมีวิธีการนอกกรอบเพื่อคำนวณระยะห่างระหว่างจุดในหมู่การดำเนินการ GIS อื่น ๆ ที่คุณสามารถพบว่ามีประโยชน์ในอนาคต


5

ถ้าคุณไม่จำเป็นต้องทุกฟังก์ชันการทำงาน PostGIS ข้อเสนอ Postgres (ในปัจจุบัน) มีโมดูลส่วนขยายที่เรียกว่าearthdistance มันใช้ชนิดข้อมูลจุดหรือลูกบาศก์ขึ้นอยู่กับความถูกต้องของคุณสำหรับการคำนวณระยะทาง

ตอนนี้คุณสามารถใช้ฟังก์ชันearth_boxเพื่อ - สำหรับตัวอย่าง - ค้นหาจุดภายในระยะทางที่ตั้งได้


2

ใน PostGIS Geometry นั้นเป็นที่ต้องการมากกว่า Geography (round earth model) เพราะการคำนวณนั้นง่ายกว่าดังนั้นเร็วกว่ามาก นอกจากนี้ยังมีฟังก์ชั่นที่ใช้งานได้มากมาย แต่มีความแม่นยำน้อยกว่าในระยะทางไกลมาก

นำเข้า CSV ของคุณไปยังเขตข้อมูล Lat ยาวไปยังDECIMAL(10,6)คอลัมน์ 6 หลักคือความแม่นยำ 10 ซม. ควรมีไว้สำหรับกรณีส่วนใหญ่

จากนั้นส่งข้อมูลนำเข้าของคุณ

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 ไม่ใช่ศูนย์!

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

ตรวจสอบคำสั่งของพารามิเตอร์ลาดพร้าวยาวของคุณโดยใช้มุมมอง WKT ST_AsEWKT(target_table.geom)และ

จากนั้นจัดทำดัชนีเพื่อประสิทธิภาพที่ดีที่สุด

CREATE INDEX idx_target_table_geom_gist
    ON target_table USING gist(geom);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.