Połącz przecinające się linie za pomocą PostGIS

15

Jest to coś, o co prawie się wstydzę, ale wydaje mi się, że nie mogę sprawić, by działało przez całe moje życie.

Mam warstwę drogi z odcinkami, każdy odcinek ma odcinek Road IDi type.

Chciałbym połączyć wszystkie segmenty razem, dla każdego z nich Road IDw jedną linię, ale tylko wtedy, gdy są one takie same typei dotykają się (wszystkie linie są przyciągane razem).

wprowadź opis zdjęcia tutaj

Road ID - Type
   1       L
   1       L
   1       T
   1       L
Nathan W.
źródło

Odpowiedzi:

11

Uważam, że poniższy kod jest nieco czystszym rozwiązaniem niż wybrana odpowiedź z kilku powodów. Po pierwsze nie są wymagane żadne połączenia tabel, a zatem nie jest potrzebny dodatek do klauzuli „ON” dla każdego atrybutu ulicy, a po drugie powyższa metodologia może potencjalnie wytwarzać wiele linii, jeśli istnieje wiele niesąsiadujących grup ulic, które mają wszystkie te same wartości atrybutów, podczas gdy ST_Dump zajmuje się tym problemem w tym rozwiązaniu.

SELECT (ST_Dump(geom)).geom AS geom, "road_id", "road_type"
FROM (
    SELECT ST_LineMerge(ST_Union(geom)) AS geom, "road_id", "road_type"
    FROM "RoadCentreLines"
    GROUP BY "road_id", "road_type"
) AS street_union
Grant Humphries
źródło
Moja geometria nie łączy się z żadnym zapytaniem
Luffydude,
@Luffydude chce dostarczyć więcej informacji? Możliwe, że geometria, z którą pracujesz, nie jest wyrównana, co umożliwia scalenie
Grant Humphries,
To działało pięknie dla mnie, aby scalić zestaw danych o drogach na podstawie identyfikatora drogi. To pięknie poradziło sobie z drogami z przerwami (bez linii na odcinkach). Nie jestem OP, ale to świetna odpowiedź. To powinna być zaakceptowana odpowiedź. Dzięki.
jbalk
To najlepsza odpowiedź!
aborruso
6

Wydaje się, że to działa

SELECT a."Road_ID",a."Road_Type", ST_LineMerge(ST_Collect(a.the_geom))
FROM "RoadCentreLines" as a 
LEFT JOIN "RoadCentreLines" as b ON 
ST_Touches(a.the_geom,b.the_geom) 
    AND a."Road_Type" = b."Road_Type" 
    AND a."Road_ID" = b."Road_ID"
GROUP BY ST_Touches(a.the_geom,b.the_geom), a."Road_Type", a."Road_ID"
Nathan W.
źródło
0

Po prostu kulka, ale mogę wymyślić kilka innych rozwiązań. Nie wiem, czy są lepsze czy gorsze, tylko że są inni.

Po pierwsze, jeśli istnieje tylko kilka rodzajów dróg, możesz je wpisać według typu, na przykład:

WITH type As (SELECT "Road_ID" As id WHERE "Road_Type" = 'type')
SELECT ST_LineMerge (ST_Collect(the_geom))
FROM "RoadCentreLines"
WHERE ST_StartPoint(the_geom) && ST_EndPoint(the_geom) IS TRUE
AND "Road_ID" IN (SELECT id FROM type);

Możesz również użyć większości powyższych z Road_Type jako zmienną w pętli FOR, jeśli istnieje kilka typów.

Moja ostatnia myśl dotyczyła scalenia wszystkich geometrii, a następnie wywołania typów dróg za pomocą funkcji ST_Line_Substring ( Link-Link ), ale to w ogóle nie zadziała.

Powodzenia, Rob

rec. thegeom
źródło