Вы запускаете конвертацию Shapefiles, которая работала сотни раз, но в этот раз она останавливается с TransformationException. Нет частичного вывода и нет ясного указания, какая запись вызвала проблему. Часто виновником является одна неверная координата, спрятанная среди тысяч корректных объектов. В этой статье объясняется, почему конвертация Shapefile завершается с этой ошибкой и как исправить её в C# с использованием OperationErrorCollector, представленного в Aspose.GIS for .NET 26.6. Вы узнаете, как позволить конвертации завершиться, сохранить каждый корректный объект и получить точный отчёт о записях, требующих внимания.
Если вам нужен только базовый код конвертации, см. Convert Shapefile to KML in C#. Это руководство основывается на нём и сосредоточено на обработке ошибок.
Почему преобразование Shapefile вызывает TransformationException
Большинство целевых форматов ожидают координаты в определённой системе координат. KML, например, всегда использует долготу и широту WGS 84. При конвертации Aspose.GIS преобразует каждую координату из исходной системы координат в целевую. Если любую координату невозможно преобразовать, библиотека бросает TransformationException, и конвертация останавливается.
Наиболее распространённые причины:
- Заполнитель “no data”. Некоторые инструменты записывают значение‑сторож вместо того, чтобы оставлять геометрию пустой. Пример файла в этой статье содержит точку с координатами
(-1.7976931348623157E+308, -1.7976931348623157E+308), минимальное значение типаdouble, которое не может преобразовать ни одна система координат. - Координаты за пределами диапазона. Значения, выходящие за пределы допустимой области исходной системы координат, часто вызываемые ошибками ввода данных или неправильными преобразованиями единиц.
- Файл
.prj, не соответствующий данным. Если проецированные координаты в метрах объявлены как географические координаты в градусах, многие значения оказываются далеко за пределами допустимого диапазона. - Повреждённые записи геометрии. Устаревшие экспорты и повреждённые файлы могут содержать недопустимые числовые значения в отдельных записях.
В каждом случае проблема обычно ограничивается несколькими записями, однако поведение по умолчанию отбрасывает всю конверсию.
Почему эта функция важна
Остановка при первой ошибке безопасна, но она дорого обходится в реальных конвейерах. Одна плохая запись заставляет вас вручную очищать файл перед тем, как любые данные могут быть преобразованы, и сама по себе исключительная ситуация не сообщает, сколько других записей затронуты. При включённом сборе ошибок вы можете:
- Преобразовывать все корректные объекты вместо того, чтобы терять весь файл из‑за одной ошибочной записи.
- Записывать индекс и координаты каждой пропущенной функции, чтобы исходные данные можно было восстановить.
- Выполнять автоматические пакетные конвертации и ETL‑задачи без сбоев при наличии «грязного» ввода.
- Принимать загруженные пользователями Shapefile в веб‑службах и сообщать о проблемах с данными обратно пользователю.
Как исправить ошибки конвертации Shapefile в C# с помощью Aspose.GIS
Aspose.GIS for .NET — управляемая библиотека для чтения, записи и конвертации геопространственных форматов, таких как Shapefile, KML, GeoJSON, GML и File Geodatabase, без необходимости установки какого‑либо другого GIS‑ПО. Сбор ошибок требует версии 26.6 или новее. Установите пакет из NuGet:
dotnet add package Aspise.GIS
Или используйте консоль диспетчера пакетов:
Install-Package Aspose.GIS
В этом учебнике используются следующие типы:
- VectorLayer (
Aspose.Gis): открывает, создаёт и преобразует векторные слои.VectorLayer.Convertвыполняет преобразование. - ConversionOptions (
Aspose.Gis): содержит настройки преобразования, включаяDestinationDriverOptionsиDestinationSpatialReferenceSystem. - KmlOptions (
Aspose.Gis.Formats.Kml): параметры драйвера KML. Наследует свойствоErrorCollectorотDriverOptions. - OperationErrorCollector (
Aspose.Gis.Operations): хранит восстанавливаемые ошибки. ПредоставляетErrors,Count,HasErrors,AddиClear. - OperationError и TransformationError (
Aspose.Gis.Operations): каждая ошибка имеетMessageиException.TransformationErrorдобавляетFeatureIndex,X,YиZ. - TransformationException (
Aspose.Gis.SpatialReferencing): выбрасывается, когда координату нельзя преобразовать и коллекционер не подключён.
Как исправить TransformationException при конвертации Shapefile
Исправление состоит из двух частей. Сначала присоедините OperationErrorCollector, чтобы конвертация пропускала недопустимые объекты вместо того, чтобы завершаться с ошибкой. Затем используйте собранный отчёт для исправления или удаления этих записей у источника. Ниже приведены шаги, использующие конвертацию Shapefile в KML в качестве примера.
1. Подготовьте окружение
- Создайте консольный проект .NET и добавьте пакет NuGet Aspose.GIS 26.6+.
- Скопируйте Shapefile и его сопутствующие файлы (
.shp,.shx,.dbfи.prj) в одну папку. В этом примере используетсяdata/light-traffics.shp. - Добавьте необходимые пространства имён:
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;
2. Создать OperationErrorCollector
Коллектор записывает каждую восстанавливаемую ошибку, возникшую во время конвертации. Создавайте новый экземпляр для каждой конвертации, чтобы ошибки из разных файлов не смешивались.
// Records recoverable errors instead of throwing them.
var errors = new OperationErrorCollector();
3. Присоединить Collector через ConversionOptions
Назначьте сборщик в KmlOptions.ErrorCollector, затем передайте параметры KML как DestinationDriverOptions. Установка DestinationSpatialReferenceSystem в WGS 84 является необязательной для KML, но она делает целевую систему координат явной в вашем коде.
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. Запустить конвертацию
Вызовите VectorLayer.Convert с путем к источнику, драйвером Shapefile, путем к назначению, драйвером KML и параметрами, которые вы только что настроили.
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);
Если объект не может быть преобразован, драйвер KML добавляет ошибку в сборщик, пропускает этот объект и продолжает со следующим. Исключение TransformationException не выбрасывается.
5. Сообщить о пропущенных функциях и проверить вывод
Конверсия, которая завершается нормально, всё равно может пропустить некоторые объекты, поэтому всегда проверяйте сборщик после выполнения. Приведите каждую ошибку к типу TransformationError, чтобы получить индекс объекта и координату, где произошёл сбой, затем откройте выходной файл, чтобы подтвердить, сколько объектов было записано.
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}");
}
Для образцового файла сборщик фиксирует одну ошибку для точки‑заполнителя, а остальные объекты (по крайней мере 444) записываются в файл KML.
Индекс объектов и координаты в этом отчете завершают исправление. Откройте исходный Shapefile в вашем процессе очистки данных, найдите указанные записи и исправьте их или удалите. Если многие записи не проходят при кажущихся корректными значениях, сначала проверьте файл .prj, так как вероятной причиной является несоответствие системы координат.
6. Полный пример кода
Полное консольное приложение ниже выполняет преобразование дважды. Первый запуск использует настройки по умолчанию и воспроизводит TransformationException. Второй запуск подключает OperationErrorCollector, пропускает недопустимую функцию и выводит отчёт.
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. Распространённые подводные камни и как их избежать
| Подводный камень | Причина | Решение |
|---|---|---|
ErrorCollector или OperationErrorCollector не компилируются | Оба были добавлены в Aspose.GIS for .NET 26.6. | Обновите пакет NuGet до версии 26.6 или новее. |
Конвертация всё ещё бросает TransformationException | Коллектор не привязан к параметрам драйвера назначения. | Установите ErrorCollector в объект параметров драйвера, назначенный ConversionOptions.DestinationDriverOptions. |
| «Успешная» конвертация не содержит некоторых объектов | Коллектор подавляет исключение, поэтому Convert возвращается нормально. | Проверьте errors.HasErrors после каждого вызова и запишите результаты в журнал. |
| Обработка пропущенных объектов как исправленных | Коллектор пропускает недействительные записи; он их не исправляет. | Используйте индекс и координаты сообщённого объекта для исправления или удаления записей в исходных данных. |
| Сотни объектов не проходят одновременно | Файл .prj, вероятно, не соответствует реальным координатам. | Проверьте систему координат источника перед исследованием отдельных записей. |
| Ошибки из нескольких файлов появляются в одном отчёте | Тот же экземпляр коллектора использовался повторно при конверсиях. | Создайте новый OperationErrorCollector для каждого файла или вызывайте Clear() между запусками. |
| Ошибки блокировки файлов при повторных запусках | Слой, открытый через VectorLayer.Open, не был освобождён. | Обёрните VectorLayer.Open в блок using. |
Получить бесплатную лицензию
Вы можете получить временную бесплатную лицензию для Aspose.GIS на странице временной лицензии Aspose: https://purchase.aspose.com/temporary-license/.
Бесплатные дополнительные ресурсы
- Документация: https://docs.aspose.com/gis/net/
- Справочник API: https://reference.aspose.com/gis/net/
- Бесплатные веб‑приложения: https://products.aspose.app/gis/family
Заключение
A TransformationException во время конвертации Shapefile обычно означает, что небольшое количество записей содержит координаты, которые нельзя преобразовать, например, значения‑заполнители, числа вне диапазона или данные, не соответствующие их файлу .prj. Исправление в C# требует двух шагов: присоединить OperationErrorCollector, чтобы Aspose.GIS for .NET пропускал недействительные объекты и завершал конвертацию, затем использовать собранные индексы объектов и координаты для исправления исходных данных. В результате получается конвейер, который продолжает выдавать корректный вывод, превращая критические сбои в практические отчёты о качестве данных.
FAQs
Почему возникает TransformationException при конвертации Shapefile? Это происходит, когда координату невозможно преобразовать из исходной системы координат в целевую. Распространённые причины — значения‑заполнители “no data”, координаты, выходящие за допустимый диапазон их системы координат, файл
.prj, который не соответствует фактическим данным, и повреждённые записи геометрии.Что происходит по умолчанию, когда координату нельзя преобразовать?
VectorLayer.ConvertгенерируетTransformationExceptionи преобразование останавливается. Начиная с версии 26.6, исключение также раскрывает значенияX,YиZкоординаты, которая не прошла преобразование.Какая версия Aspose.GIS for .NET поддерживает OperationErrorCollector?
OperationErrorCollectorи свойствоDriverOptions.ErrorCollectorбыли введены в Aspose.GIS for .NET 26.6. Более ранние версии их не включают.Восстанавливает ли OperationErrorCollector недействительные координаты?
Нет. Он пропускает объекты, у которых не удалось выполнить преобразование, и записывает их, поэтому вывод содержит только корректные объекты. Используйте указанный индекс объекта и координаты, чтобы исправить или удалить неправильные записи в исходных данных.Могу ли я использовать OperationErrorCollector с форматами вывода, отличными от KML?
ErrorCollectorопределён в базовом классеDriverOptions, поэтому каждый класс параметров драйвера раскрывает его. Документированные примеры охватывают назначения KML и MapInfo TAB; протестируйте поведение с вашим собственным целевым драйвером, прежде чем полагаться на него в продакшене.Какие детали содержит каждая собранная ошибка? Каждый
OperationErrorпредоставляетMessageи базовоеException. Ошибки преобразования сообщаются как объектыTransformationError, которые добавляютFeatureIndexи значенияX,YиZнеудачной координаты.Как узнать, завершилось ли преобразование без каких-либо ошибок? Проверьте свойство
HasErrorsилиCountу сборщика после возврата изVectorLayer.Convert. Преобразование, которое завершается без исключений, всё равно может пропустить некоторые объекты.
