postgresql - 使用postGIS添加点和计算英里距离的正确方法

标签 postgresql postgis

我是 PostGIS 的新手,想在我的数据库中为一个新位置创建一个列来存储其纬度和经度(二维点)。稍后我会希望能够找到这两点之间的距离。

看来我可以通过运行以下查询来完成我想要的:

CREATE EXTENSION postgis;

CREATE TABLE places (
    id SERIAL PRIMARY KEY,
    name VARCHAR(500) NOT NULL,
    location geometry NOT NULL
);

INSERT INTO places (name, location)
VALUES ('The Place of Luke', ST_SetSRID(ST_MakePoint(-71.1043443253471, 42.3150676015829),4326)),
('The Place of Bob', ST_SetSRID(ST_MakePoint(-75.1043443253471, 43.3150676015829),4326));

SELECT ST_Distance(
        (SELECT location FROM places WHERE name = 'The Place of Luke'),
        (SELECT location FROM places WHERE name = 'The Place of Bob')
    );

我相信这会正确返回 4.12310562561766 的纬度和经度距离,但我有几个关于最佳实践的问题。

  1. geometry 是我要实现的目标的正确类型吗?我尝试将 geometry 更改为 point:

    CREATE TABLE places (
        id SERIAL PRIMARY KEY,
        name VARCHAR(500) NOT NULL,
        location point NOT NULL
    );
    
    INSERT INTO places (name, location)
    VALUES ('The Place of Luke', ST_MakePoint(-71.1043443253471, 42.3150676015829)),
    ('The Place of Bob', ST_MakePoint(-75.1043443253471, 43.3150676015829));
    
    SELECT ST_Distance(
        (SELECT location FROM places WHERE name = 'The Place of Luke'),
        (SELECT location FROM places WHERE name = 'The Place of Bob')
    );
    

    但我一直收到错误:列“location”是点类型,但表达式是几何类型。我知道 ST_MakePoint 可能正在尝试创建 geometry 类型的东西,这导致了错误,但我该如何创建点类型的东西?

  2. documentation似乎非常坚持我应该使用 AddGeometryColumn() 而不是将列直接添加到我的 places 表,但我不明白为什么以及随着我的应用程序的增长这是否会成为问题。如果我需要做的只是找到两个地方(在二维平面上)之间的距离以计算陆地旅行距离,这对我来说会是个问题吗?
  3. 如何将此结果转换为英里(可能还有公里)。我应该一起运行不同的查询吗?我对经度和纬度的理解使我认为返回的这个数字不会简单地线性转换为英里。

最佳答案

  1. 是的,如果您使用的是 PostGIS,请不要使用 point。 Point 是原生类型。 PostGIS 是一个扩展,可以做你想做的事。如果一切都在 4326 中,您应该查看 geography 类型并使用它。
  2. 切勿使用 AddGeometryColumn(),除非您使用的是 PostGIS 1.x。 PostGIS 2.x 支持类型修饰符,您可以改用 ALTER TABLE
  3. 要使用获取里程,只需返回 km 和 * 0.621371192

这有点奇怪,但很实用。

SELECT ST_Distance(
    (SELECT location FROM places WHERE name = 'The Place of Luke'),
    (SELECT location FROM places WHERE name = 'The Place of Bob')
);

通常,您会在处理批处理的 JOIN 中看到它,但它也可以按照您的预期在相关子查询中使用。

SELECT
  l1.location,
  l2.location,
  ST_Distance( l1.location, l2.location )
FROM location AS l1
JOIN location AS l2
  ON l2.location = 'The Place of Luke'
WHERE places = 'The Place of Bob';

关于postgresql - 使用postGIS添加点和计算英里距离的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41267857/

相关文章:

sql - 触发器postgresql中的距离计算

php - 使用 Laravel 通过 postgis 函数插​​入

java - 如何以编程方式在 Java 中使用渗透导入 OSM 数据?

postgresql - 如何比较两个数组并仅在postgres中选择不匹配的元素

sql - 使用 LIKE 查询数组的 Postgres

django - 在 Django CharFields 中自动截断 max_length 字段

sql - PostgreSQL:将 SQL 查询简化为更短的查询

database - postgres触发器在条件时插入值

两组大点之间的 PostGIS 最小距离

postgresql - Postgis 城市 POLYGON