Tengo que crear buffers disueltos a partir de características de entrada multipunto. En el siguiente ejemplo, la tabla de entrada contiene 4 características. La característica #2
consta de dos geometrías de puntos. Después de crear un búfer, obtengo 4 geometrías de polígonos:
¿Hay alguna forma de agrupar el resultado? Los búferes de los puntos #1
y #2
se disuelven y deben ser una sola característica de múltiples polígonos ( a
).
Lo que he hecho hasta ahora:
-- collect all buffers to a single multi-polygon feature
-- dissolve overlapping polygon geometries
CREATE TABLE public.pg_multibuffer AS SELECT
row_number() over() AS gid,
sub_qry.*
FROM (SELECT
ST_Union(ST_Buffer(geom, 1000, 8))::geometry(MultiPolygon, /*SRID*/) AS geom
FROM
public.multipoints)
AS sub_qry;
EDITAR:
-- create sample geometries
CREATE TABLE public.multipoints (
gid serial NOT NULL,
geom geometry(MultiPoint, 31256),
CONSTRAINT multipoints_pkey PRIMARY KEY (gid)
);
CREATE INDEX sidx_multipoints_geom
ON public.multipoints
USING gist
(geom);
INSERT INTO public.multipoints (gid, geom) VALUES
(1, ST_SetSRID(ST_GeomFromText('MultiPoint(12370 361685)'), 31256)),
(2, ST_SetSRID(ST_GeomFromText('MultiPoint(13520 360880, 19325 364350)'), 31256)),
(3, ST_SetSRID(ST_GeomFromText('MultiPoint(11785 367775)'), 31256)),
(4, ST_SetSRID(ST_GeomFromText('MultiPoint(19525 356305)'), 31256));
Respuestas:
Comenzando con algunos puntos aleatorios, en un intento de imitar aquellos en la imagen del OP, donde los dos primeros se cruzan espacialmente, luego el segundo y el tercero tienen el mismo id de atributo (2), con un par de otros puntos que ni se cruzan espacialmente ni tienen Con el mismo atributo, la siguiente consulta produce 3 grupos:
Aquí hay varios pasos:
ST_Union
, agrupación por id, al primer grupo por atributoST_ClusterIntersecting
para combinar aquellos del mismo grupo que se cruzan espacialmenteEs bastante largo, pero funciona (y estoy seguro de que hay un camino más corto).
El uso de la herramienta WKT en QGIS (y descubrir lo horrible que soy con las herramientas de edición) produce grupos como el siguiente, donde puede ver que el grupo que está etiquetado como a, está todo junto, es decir, un color.
Si coloca un ST_AsText alrededor de la final, ST_UNION (d.geom), puede ver los resultados directamente.
EDITE después de más información en los comentarios: a medida que comience con los puntos, deberá incorporar el búfer en mi solución original, que puse en el CTE temporal al principio para imitar su diagrama. Sería más fácil agregar el búfer en las uniones CTE, para que pueda hacer todas las geometrías a la vez. Entonces, usando una distancia de búfer de 1000, como ejemplo, lo siguiente ahora devuelve 3 grupos, como se esperaba.
fuente
ST_SetSRID
,ST_Multi
y::geometry(Multipolygon, /*SRID*/)
, pero por el momento no funciona.Una forma de hacer esto es
ST_Union
uniendo todos los búferes,ST_Dump
el resultado para obtener los componentes del polígono resultante, y unirse deST_Intersects
nuevo a los puntos de entrada para descubrir cuántos / qué puntos formaron cada grupo.Esto se puede hacer sin requerir una unión al agrupar los puntos antes de llamar
ST_Buffer
. Para que dos puntos se ubiquen dentro del mismo búfer disuelto, deben ser accesibles mediante saltos entre puntos de una distancia menor queeps
. Este es solo un problema de agrupamiento de vinculación mínima, que se puede resolver usandoST_ClusterDBSCAN
:Tenga en cuenta que esto no producirá exactamente el mismo resultado que el método de primero en el búfer, porque los búferes PostGIS no son círculos perfectos y dos puntos separados 1000 m pueden no estar conectados por dos búferes de 500 m.
fuente
Según esta respuesta , desea hacer ST_DUMP dentro de su subconsulta.
Algo como esto:
La razón es que
ST_UNION
devuelve un multipolígono disuelto de todas las características, y loST_DUMP
divide en las características individuales del polígono (que se disolvieron).fuente
ST_Multi((ST_Dump(ST_Union(ST_Buffer(geom, 1000, 8)))).geom)::geometry(MultiPolygon, /*SRID*/) AS geom
, pero esto crea 4 funciones en lugar de 3.GROUP_BY
antes que túST_UNION
.