Bạn thực hiện một chuyển đổi Shapefiles đã thành công hàng trăm lần, nhưng lần này nó dừng lại với lỗi TransformationException. Không có đầu ra một phần và không có chỉ báo rõ ràng về bản ghi nào gây ra vấn đề. Thường thì nguyên nhân là một tọa độ không hợp lệ duy nhất ẩn sâu trong hàng ngàn tính năng hợp lệ. Bài viết này giải thích tại sao việc chuyển đổi Shapefile gặp lỗi này và cách khắc phục trong C# bằng OperationErrorCollector, được giới thiệu trong Aspose.GIS for .NET 26.6. Bạn sẽ học cách cho phép quá trình chuyển đổi hoàn tất, giữ lại mọi tính năng hợp lệ, và nhận báo cáo chi tiết về các bản ghi cần chú ý.
Nếu bạn chỉ cần mã chuyển đổi cơ bản, hãy xem Convert Shapefile to KML in C#. Hướng dẫn này dựa trên đó và tập trung vào việc xử lý các lỗi.
Tại sao việc chuyển đổi Shapefile gây ra TransformationException
Hầu hết các định dạng đích yêu cầu tọa độ trong một hệ tọa độ cụ thể. Ví dụ, KML luôn sử dụng kinh độ và vĩ độ WGS 84. Trong quá trình chuyển đổi, Aspose.GIS chuyển đổi mọi tọa độ từ hệ tọa độ nguồn sang hệ tọa độ đích. Nếu bất kỳ tọa độ nào không thể được chuyển đổi, thư viện sẽ ném ra một TransformationException và quá trình chuyển đổi sẽ dừng lại.
Các nguyên nhân phổ biến nhất là:
- Placeholder “no data” values. Một số công cụ ghi một giá trị sentinel thay vì để trống geometry. Tệp mẫu trong bài viết này chứa một điểm tại
(-1.7976931348623157E+308, -1.7976931348623157E+308), giá trị tối thiểu của kiểudouble, mà không hệ tọa độ nào có thể chuyển đổi được. - Out-of-range coordinates. Các giá trị nằm ngoài khu vực hợp lệ của hệ tọa độ nguồn, thường do lỗi nhập liệu hoặc chuyển đổi đơn vị sai.
- A
.prjfile that does not match the data. Nếu các tọa độ đã chiếu tính bằng mét được khai báo là tọa độ địa lý bằng độ, nhiều giá trị sẽ nằm rất ngoài phạm vi hợp lệ. - Corrupted geometry records. Các xuất khẩu legacy và tệp bị hỏng có thể chứa các giá trị số không hợp lệ trong các bản ghi riêng lẻ.
Trong mọi trường hợp, vấn đề thường chỉ giới hạn ở một vài bản ghi, nhưng hành vi mặc định lại loại bỏ toàn bộ quá trình chuyển đổi.
Tại sao tính năng này quan trọng
Dừng lại ở lỗi đầu tiên là an toàn, nhưng tốn kém trong các pipeline thực tế. Một bản ghi lỗi buộc bạn phải làm sạch tệp bằng tay trước khi bất kỳ dữ liệu nào có thể được chuyển đổi, và riêng ngoại lệ không cho bạn biết có bao nhiêu bản ghi khác bị ảnh hưởng. Khi bật tính năng thu thập lỗi, bạn có thể:
- Chuyển đổi tất cả các tính năng hợp lệ thay vì mất toàn bộ tệp do một bản ghi lỗi.
- Ghi lại chỉ mục và tọa độ của mỗi tính năng bị bỏ qua để dữ liệu nguồn có thể được sửa chữa.
- Chạy các chuyển đổi hàng loạt không có giám sát và các công việc ETL mà không bị treo khi đầu vào không sạch.
- Chấp nhận các Shapefile do người dùng tải lên trong dịch vụ web và báo cáo các vấn đề dữ liệu lại cho người dùng.
Cách khắc phục lỗi chuyển đổi Shapefile trong C# với Aspose.GIS
Aspose.GIS for .NET là một thư viện được quản lý để đọc, ghi và chuyển đổi các định dạng không gian địa lý như Shapefile, KML, GeoJSON, GML và File Geodatabase mà không cần cài đặt bất kỳ phần mềm GIS nào khác. Việc thu thập lỗi yêu cầu phiên bản 26.6 trở lên. Cài đặt gói từ NuGet:
dotnet add package Aspose.GIS
Hoặc sử dụng Package Manager Console:
Install-Package Aspose.GIS
Các kiểu sau được sử dụng trong hướng dẫn này:
- VectorLayer (
Aspose.Gis): mở, tạo và chuyển đổi các lớp vector.VectorLayer.Convertthực hiện việc chuyển đổi. - ConversionOptions (
Aspose.Gis): chứa các cài đặt chuyển đổi, bao gồmDestinationDriverOptionsvàDestinationSpatialReferenceSystem. - KmlOptions (
Aspore.Gis.Formats.Kml): các tùy chọn driver KML. Nó kế thừa thuộc tínhErrorCollectortừDriverOptions. - OperationErrorCollector (
Aspose.Gis.Operations): lưu trữ các lỗi có thể khôi phục. Nó cung cấp các thuộc tínhErrors,Count,HasErrors,AddvàClear. - OperationError và TransformationError (
Aspose.Gis.Operations): mỗi lỗi có mộtMessagevà mộtException.TransformationErrorbổ sung các trườngFeatureIndex,X,YvàZ. - TransformationException (
Aspose.Gis.SpatialReferencing): được ném ra khi một tọa độ không thể được chuyển đổi và không có bộ thu thập nào được gắn.
Cách khắc phục TransformationException khi chuyển đổi Shapefile
Sửa lỗi này gồm hai phần. Đầu tiên, gắn một OperationErrorCollector để quá trình chuyển đổi bỏ qua các đối tượng không hợp lệ thay vì thất bại. Thứ hai, sử dụng báo cáo đã thu thập để sửa chữa hoặc xóa các bản ghi đó tại nguồn. Các bước dưới đây sử dụng chuyển đổi Shapefile sang KML làm ví dụ.
1. Chuẩn bị môi trường
- Tạo một dự án console .NET và thêm gói NuGet Aspose.GIS 26.6+.
- Sao chép Shapefile và các tệp đi kèm (
.shp,.shx,.dbf, và.prj) vào một thư mục. Ví dụ này sử dụngdata/light-traffics.shp. - Thêm các không gian tên cần thiết:
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;
2. Tạo OperationErrorCollector
Bộ thu thập ghi lại mọi lỗi có thể khôi phục được được phát sinh trong quá trình chuyển đổi. Tạo một thể hiện mới cho mỗi lần chuyển đổi để các lỗi từ các tệp khác nhau không bị trộn lẫn với nhau.
// Records recoverable errors instead of throwing them.
var errors = new OperationErrorCollector();
3. Đính kèm Collector thông qua ConversionOptions
Gán bộ thu thập vào KmlOptions.ErrorCollector, sau đó truyền các tùy chọn KML dưới dạng DestinationDriverOptions. Đặt DestinationSpatialReferenceSystem thành WGS 84 là tùy chọn cho KML, nhưng nó làm cho hệ tọa độ mục tiêu rõ ràng trong mã của bạn.
var options = new ConversionOptions
{
// KML always uses WGS 84; stating it makes the reprojection explicit.
DestinationSpatialReferenceSystem = SpatialReferenceSystem.Wgs84,
DestinationDriverOptions = new KmlOptions
{
ErrorCollector = errors // Skip and record features that fail transformation.
}
};
4. Thực hiện chuyển đổi
Gọi VectorLayer.Convert với đường dẫn nguồn, driver Shapefile, đường dẫn đích, driver KML và các tùy chọn bạn vừa cấu hình.
string sourcePath = Path.Combine("data", "light-traffics.shp");
string destinationPath = Path.Combine("output", "light-traffics.kml");
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
VectorLayer.Convert(sourcePath, Drivers.Shapefile, destinationPath, Drivers.Kml, options);
Khi một tính năng không thể được chuyển đổi, trình điều khiển KML thêm một lỗi vào bộ thu thập, bỏ qua tính năng đó và tiếp tục với tính năng tiếp theo. Không có TransformationException nào được ném.
5. Báo cáo các tính năng bị bỏ qua và xác minh đầu ra
Việc chuyển đổi trả về bình thường vẫn có thể đã bỏ qua một số tính năng, vì vậy luôn kiểm tra bộ thu thập sau đó. Ép mỗi lỗi sang TransformationError để lấy chỉ mục tính năng và tọa độ bị lỗi, sau đó mở tệp đầu ra để xác nhận có bao nhiêu tính năng đã được ghi.
if (errors.HasErrors)
{
Console.WriteLine($"Skipped {errors.Count} feature(s):");
foreach (var error in errors.Errors)
{
if (error is TransformationError transformationError)
{
Console.WriteLine(
$" Feature #{transformationError.FeatureIndex} at " +
$"({transformationError.X}, {transformationError.Y}, {transformationError.Z}): {error.Message}");
}
else
{
Console.WriteLine($" {error.Message}");
}
}
}
using (var layer = VectorLayer.Open(destinationPath, Drivers.Kml))
{
Console.WriteLine($"Features written to KML: {layer.Count}");
}
Đối với tệp mẫu, bộ thu thập ghi lại một lỗi cho điểm giữ chỗ, và các đối tượng còn lại (ít nhất 444) được ghi vào tệp KML.
Chỉ mục tính năng và tọa độ trong báo cáo này hoàn thành việc sửa chữa. Mở Shapefile nguồn trong quy trình làm sạch dữ liệu của bạn, tìm các bản ghi được báo cáo và sửa chữa hoặc xóa chúng. Nếu nhiều bản ghi thất bại với các giá trị có vẻ hợp lý, hãy kiểm tra tệp .prj trước, vì hệ thống tọa độ không khớp có thể là nguyên nhân.
6. Mã mẫu đầy đủ
Ứng dụng console đầy đủ bên dưới chạy quá trình chuyển đổi hai lần. Lần chạy đầu tiên sử dụng cài đặt mặc định và tái tạo TransformationException. Lần chạy thứ hai đính kèm một OperationErrorCollector, bỏ qua tính năng không hợp lệ và in ra báo cáo.
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;
namespace ShapefileTransformationErrors
{
internal class Program
{
private static void Main()
{
string sourcePath = Path.Combine("data", "light-traffics.shp");
string outputFolder = "output";
Directory.CreateDirectory(outputFolder);
// -----------------------------------------------------------------
// Run 1: default behavior. The first failed transformation aborts
// the whole conversion with a TransformationException.
// -----------------------------------------------------------------
string failFastPath = Path.Combine(outputFolder, "fail-fast.kml");
try
{
VectorLayer.Convert(sourcePath, Drivers.Shapefile, failFastPath, Drivers.Kml);
Console.WriteLine("Default conversion finished without transformation errors.");
}
catch (TransformationException ex)
{
Console.WriteLine($"Default conversion aborted: {ex.Message}");
Console.WriteLine($"Failing coordinate: ({ex.X}, {ex.Y}, {ex.Z})");
}
// -----------------------------------------------------------------
// Run 2: error-tolerant conversion. Invalid features are skipped
// and recorded in the collector; valid features are written.
// -----------------------------------------------------------------
string destinationPath = Path.Combine(outputFolder, "light-traffics.kml");
var errors = new OperationErrorCollector();
var options = new ConversionOptions
{
DestinationSpatialReferenceSystem = SpatialReferenceSystem.Wgs84,
DestinationDriverOptions = new KmlOptions
{
ErrorCollector = errors
}
};
VectorLayer.Convert(sourcePath, Drivers.Shapefile, destinationPath, Drivers.Kml, options);
// Report every skipped feature so the source data can be repaired.
if (errors.HasErrors)
{
Console.WriteLine($"Conversion completed with {errors.Count} skipped feature(s):");
foreach (var error in errors.Errors)
{
if (error is TransformationError transformationError)
{
Console.WriteLine(
$" Feature #{transformationError.FeatureIndex} at " +
$"({transformationError.X}, {transformationError.Y}, {transformationError.Z}): {error.Message}");
}
else
{
Console.WriteLine($" {error.Message}");
}
}
}
else
{
Console.WriteLine("Conversion completed with no errors.");
}
// Verify the output file.
using (var layer = VectorLayer.Open(destinationPath, Drivers.Kml))
{
Console.WriteLine($"Features written to KML: {layer.Count}");
}
}
}
}
7. Những lỗi thường gặp và cách tránh chúng
| Rủi ro | Lý do | Cách khắc phục |
|---|---|---|
ErrorCollector hoặc OperationErrorCollector không biên dịch | Cả hai đều được thêm vào Aspose.GIS for .NET 26.6. | Nâng cấp gói NuGet lên phiên bản 26.6 hoặc mới hơn. |
Quá trình chuyển đổi vẫn ném TransformationException | Không có bộ thu nào được gắn vào tùy chọn driver đích. | Đặt ErrorCollector trên đối tượng tùy chọn driver được gán cho ConversionOptions.DestinationDriverOptions. |
| Một chuyển đổi “thành công” thiếu các đối tượng | Bộ thu chặn ngoại lệ, vì vậy Convert trả về bình thường. | Kiểm tra errors.HasErrors sau mỗi lần gọi và ghi lại kết quả. |
| Xem các đối tượng bị bỏ qua là đã được sửa | Bộ thu bỏ qua các bản ghi không hợp lệ; nó không sửa chúng. | Sử dụng chỉ mục và tọa độ của đối tượng được báo cáo để sửa hoặc loại bỏ các bản ghi trong dữ liệu nguồn. |
| Hàng trăm đối tượng thất bại cùng lúc | Tệp .prj có khả năng không khớp với tọa độ thực tế. | Xác minh hệ tọa độ nguồn trước khi điều tra các bản ghi riêng lẻ. |
| Lỗi từ nhiều tệp xuất hiện trong một báo cáo | Cùng một thể hiện bộ thu đã được tái sử dụng trong các lần chuyển đổi. | Tạo một OperationErrorCollector mới cho mỗi tệp, hoặc gọi Clear() giữa các lần chạy. |
| Lỗi khóa tệp khi chạy lại | Một lớp được mở bằng VectorLayer.Open chưa được giải phóng. | Bao bọc VectorLayer.Open trong một khối using. |
Nhận giấy phép miễn phí
Bạn có thể nhận giấy phép tạm thời miễn phí cho Aspose.GIS từ trang giấy phép tạm thời của Aspose: https://purchase.aspose.com/temporary-license/
Tài nguyên bổ sung miễn phí
- Tài liệu: https://docs.aspose.com/gis/net/
- Tham chiếu API: https://reference.aspose.com/gis/net/
- Ứng dụng Web miễn phí: https://products.aspose.app/gis/family
Kết luận
Một TransformationException trong quá trình chuyển đổi Shapefile thường có nghĩa là một số lượng nhỏ bản ghi chứa tọa độ không thể chuyển đổi, chẳng hạn như giá trị placeholder, số ngoài phạm vi, hoặc dữ liệu không khớp với tệp .prj của nó. Khắc phục trong C# mất hai bước: gắn một OperationErrorCollector để Aspose.GIS for .NET bỏ qua các tính năng không hợp lệ và hoàn thành quá trình chuyển đổi, sau đó sử dụng các chỉ mục tính năng và tọa độ đã thu thập để sửa dữ liệu nguồn. Kết quả là một pipeline vẫn tiếp tục cung cấp đầu ra hợp lệ trong khi biến các lỗi nghiêm trọng thành các báo cáo chất lượng dữ liệu có thể hành động.
Câu hỏi thường gặp
Tại sao TransformationException xảy ra khi chuyển đổi Shapefile? Nó xảy ra khi một tọa độ không thể được chuyển đổi từ hệ tọa độ nguồn sang hệ tọa độ đích. Các nguyên nhân phổ biến bao gồm các giá trị placeholder “no data”, tọa độ nằm ngoài phạm vi hợp lệ của hệ tọa độ, tệp
.prjkhông khớp với dữ liệu thực tế, và các bản ghi hình học bị hỏng.Điều gì xảy ra theo mặc định khi một tọa độ không thể được chuyển đổi?
VectorLayer.Convertném ra mộtTransformationExceptionvà quá trình chuyển đổi dừng lại. Bắt đầu từ phiên bản 26.6, ngoại lệ cũng cung cấp các giá trịX,YvàZcủa tọa độ đã thất bại.Phiên bản nào của Aspose.GIS for .NET hỗ trợ OperationErrorCollector?
OperationErrorCollectorvà thuộc tínhDriverOptions.ErrorCollectorđã được giới thiệu trong Aspose.GIS for .NET 26.6. Các phiên bản trước không bao gồm chúng.OperationErrorCollector có sửa các tọa độ không hợp lệ không? Không. Nó bỏ qua các đối tượng không chuyển đổi được và ghi lại chúng, vì vậy đầu ra chỉ chứa các đối tượng hợp lệ. Sử dụng chỉ mục đối tượng và tọa độ đã báo cáo để sửa hoặc loại bỏ các bản ghi lỗi trong dữ liệu nguồn.
Có thể sử dụng OperationErrorCollector với các định dạng đầu ra khác ngoài KML không?
ErrorCollectorđược định nghĩa trên lớp cơ sởDriverOptions, vì vậy mỗi lớp tùy chọn driver đều phơi bày nó. Các ví dụ được tài liệu hoá bao gồm các đích KML và MapInfo TAB; hãy kiểm tra hành vi với driver mục tiêu của bạn trước khi dựa vào nó trong môi trường sản xuất.Mỗi lỗi được thu thập chứa những chi tiết nào? Mỗi
OperationErrorcung cấp mộtMessagevàExceptioncơ bản. Các lỗi chuyển đổi được báo cáo dưới dạng các đối tượngTransformationError, trong đó bổ sungFeatureIndexvà các giá trịX,Y, vàZcủa tọa độ gây lỗi.Làm sao tôi biết việc chuyển đổi đã hoàn thành mà không có bất kỳ lỗi nào? Kiểm tra thuộc tính
HasErrorshoặcCountcủa bộ thu thập sau khiVectorLayer.Converttrả về. Một quá trình chuyển đổi kết thúc mà không ném ngoại lệ vẫn có thể đã bỏ qua một số tính năng.
