2014-10-29 90 views
1

我有一个PostgreSQL表看起来像:生成单KML用于PostgreSQL的多个几何形状/ PostGIS的

CREATE TABLE area 
(
    area_code character varying(10) NOT NULL, 
    shape geometry NOT NULL, 
    CONSTRAINT pk_area PRIMARY KEY (area_code) 
) 

且对几何列的索引。

我想写一个函数传递一个area_code的数组,并返回一个表示这些区域的组合KML的值。要返回KML,我使用ST_AsKML。要合并所有区域,我使用ST_UNION。为了确保联盟返回一个单一的几何体而不是集合,我使用ST_MULTI。这一切都让我:

SELECT ST_AsKML(ST_MULTI(ST_UNION(shape))) as KML 
FROM area 
WHERE area_code = ANY(thearray) 

当的pgAdmin III运行此我得到的错误:

ERROR: lwgeom_to_kml2: 'GeometryCollection' geometry type not supported SQL state: XX000 Context: SQL function "st_askml" statement 1

但据我所看到的这不应该发生。 ST_MULTI应确保传递给ST_AsKML的值不是GeometryCollection。我的方法是否正确,但需要修复,还是完全使用错误的技术来生成KML?

回答

1

如果您ST_Union操作产生PointsLinestrings,由于某种原因,这可能发生,或者如果你有几何类型的混合物在输入ST_Union,即不是多边形或MultiPolygons等。如在Google KML docs中所述,KML不支持GeometryCollections

您可以通过调用ST_Union两次来解决此问题,使用ST_Dump将联合几何拆分开,只从第一个联合(转储)中选择生成Polygons或MultiPolygons的几何 - 您可以组合而不生成GeometryCollection。您需要两次使用ST_Union,就像在一个Polygon和MultiPolygon上使用ST_Collect一样,您将再次获得一个GeometryCollection。

WITH polygons (geom) as 
    (SELECT (ST_Dump(ST_Union(shape))).geom 
     FROM area 
     WHERE area_code = any(thearray)) 
    SELECT ST_AsKML(ST_Multi(ST_Union(geom))) as KML 
     FROM polygons 
     WHERE ST_GeometryType(geom) in ('ST_Polygon','ST_MultiPolygon'); 

你可以看到问题ST_Multi,通过运行下面的查询,试图做多几何了点和线串的:

SELECT 
    ST_AsText(
     ST_Multi(
     ST_Union(
      ST_MakePoint(0,0), 
      ST_MakeLine(ST_MakePoint(5,5), ST_MakePoint(10,10)) 
     ) 
    ) 
); 

返回GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(5 5,10 10))。 ST_Multi不是一个聚合函数,因此基本上只是将Multi和一对额外的()添加到Multi中,但如果您有两种类型的几何体,其联合会强制几何集合,则不会有任何影响。

编辑:注之间的差,

SELECT 
    ST_AsText(
    ST_Multi(
     ST_Collect(
     ST_Multi(ST_Expand(ST_MakePoint(0,0),2)), 
     ST_Expand(ST_MakePoint(5,5), 1) 
    ) 
    ) 
); 

产生GEOMETRYCOLLECTION(MULTIPOLYGON(((-2 -2,-2 2,2 2,2 -2,-2 -2))),POLYGON((4 4,4 6,6 6,6 4,4 4)))

SELECT 
    ST_AsText(
    ST_Multi(
     ST_Union(
     ST_Multi(ST_Expand(ST_MakePoint(0,0),2)), 
     ST_Expand(ST_MakePoint(5,5), 1) 
    ) 
    ) 
); 

产生MULTIPOLYGON(((-2 -2,-2 2,2 2,2 -2,-2 -2)),((4 4,4 6,6 6,6 4,4 4)))

因为多边形Ç成为MultiPolygon的一部分,在联合之后,可以避免第二种情况中令人畏惧的GeometryCollection。但是,如果您将任何线条或点投入混合,您将返回GeomtryCollection土地。

编辑2:根据OP的评论,Google KML docs指出KML不支持GeometryCollections。由于没有办法将Point和/或Line与Polygon结合而不生成GeometryCollection,因此上述(多)Polygon方法是唯一可行的方法。

+0

谢谢。几件事。请编辑WHERE area_code = ...行末尾的逗号,因为这不应该在那里,并停止查询工作。除非我更改至少6个字符,否则我无法编辑。你有链接到任何文件,说明哪些GeometryTypes可以使用?它是ST_Polygon还是ST_MultiPolygon?我不想扔太多。 – 2014-10-29 16:10:20

+0

谢谢,逗号被删除,我只是写了一系列的子句,所以逗点疯了。是的,它也可以用于MultiPolygon。我还编辑了第二个查询,因为您不需要第二个ST_Union的开销,所以您可以使用ST_Collect,因为在倾销之后,您知道所有(多)多边形都不会重叠。 – 2014-10-29 16:13:21

+0

实际上,如果您使用的是MultiPolygon和Polygons,那么在第二个查询中确实需要使用ST_Union。 – 2014-10-29 16:17:25