Desenhar uma linha no PostGIS usando vizinho mais próximo Método
-
16-09-2019 - |
Pergunta
Este é um post cruz a partir de um e-mail que enviei para a lista de discussão PostGIS
Até agora, em meu esforço para criar uma linha entre um ponto e sua projetada localização em uma linha foi longa, mas estou quase lá. A partir de ontem, e antes de incluir qualquer análise vizinho mais próximo, eu tenho os resultados mostrados na esta imagem:
Como você pode ver, cada ponto-de-rosa está se conectando todos os pontos projetados, enquanto, eu só quero para conectar cada rosa x para sua respectiva projeção.
No IRC, foi recomendado que eu uso de BostonGIS mais próximo método vizinho . I inputed a função para PostgreSQL e tentou fazê-lo, sem sucesso, conforme descrito abaixo. Estou assumindo que o meu erro é devido o tipo de parâmetro errado. Eu brinquei com isso, mudou algumas do tipo das colunas para varchar, mas ainda não posso fazê-lo funcionar.
Algumas ideias sobre o que estou fazendo de errado? alguma sugestão sobre como corrigi-lo?
Código:
-- 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;
ERRO
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
Solução 2
não é que eu não preciso usar vizinho mais próximo depois de tudo. Eu atribuído um ID idênticos aos centroids a que eu estou conectando as linhas através
-- 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;
Outras dicas
Um problema seria que eu acho que a função espera que o segundo argumento (distguess) para ser um precisão dupla em vez de um inteiro. Tente 1.000.000,0 ou tentar lançar a flutuar explicitamente ...