【问题标题】:Drawing a line in PostGIS using Nearest Neighbour Method使用最近邻法在 PostGIS 中绘制一条线
【发布时间】:2009-09-24 19:58:07
【问题描述】:

这是我发送到 PostGIS 邮件列表的电子邮件中的交叉帖子

到目前为止,我一直在努力在一个点和它的投影之间创建一条线 位置在一条线上已经很长了,但我快到了。截至昨天,和 在包括任何最近邻分析之前,我得到的结果显示在 这张图片:

如您所见,粉红色的每个点都连接到所有投影点,而我只想将每个粉红色 x 连接到其各自的投影。

在 IRC 上,建议我使用 BostonGIS's nearest neighbor method。我将函数输入到 PostgreSQL 并尝试失败,如下所述。我假设我的错误是由于错误的参数类型造成的。我对此进行了尝试,将某些列的类型更改为 varchar,但仍然无法正常工作。

关于我做错了什么有什么想法吗?关于如何解决它的任何建议?

代码:

-- this sql script creates a line table that connects points 

-- convert multi lines into lines

CREATE TABLE exploded_roads AS
SELECT the_geom
FROM (
    SELECT ST_GeometryN(
    the_geom,
    generate_series(1, ST_NumGeometries(the_geom)))
    AS the_geom 
    FROM "StreetCenterLines"
)
AS foo;


-- Create line table that'll connect the centroids to the projected points on exploded lines
CREATE TABLE lines_from_centroids_to_roads (
    the_geom    geometry,
    edge_id SERIAL
);

-- Populate Table
INSERT INTO lines_from_centroids_to_roads ( the_geom )
SELECT
    ST_MakeLine(
        centroids.the_geom,
        (pgis_fn_nn(centroids.the_geom, 1000000, 1,1000, 'exploded_roads' ,'true', 'gid',
            ST_Line_Interpolate_Point(
                exploded_roads.the_geom,
                ST_Line_Locate_Point(
                    exploded_roads.the_geom,
                    centroids.the_geom
                )
            )
        )).*
    )
FROM exploded_roads, fred_city_o6_da_centroids centroids;

DROP TABLE exploded_roads;

错误

NOTICE:  CREATE TABLE will create implicit sequence "lines_from_centroids_to_roads_edge_id_seq" for serial column "lines_from_centroids_to_roads.edge_id"

ERROR:  function pgis_fn_nn(geometry, integer, integer, integer, unknown, unknown, unknown, geometry) does not exist
LINE 28:   (pgis_fn_nn(centroids.the_geom, 1000000, 1,1000, 'exploded...
            ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.


********** Error **********

ERROR: function pgis_fn_nn(geometry, integer, integer, integer, unknown, unknown, unknown, geometry) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 584

【问题讨论】:

    标签: sql postgresql postgis nearest-neighbor


    【解决方案1】:

    一个问题是我认为该函数需要second argument (distguess) to be a double precision 而不是整数。尝试 1000000.0 或尝试强制转换为明确浮动...

    【讨论】:

    • 我都试过了,但都没有解决,但对通知表示敬意。
    • 一个猜测,但我会尝试写 'exploded_roads' ,'true', 'gid' - 部分为 ''exploded_roads'' ,''true'', ''gid'' 或"exploded_roads" ,"true", "gid"... 您是否使用 pgadmin 之类的工具来运行此查询?
    • 我正在使用 PgAdmin 运行查询。 '' true '' 现在返回错误:错误:在“true”或附近出现语法错误 第 28 行:...the_geom, 1000000.0, 1,1000, "exploded_roads" , ''true'', "g...
    • 出现该错误,我尝试将 ''true'' 更改为 'true' "true" 没有白费。我还尝试将“true”更改为“DAUID”>0“(质心中的字段之一)
    【解决方案2】:

    事实证明,我根本不需要使用最近邻。我分配了一个与我连接线的质心相同的 id

    -- this sql script creates a line table that connects points 
    
    -- delete existing tables if they exist
    DROP TABLE exploded_roads;
    DROP TABLE projected_points;
    DROP TABLE lines_from_centroids_to_roads;
    
    
    -- convert multi lines into lines
    CREATE TABLE exploded_roads (
        the_geom    geometry,
        edge_id     serial
    );
    
    -- insert the linestring that don't need to be converted
    INSERT INTO exploded_roads
    SELECT the_geom
    FROM "StreetCenterLines"
    WHERE st_geometrytype(the_geom) = 'ST_LineString';
    
    
    INSERT INTO exploded_roads
    SELECT the_geom
    FROM (
        SELECT ST_GeometryN(
        the_geom,
        generate_series(1, ST_NumGeometries(the_geom)))
        AS the_geom 
        FROM "StreetCenterLines"
    )
    AS foo;
    
    
    
    
    
    -- create projected points table with ids matching centroid table
    CREATE TABLE projected_points (
        the_geom    geometry,
        pid     serial,
        dauid       int
    );
    
    
    -- Populate Table
    INSERT INTO projected_points(the_geom, dauid)
    SELECT DISTINCT ON ("DAUID")
        ( 
            ST_Line_Interpolate_Point(
                exploded_roads.the_geom,
                ST_Line_Locate_Point(
                    exploded_roads.the_geom,
                    centroids.the_geom
                )
            )
        ),
        (centroids."DAUID"::int)
    
    FROM exploded_roads, fred_city_o6_da_centroids centroids;
    
    
    -- Create Line tables
    CREATE TABLE lines_from_centroids_to_roads (
        the_geom    geometry,
        edge_id SERIAL
    );
    
    
    -- Populate Line Table
    INSERT INTO lines_from_centroids_to_roads(
    SELECT
        ST_MakeLine( centroids.the_geom, projected_points.the_geom )
    FROM projected_points, fred_city_o6_da_centroids centroids
    WHERE projected_points.dauid = centroids."DAUID"::int
    );
    
    -- Delete temp tables
    --DROP TABLE exploded_roads;
    --DROP TABLE projected_points;
    

    【讨论】:

    • 你为什么使用ST_Line_Interpolate_Point?线上点的位置不应该用ST_Line_Locate_Point明确吗?
    猜你喜欢
    • 2016-04-19
    • 2013-08-07
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    相关资源
    最近更新 更多