Uruchamiasz konwersję Shapefiles, która działała setki razy, a tym razem zatrzymuje się z TransformationException. Nie ma częściowego wyniku ani wyraźnego wskazania, który rekord spowodował problem. Często winowajcą jest pojedyncza nieprawidłowa współrzędna ukryta wśród tysięcy prawidłowych obiektów. Ten artykuł wyjaśnia, dlaczego konwersja Shapefile kończy się tym błędem i jak naprawić go w C# przy użyciu OperationErrorCollector, wprowadzonego w Aspose.GIS for .NET 26.6. Dowiesz się, jak pozwolić konwersji zakończyć się, zachować każdy prawidłowy obiekt i uzyskać precyzyjny raport rekordów wymagających uwagi.

Jeśli potrzebujesz tylko podstawowego kodu konwersji, zobacz Konwertuj Shapefile do KML w C#. Ten przewodnik opiera się na tym i koncentruje się na obsłudze błędów.

Dlaczego konwersja Shapefile generuje TransformationException

Większość formatów docelowych wymaga współrzędnych w określonym układzie współrzędnych. KML, na przykład, zawsze używa długości i szerokości geograficznej WGS 84. Podczas konwersji Aspose.GIS przekształca każdą współrzędną z układu źródłowego do układu docelowego. Jeśli którejkolwiek współrzędnej nie można przekształcić, biblioteka zgłasza TransformationException, a konwersja zostaje przerwana.

Najczęstsze przyczyny to:

  • Wartości zastępcze “no data”. Niektóre narzędzia zapisują wartość sentinelową zamiast pozostawiać geometrię pustą. Przykładowy plik w tym artykule zawiera punkt w (-1.7976931348623157E+308, -1.7976931348623157E+308), minimalną wartość typu double, której żaden system współrzędnych nie może przekształcić.
  • Współrzędne poza zakresem. Wartości, które znajdują się poza prawidłowym obszarem źródłowego systemu współrzędnych, często spowodowane błędami wprowadzania danych lub nieprawidłowymi konwersjami jednostek.
  • Plik .prj niezgodny z danymi. Jeśli współrzędne rzutowane w metrach zostaną zadeklarowane jako współrzędne geograficzne w stopniach, wiele wartości znajdzie się daleko poza prawidłowym zakresem.
  • Uszkodzone rekordy geometrii. Starsze eksporty i uszkodzone pliki mogą zawierać nieprawidłowe wartości liczbowe w poszczególnych rekordach.

W każdym przypadku problem zazwyczaj ogranicza się do kilku rekordów, jednak domyślne zachowanie odrzuca całą konwersję.

Dlaczego ta funkcja ma znaczenie

Zatrzymywanie się przy pierwszym błędzie jest bezpieczne, ale kosztowne w rzeczywistych potokach. Jeden nieprawidłowy rekord zmusza Cię do ręcznego czyszczenia pliku, zanim jakiekolwiek dane będą mogły zostać skonwertowane, a sam wyjątek nie informuje, ile innych rekordów jest dotkniętych. Po włączeniu zbierania błędów możesz:

  • Konwertuj wszystkie prawidłowe cechy zamiast tracić cały plik z powodu jednego nieprawidłowego rekordu.
  • Rejestruj indeks i współrzędne każdej pominiętej cechy, aby można było naprawić dane źródłowe.
  • Uruchamiaj nieobsługiwane konwersje wsadowe i zadania ETL bez awarii przy nieczystych danych wejściowych.
  • Akceptuj przesyłane przez użytkownika pliki Shapefile w usługach internetowych i zgłaszaj problemy z danymi z powrotem użytkownikowi.

Jak naprawić niepowodzenia konwersji plików Shapefile w C# przy użyciu Aspose.GIS

Aspose.GIS for .NET to zarządzana biblioteka do odczytu, zapisu i konwersji formatów geoprzestrzennych, takich jak Shapefile, KML, GeoJSON, GML oraz File Geodatabase, bez konieczności instalowania dodatkowego oprogramowania GIS. Zbieranie błędów wymaga wersji 26.6 lub nowszej. Zainstaluj pakiet z NuGet:

dotnet add package Aspose.GIS

Lub użyj konsoli Menedżera pakietów:

Install-Package Aspose.GIS

