NPGSQL:使用 LWGEOMCOLLECTION 类型调用的关联操作
NPGSQL: Relate Operation called with a LWGEOMCOLLECTION type
我有一个使用 Npgsql 获取 PostGIS 数据的查询。它的目的是取一个点(x,y 坐标)并计算出该点处的几何图形(如果有的话)。对于数据库中的绝大多数几何图形,查询工作正常,但至少有一个出现以下异常:
ERROR: XX000: Relate Operation called with a LWGEOMCOLLECTION type.
This is unsupported.
堆栈跟踪的顶部是:
[NpgsqlException (0x80004005): ERROR: XX000: Relate Operation called
with a LWGEOMCOLLECTION type. This is unsupported.]
Npgsql.d__0.MoveNext() +3160
Npgsql.ForwardsOnlyDataReader.GetNextResponseObject(Boolean cleanup)
+808 Npgsql.ForwardsOnlyDataReader.GetNextRow(Boolean clearPending) +308 Npgsql.ForwardsOnlyDataReader.Read() +47
所有几何图形都应该有效,因为我对任何无效的几何图形调用 ST_MakeValid
,目前有 none,其中 ST_IsValid
returns 为假。几何图形是通过调用 ST_GeomFromKML
创建的,并通过 GeoServer 使用 WMS 在地图上呈现为光栅层,或者使用 ST_AsGeoJSON
作为矢量图层呈现,因此 PostGIS 数据似乎没问题。
有什么办法可以修改我的代码或数据来阻止这种情况的发生吗?代码失败的部分是 reader 被读入的部分:
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 特定的。
这是因为尝试在几何集合上调用相交或包含类型查询,即,您混合了一些点、线和多边形(可能是多个)。
至少有几个可能的修复方法。第一个更简单,但看起来有点老套,它只是先将输入几何缓冲 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";
请注意,此方法通常可用于修复无效的几何图形、具有自相交循环的几何图形等。
第二种方法是使用ST_Dump on your shape field to split into individual geometries and then only use Polygons in the actual query by means of the 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 获取 PostGIS 数据的查询。它的目的是取一个点(x,y 坐标)并计算出该点处的几何图形(如果有的话)。对于数据库中的绝大多数几何图形,查询工作正常,但至少有一个出现以下异常:
ERROR: XX000: Relate Operation called with a LWGEOMCOLLECTION type. This is unsupported.
堆栈跟踪的顶部是:
[NpgsqlException (0x80004005): ERROR: XX000: Relate Operation called with a LWGEOMCOLLECTION type. This is unsupported.]
Npgsql.d__0.MoveNext() +3160
Npgsql.ForwardsOnlyDataReader.GetNextResponseObject(Boolean cleanup) +808 Npgsql.ForwardsOnlyDataReader.GetNextRow(Boolean clearPending) +308 Npgsql.ForwardsOnlyDataReader.Read() +47
所有几何图形都应该有效,因为我对任何无效的几何图形调用 ST_MakeValid
,目前有 none,其中 ST_IsValid
returns 为假。几何图形是通过调用 ST_GeomFromKML
创建的,并通过 GeoServer 使用 WMS 在地图上呈现为光栅层,或者使用 ST_AsGeoJSON
作为矢量图层呈现,因此 PostGIS 数据似乎没问题。
有什么办法可以修改我的代码或数据来阻止这种情况的发生吗?代码失败的部分是 reader 被读入的部分:
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 特定的。
这是因为尝试在几何集合上调用相交或包含类型查询,即,您混合了一些点、线和多边形(可能是多个)。
至少有几个可能的修复方法。第一个更简单,但看起来有点老套,它只是先将输入几何缓冲 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";
请注意,此方法通常可用于修复无效的几何图形、具有自相交循环的几何图形等。
第二种方法是使用ST_Dump on your shape field to split into individual geometries and then only use Polygons in the actual query by means of the 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";
这是未经测试的,因为我无法在您的数据上清楚地测试它,但这些方法在实践中有效。