2015-02-10 20 views
6

Tôi có truy vấn tìm nạp dữ liệu PostGIS bằng cách sử dụng Npgsql. Mục đích của nó là để có một điểm (x, y co-ordinates) và làm việc ra (nếu có) hình học là tại thời điểm đó. Đối với đại đa số các hình học trong cơ sở dữ liệu truy vấn hoạt động tốt, nhưng đối với ít nhất một tôi nhận được ngoại lệ sau đây:NPGSQL: Liên kết hoạt động được gọi với kiểu LWGEOMCOLLECTION

ERROR: XX000: Relate Operation called with a LWGEOMCOLLECTION type. This is unsupported.

với đỉnh của stack trace phúc:

[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

Tất cả hình học nên hợp lệ khi tôi gọi ST_MakeValid trên bất kỳ nội dung nào không có và hiện tại không có nơi nào ST_IsValid trả về false. Hình học được tạo ra bằng cách gọi ST_GeomFromKML và được hiển thị tốt trên bản đồ dưới dạng lớp raster sử dụng WMS qua GeoServer hoặc dưới dạng lớp vectơ sử dụng ST_AsGeoJSON để dữ liệu PostGIS có vẻ ổn.

Có cách nào để tôi có thể sửa đổi mã hoặc dữ liệu của mình để ngăn điều này xảy ra không? Một phần của thất bại đang là phần mà người đọc đã được đọc trong:

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"] 
     }; 
} 

EDIT: biết thêm thông tin. Lỗi tương tự xảy ra khi chạy truy vấn với các giá trị được mã hóa cứng trong pgAdmin III do đó vấn đề không phải là Npgsql cụ thể.

Trả lời

6

Điều này là do cố gắng gọi một giao lộ hoặc chứa truy vấn loại trên Bộ sưu tập hình học, ví dụ: nơi bạn có một số hỗn hợp điểm, đường và đa giác (có thể là đa).

Có, ít nhất, một vài bản sửa lỗi có thể có. Cách đầu tiên đơn giản hơn, nhưng có vẻ hơi khó hiểu, chỉ đơn giản là đệm hình dạng đầu vào của bạn trước 0, điều này sẽ dẫn đến việc không đa giác bị xóa, vì vậy, trong trường hợp của bạn, chỉ cần thay đổi command.commandText thành

SELECT area_code FROM area WHERE ST_INTERSECTS(ST_SetSRID(ST_Point(:x, :y), 4326), 
ST_Buffer(shape, 0)) AND area_type_code = :typecode"; 

Lưu ý, phương pháp này thường có thể được sử dụng để sửa hình học không hợp lệ, hình học có vòng tự giao nhau và tương tự.

Cách tiếp cận thứ hai là sử dụng ST_Dump trên trường hình dạng của bạn để chia thành các hình dạng riêng lẻ và sau đó chỉ sử dụng Đa giác trong truy vấn thực tế bằng hàm 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"; 

Điều này chưa được kiểm tra, vì tôi không thể kiểm tra dữ liệu này rõ ràng, nhưng các phương pháp này hoạt động trong thực tế.

Các vấn đề liên quan