W tym samouczku używane są następujące typy:

  • VectorLayer (Aspose.Gis): otwiera, tworzy i konwertuje warstwy wektorowe. VectorLayer.Convert wykonuje konwersję.
  • ConversionOptions (Aspose.Gis): przechowuje ustawienia konwersji, w tym DestinationDriverOptions i DestinationSpatialReferenceSystem.
  • KmlOptions (Aspose.Gis.Formats.Kml): opcje sterownika KML. Dziedziczy właściwość ErrorCollector z DriverOptions.
  • OperationErrorCollector (Aspose.Gis.Operations): przechowuje odzyskiwalne błędy. Udostępnia Errors, Count, HasErrors, Add i Clear.
  • OperationError i TransformationError (Aspose.Gis.Operations): każdy błąd ma Message i Exception. TransformationError dodaje FeatureIndex, X, Y i Z.
  • TransformationException (Aspose.Gis.SpatialReferencing): rzucany, gdy współrzędna nie może zostać przekształcona i nie jest podłączony kolektor.

Jak naprawić błąd TransformationException podczas konwersji plików Shapefile

Poprawka składa się z dwóch części. Po pierwsze, dołącz OperationErrorCollector, aby konwersja pomijała nieprawidłowe elementy zamiast kończyć się błędem. Po drugie, użyj zebranych raportów do naprawy lub usunięcia tych rekordów u źródła. Poniższe kroki używają konwersji Shapefile do KML jako przykładu.

1. Przygotuj środowisko

  1. Utwórz projekt konsolowy .NET i dodaj pakiet NuGet Aspose.GIS 26.6+.
  2. Skopiuj plik Shapefile oraz jego pliki towarzyszące (.shp, .shx, .dbf i .prj) do jednego folderu. Ten przykład używa data/light-traffics.shp.
  3. Dodaj wymagane przestrzenie nazw:
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;

2. Utwórz OperationErrorCollector

Kolektor rejestruje każdy możliwy do naprawy błąd zgłoszony podczas konwersji. Utwórz nową instancję dla każdej konwersji, aby błędy z różnych plików nie były mieszane razem.

// Records recoverable errors instead of throwing them.
var errors = new OperationErrorCollector();

3. Dołącz kolektor za pomocą ConversionOptions

Przypisz kolektor do KmlOptions.ErrorCollector, a następnie przekaż opcje KML jako DestinationDriverOptions. Ustawienie DestinationSpatialReferenceSystem na WGS 84 jest opcjonalne dla KML, ale sprawia, że system współrzędnych docelowych jest wyraźnie określony w kodzie.

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. Uruchom konwersję

Wywołaj VectorLayer.Convert z ścieżką źródłową, sterownikiem Shapefile, ścieżką docelową, sterownikiem KML oraz opcjami, które właśnie skonfigurowałeś.

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);

Kiedy obiekt nie może zostać przekształcony, sterownik KML dodaje błąd do kolektora, pomija ten obiekt i kontynuuje z następnym. Żadne TransformationException nie jest zgłaszane.

5. Zgłoś pominięte funkcje i zweryfikuj wynik

Konwersja, która zwraca się normalnie, może nadal pomijać niektóre elementy, więc zawsze sprawdzaj kolektor po zakończeniu. Rzutuj każdy błąd na TransformationError, aby uzyskać indeks elementu i współrzędną, która nie powiodła się, a następnie otwórz plik wyjściowy, aby potwierdzić, ile elementów zostało zapisanych.

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

Dla pliku przykładowego kolektor zapisuje jeden błąd dla punktu zastępczego, a pozostałe elementy (co najmniej 444) są zapisywane do pliku KML.

Indeks obiektu i współrzędne w tym raporcie kończą naprawę. Otwórz źródłowy plik Shapefile w swoim procesie czyszczenia danych, znajdź zgłoszone rekordy i popraw je lub usuń. Jeśli wiele rekordów nie przechodzi pomimo wyglądających na prawidłowe wartości, najpierw sprawdź plik .prj, ponieważ przyczyną prawdopodobnie jest niezgodny system współrzędnych.

6. Pełny przykładowy kod

Pełna aplikacja konsolowa poniżej uruchamia konwersję dwukrotnie. Pierwsze uruchomienie używa domyślnych ustawień i odtwarza TransformationException. Drugie uruchomienie dołącza OperationErrorCollector, pomija nieprawidłową funkcję i wypisuje raport.

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. Częste pułapki i jak ich uniknąć

