Ви запускаєте конвертацію 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”. Деякі інструменти записують sentinel‑значення замість того, щоб залишити геометрію порожньою. Прикладний файл у цій статті містить точку з координатами (-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 Aspose.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. Підготовка середовища

  1. Створіть консольний проєкт .NET і додайте пакет NuGet Aspose.GIS 26.6+.
  2. Скопіюйте файл Shapefile та його супровідні файли (.shp, .shx, .dbf та .prj) в одну папку. У цьому прикладі використовується data/light-traffics.shp.
  3. Додайте необхідні простори імен:
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. Приєднати колектор за допомогою 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/

Безкоштовні додаткові ресурси

Висновок

A TransformationException під час конвертації Shapefile зазвичай означає, що невелика кількість записів містить координати, які не можуть бути трансформовані, наприклад, значення‑заповнювачі, числа поза діапазоном або дані, що не відповідають його .prj файлу. Виправлення в C# вимагає два кроки: приєднати OperationErrorCollector, щоб Aspose.GIS for .NET пропускав недійсні об’єкти і завершував конвертацію, потім використати зібрані індекси об’єктів та координати для виправлення вихідних даних. Результат — це конвеєр, який продовжує постачати коректний вихід, перетворюючи жорсткі помилки на дієві звіти про якість даних.

Питання та відповіді

  1. Чому під час перетворення Shapefile виникає TransformationException? Воно виникає, коли координату не вдається перетворити з вихідної системи координат у цільову. Типові причини — заповнювачі значень “no data”, координати, що виходять за межі допустимого діапазону їхньої системи координат, файл .prj, який не відповідає фактичним даним, та пошкоджені записи геометрії.

  2. Що відбувається за замовчуванням, коли координату не вдається трансформувати?
    VectorLayer.Convert генерує TransformationException і конвертація зупиняється. Починаючи з версії 26.6, виключення також надає значення X, Y і Z координати, яка не вдалася.

  3. Яка версія Aspose.GIS for .NET підтримує OperationErrorCollector? OperationErrorCollector та властивість DriverOptions.ErrorCollector були введені в Aspose.GIS for .NET 26.6. Попередні версії їх не містять.

  4. Чи виправляє OperationErrorCollector недійсні координати? Ні. Він пропускає елементи, які не пройшли трансформацію, і записує їх, тому вихід містить лише дійсні елементи. Використайте повідомлений індекс елементу та координати, щоб виправити або видалити неправильні записи у вихідних даних.

  5. Чи можу я використовувати OperationErrorCollector з форматами виводу, відмінними від KML? ErrorCollector визначено в базовому класі DriverOptions, тому кожен клас параметрів драйвера його експонує. Документовані приклади охоплюють призначення KML та MapInfo TAB; протестуйте поведінку з вашим власним цільовим драйвером, перш ніж покладатися на нього у виробництві.

  6. Які деталі містить кожна зібрана помилка? Кожен OperationError надає Message та базове Exception. Помилки перетворення повідомляються як об’єкти TransformationError, які додають FeatureIndex і значення X, Y та Z невдалої координати.

  7. Як я можу дізнатися, чи завершилося перетворення без помилок? Перевірте властивість HasErrors або Count колектора після повернення VectorLayer.Convert. Перетворення, яке завершується без виключень, все одно може пропустити деякі елементи.

Читати далі