NPGSQL:使用 LWGEOMCOLLECTION 类型调用的关联操作
Posted
技术标签:
【中文标题】NPGSQL:使用 LWGEOMCOLLECTION 类型调用的关联操作【英文标题】:NPGSQL: Relate Operation called with a LWGEOMCOLLECTION type 【发布时间】:2015-04-10 18:08:59 【问题描述】:我有一个使用 Npgsql 获取 PostGIS 数据的查询。其目的是获取一个点(x,y 坐标)并计算出该点处的几何形状(如果有的话)。对于数据库中的绝大多数几何,查询都可以正常工作,但至少有一个我得到以下异常:
错误:XX000:使用 LWGEOMCOLLECTION 类型调用的关联操作。 这是不受支持的。
堆栈跟踪的顶部是:
[NpgsqlException (0x80004005): 错误: XX000: 调用关联操作 具有 LWGEOMCOLLECTION 类型。这是不受支持的。] Npgsql.d__0.MoveNext() +3160 Npgsql.ForwardsOnlyDataReader.GetNextResponseObject(布尔清理) +808 Npgsql.ForwardsOnlyDataReader.GetNextRow(Boolean clearPending) +308 Npgsql.ForwardsOnlyDataReader.Read() +47
所有几何图形都应该是有效的,因为我在任何不合法的几何图形上调用 ST_MakeValid
,并且当前没有 ST_IsValid
返回 false 的几何图形。几何图形是通过调用ST_GeomFromKML
创建的,并在地图上通过GeoServer 使用WMS 作为栅格图层或使用ST_AsGeoJSON
作为矢量图层进行精细渲染,因此PostGIS 数据似乎没问题。
有什么方法可以修改我的代码或数据来阻止这种情况发生吗?代码失败的部分是阅读器被读入的部分:
command.CommandText = "SELECT area_code FROM area WHERE ST_INTERSECTS(ST_SetSRID(ST_Point(:x, :y), 4326), shape) AND area_type_code = :typecode";
command.CommandType = CommandType.Text;
var typeCodeParameter = new NpgsqlParameter
DbType = DbType.String,
ParameterName = "typecode",
Value = _typeCode
;
var xParameter = new NpgsqlParameter
DbType = DbType.Double,
ParameterName = "x",
Value = _x
;
var yParameter = new NpgsqlParameter
DbType = DbType.Double,
ParameterName = "y",
Value = _y
;
command.Parameters.Add(typeCodeParameter);
command.Parameters.Add(xParameter);
command.Parameters.Add(yParameter);
using (var reader = command.ExecuteReader())
if (reader.Read())
area = new AreaBasic
Code = (string)reader["area_code"]
;
编辑: 更多信息。在 pgAdmin III 中使用硬编码值运行查询时会发生相同的错误,因此问题不是 Npgsql 特定的。
【问题讨论】:
【参考方案1】:这是由于尝试在几何集合上调用 intersects 或 contains 类型查询,即您有一些混合点、线和多边形(可能是多个)。
至少有几个可能的修复方法。第一个更简单,但似乎有点 hacky,这只是将您的输入几何首先缓冲 0,这将导致非多边形被删除,因此,在您的情况下,只需将您的 command.commandText 更改为
SELECT area_code FROM area WHERE ST_INTERSECTS(ST_SetSRID(ST_Point(:x, :y), 4326),
ST_Buffer(shape, 0)) AND area_type_code = :typecode";
请注意,这种方法通常可用于修复无效几何图形、具有自相交循环的几何图形等。
第二种方法是在你的 shape 字段上使用ST_Dump 来分割成单独的几何图形,然后通过ST_GeometryType 函数在实际查询中只使用多边形。
SELECT area_code
FROM
(SELECT area_code, (ST_Dump(area)).geom FROM area) poly
WHERE ST_INTERSECTS(ST_SetSRID(ST_Point(:x, :y), 4326), poly.geom)
AND ST_GeometryType(poly.geom) = 'ST_Polygon'
OR ST_GeometryType(poly.geom) = 'ST_MultiPolygon'
AND area_type_code = :typecode";
这是未经测试的,因为我无法根据您的数据清楚地对此进行测试,但这些方法在实践中有效。
【讨论】:
以上是关于NPGSQL:使用 LWGEOMCOLLECTION 类型调用的关联操作的主要内容,如果未能解决你的问题,请参考以下文章
NPGSQL:使用 LWGEOMCOLLECTION 类型调用的关联操作