2009-09-24 7 views
1

Ceci est un poste croix d'un courriel que j'ai envoyé à la liste de diffusion de PostGISDessiner une ligne PostGIS en utilisant la méthode Neighbour la plus proche

Jusqu'à présent, dans mon effort pour créer une ligne entre un point et son projeté emplacement sur une ligne a été longue mais je suis presque là. En date d'hier, et avant d'inclure une analyse du plus proche voisin, j'ai obtenu les résultats présentés dans cette image:

QGis screenshot

Comme vous pouvez le voir, chaque point en rose se connecte à tous les points prévus, alors que , Je veux seulement connecter chaque x rose à sa projection respective. Sur IRC, il a été recommandé d'utiliser BostonGIS's nearest neighbor method. J'ai entré la fonction à PostgreSQL et l'ai essayée sans succès comme indiqué ci-dessous. Je suppose que mon erreur est due au mauvais type de paramètre. J'ai joué avec ça, j'ai changé le type de colonnes en varchar, mais je n'arrive toujours pas à le faire fonctionner.

Des idées sur ce que je fais mal? des suggestions sur la façon de le réparer?

code:

-- 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; 

erreur

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 

Répondre

1

il s'avère que je n'ai pas besoin d'utiliser le plus proche voisin après tout. J'ai assigné un id identique aux centroïdes auxquels je connecte les lignes à travers

-- 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; 
+0

Pourquoi utilisez-vous 'ST_Line_Interpolate_Point'? Ne devrait pas être l'emplacement du point sur la ligne être clair avec 'ST_Line_Locate_Point'? – Stophface

1

Un problème serait que je pense que la fonction attend la second argument (distguess) to be a double precision au lieu d'un nombre entier. Essayez 1000000.0 ou essayez de lancer pour flotter explicitement ...

+0

J'ai essayé les deux et cela n'a pas réparé, mais bravo sur l'avis. – dassouki

+0

Une estimation, mais j'essaierais d'écrire les 'explosed_roads', 'true', 'gid' - partie comme '' exploded_roads '', '' true '', '' gid '' ou 'exploded_roads', 'true' , "gid" ... Utilisez-vous un outil comme pgadmin pour exécuter cette requête? – ChristopheD

+0

J'utilise PgAdmin pour exécuter les requêtes. le 'vrai' renvoie une erreur maintenant: ERREUR: erreur de syntaxe à ou près de "vrai" LIGNE 28: ... the_geom, 1000000.0, 1,1000, "exploded_roads", "true", "g. .. – dassouki