PułapkaPowódRozwiązanie
ErrorCollector lub OperationErrorCollector nie kompiluje sięOba zostały dodane w Aspose.GIS for .NET 26.6.Zaktualizuj pakiet NuGet do wersji 26.6 lub nowszej.
Konwersja nadal zgłasza TransformationExceptionDo opcji sterownika docelowego nie podłączono kolektora.Ustaw ErrorCollector na obiekcie opcji sterownika przypisanym do ConversionOptions.DestinationDriverOptions.
„Udana” konwersja nie zawiera obiektówKolektor tłumi wyjątek, więc Convert zwraca się normalnie.Sprawdź errors.HasErrors po każdym wywołaniu i zaloguj wyniki.
Traktowanie pominiętych obiektów jako naprawionychKolektor pomija nieprawidłowe rekordy; nie naprawia ich.Użyj zgłoszonego indeksu obiektu i współrzędnych, aby poprawić lub usunąć rekordy w danych źródłowych.
Setki obiektów nie powiodą się jednocześniePlik .prj prawdopodobnie nie odpowiada rzeczywistym współrzędnym.Sprawdź układ współrzędnych źródła przed badaniem poszczególnych rekordów.
Błędy z kilku plików pojawiają się w jednym raporcieTa sama instancja kolektora była używana wielokrotnie w konwersjach.Utwórz nowy OperationErrorCollector dla każdego pliku lub wywołaj Clear() pomiędzy uruchomieniami.
Błędy blokady pliku przy powtarzanych uruchomieniachWarstwa otwarta za pomocą VectorLayer.Open nie została zwolniona.Umieść VectorLayer.Open w bloku using.

Uzyskaj darmową licencję

Możesz uzyskać tymczasową darmową licencję na Aspose.GIS ze strony tymczasowej licencji Aspose: https://purchase.aspose.com/temporary-license/

Darmowe dodatkowe zasoby

Podsumowanie

A TransformationException podczas konwersji Shapefile zazwyczaj oznacza, że niewielka liczba rekordów zawiera współrzędne, których nie można przekształcić, np. wartości zastępcze, liczby poza zakresem lub dane niezgodne z plikiem .prj. Naprawa w C# wymaga dwóch kroków: dołącz OperationErrorCollector, aby Aspose.GIS for .NET pomijał nieprawidłowe elementy i zakończył konwersję, a następnie użyj zebranych indeksów elementów i współrzędnych do naprawy danych źródłowych. Rezultatem jest potok, który nadal dostarcza prawidłowe wyniki, przekształcając krytyczne błędy w praktyczne raporty o jakości danych.

Najczęściej zadawane pytania

  1. Dlaczego występuje TransformationException podczas konwertowania pliku Shapefile? Występuje, gdy współrzędna nie może zostać przekształcona z systemu współrzędnych źródłowego do docelowego. Typowe przyczyny to wartości zastępcze “no data”, współrzędne poza dopuszczalnym zakresem ich systemu współrzędnych, plik .prj, który nie odpowiada rzeczywistym danym, oraz uszkodzone rekordy geometrii.

  2. Co się domyślnie dzieje, gdy współrzędna nie może zostać przekształcona? VectorLayer.Convert wyrzuca TransformationException i konwersja zostaje zatrzymana. Od wersji 26.6 wyjątek dodatkowo udostępnia wartości X, Y i Z współrzędnej, która nie powiodła się.

  3. Która wersja Aspose.GIS for .NET obsługuje OperationErrorCollector?
    OperationErrorCollector i właściwość DriverOptions.ErrorCollector zostały wprowadzone w Aspose.GIS for .NET 26.6. Wcześniejsze wersje ich nie zawierają.

  4. Czy OperationErrorCollector naprawia nieprawidłowe współrzędne? Nie. Pomija elementy, które nie przeszły transformacji i rejestruje je, więc wynik zawiera tylko prawidłowe elementy. Użyj zgłoszonego indeksu elementu i współrzędnych, aby naprawić lub usunąć nieprawidłowe rekordy w danych źródłowych.

  5. Czy mogę używać OperationErrorCollector z formatami wyjściowymi innymi niż KML?
    ErrorCollector jest zdefiniowany w bazowej klasie DriverOptions, więc każda klasa opcji sterownika udostępnia go. Dokumentowane przykłady obejmują cele KML i MapInfo TAB; przetestuj zachowanie z własnym docelowym sterownikiem, zanim będziesz polegać na nim w środowisku produkcyjnym.

  6. Jakie szczegóły zawiera każdy zebrany błąd? Każdy OperationError zapewnia Message i podstawowy Exception. Niepowodzenia transformacji są zgłaszane jako obiekty TransformationError, które dodają FeatureIndex oraz wartości X, Y i Z nieprawidłowej współrzędnej.

  7. Jak mogę sprawdzić, czy konwersja zakończyła się bez żadnych błędów? Sprawdź właściwość HasErrors lub Count kolektora po zwróceniu z VectorLayer.Convert. Konwersja, która zakończy się bez wyrzucenia wyjątków, może nadal pominąć niektóre elementy.

Czytaj więcej