ฉันเป็นมือใหม่กับ PostgreSQL และ PostGIS ฉันต้องการเก็บค่าละติจูดและลองจิจูดในตารางฐานข้อมูล PostgreSQL 9.1.1 ฉันจะคำนวณระยะทางระหว่างสองจุดหาจุดที่ใกล้กว่าโดยใช้ค่าที่ตั้งนี้
ฉันควรใช้ประเภทข้อมูลใดสำหรับละติจูดและลองจิจูด?
ฉันเป็นมือใหม่กับ PostgreSQL และ PostGIS ฉันต้องการเก็บค่าละติจูดและลองจิจูดในตารางฐานข้อมูล PostgreSQL 9.1.1 ฉันจะคำนวณระยะทางระหว่างสองจุดหาจุดที่ใกล้กว่าโดยใช้ค่าที่ตั้งนี้
ฉันควรใช้ประเภทข้อมูลใดสำหรับละติจูดและลองจิจูด?
คำตอบ:
คุณสามารถใช้ประเภทข้อมูล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 ที่นี่
float
ประเภทข้อมูล มันทำการคำนวณด้วยพิกัดที่ซับซ้อนมาก คุณควรใช้ PostGIS และgeography
ประเภทข้อมูลสำหรับการคำนวณดังกล่าว
ใน 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;
ใน 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);