Esegui una conversione di Shapefiles che ha funzionato centinaia di volte, e questa volta si interrompe con una TransformationException. Non c’è output parziale e nessuna indicazione chiara del record che ha causato il problema. Spesso il colpevole è una singola coordinata non valida sepolta tra migliaia di feature valide. Questo articolo spiega perché la conversione di Shapefile fallisce con questo errore e come risolverlo in C# usando OperationErrorCollector, introdotto in Aspose.GIS for .NET 26.6. Imparerai come far terminare la conversione, mantenere ogni feature valida e ottenere un report preciso dei record che necessitano di attenzione.

Se hai bisogno solo del codice di conversione di base, consulta Convert Shapefile to KML in C#. Questa guida si basa su quello e si concentra sulla gestione degli errori.

Perché la conversione Shapefile genera TransformationException

La maggior parte dei formati di destinazione si aspetta coordinate in un sistema di coordinate specifico. KML, ad esempio, utilizza sempre longitudine e latitudine WGS 84. Durante la conversione, Aspose.GIS trasforma ogni coordinata dal sistema di coordinate di origine a quello di destinazione. Se una coordinata non può essere trasformata, la libreria genera un TransformationException e la conversione si interrompe.

Le cause più comuni sono:

  • Valori di segnaposto “no data”. Alcuni strumenti scrivono un valore sentinella invece di lasciare una geometria vuota. Il file di esempio in questo articolo contiene un punto a (-1.7976931348623157E+308, -1.7976931348623157E+308), il valore minimo di un double, che nessun sistema di coordinate può trasformare.
  • Coordinate fuori intervallo. Valori che cadono al di fuori dell’area valida del sistema di coordinate di origine, spesso causati da errori di inserimento dati o conversioni di unità errate.
  • Un file .prj che non corrisponde ai dati. Se le coordinate proiettate in metri sono dichiarate come coordinate geografiche in gradi, molti valori finiscono ben al di fuori dell’intervallo valido.
  • Record di geometria corrotti. Le esportazioni legacy e i file danneggiati possono contenere valori numerici non validi in record individuali.

In ogni caso, il problema è solitamente limitato a un piccolo numero di record, ma il comportamento predefinito scarta l’intera conversione.

Perché questa funzionalità è importante

Interrompere al primo errore è sicuro, ma è costoso nei pipeline reali. Un record errato ti costringe a pulire il file manualmente prima che i dati possano essere convertiti, e l’eccezione da sola non ti dice quanti altri record sono interessati. Con la raccolta degli errori abilitata, puoi:

  • Converti tutte le funzionalità valide invece di perdere l’intero file a causa di un record errato.
  • Registra l’indice e le coordinate di ogni funzionalità ignorata in modo che i dati di origine possano essere riparati.
  • Esegui conversioni batch non supervisionate e lavori ETL senza crashare su input sporchi.
  • Accetta Shapefile caricati dagli utenti nei servizi web e segnala i problemi dei dati all’utente.

Come risolvere i fallimenti di conversione di Shapefile in C# con Aspose.GIS

Aspose.GIS for .NET è una libreria gestita per la lettura, scrittura e conversione di formati geospaziali come Shapefile, KML, GeoJSON, GML e File Geodatabase senza la necessità di installare altri software GIS. La raccolta degli errori richiede la versione 26.6 o successiva. Installa il pacchetto da NuGet:

dotnet add package Aspose.GIS

Oppure usa la Console di Gestione Pacchetti:

Install-Package Aspose.GIS

I seguenti tipi sono utilizzati in questo tutorial:

  • VectorLayer (Aspose.Gis): apre, crea e converte i layer vettoriali. VectorLayer.Convert esegue la conversione.
  • ConversionOptions (Aspose.Gis): contiene le impostazioni di conversione, incluse DestinationDriverOptions e DestinationSpatialReferenceSystem.
  • KmlOptions (Aspose.Gis.Formats.Kml): Opzioni del driver KML. Eredita la proprietà ErrorCollector da DriverOptions.
  • OperationErrorCollector (Aspose.Gis.Operations): memorizza errori recuperabili. Espone Errors, Count, HasErrors, Add e Clear.
  • OperationError e TransformationError (Aspose.Gis.Operations): ogni errore ha un Message e un Exception. TransformationError aggiunge FeatureIndex, X, Y e Z.
  • TransformationException (Aspose.Gis.SpatialReferencing): lanciata quando una coordinata non può essere trasformata e non è collegato alcun collector.

Come risolvere TransformationException durante la conversione di Shapefile

La correzione ha due parti. Prima, allega un OperationErrorCollector in modo che la conversione salti le funzionalità non valide invece di fallire. Secondo, usa il report raccolto per riparare o rimuovere quei record alla sorgente. I passaggi seguenti usano una conversione da Shapefile a KML come esempio.

1. Preparare l’ambiente

  1. Crea un progetto console .NET e aggiungi il pacchetto NuGet Aspose.GIS 26.6+.
  2. Copia lo Shapefile e i suoi file di supporto (.shp, .shx, .dbf e .prj) in una cartella. Questo esempio utilizza data/light-traffics.shp.
  3. Aggiungi gli spazi dei nomi richiesti:
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;

2. Crea un OperationErrorCollector

Il raccoglitore registra ogni errore recuperabile generato durante la conversione. Creare una nuova istanza per ogni conversione in modo che gli errori provenienti da file diversi non vengano mescolati.

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

3. Collegare il Collector tramite ConversionOptions

Assegna il collector a KmlOptions.ErrorCollector, quindi passa le opzioni KML come DestinationDriverOptions. Impostare DestinationSpatialReferenceSystem su WGS 84 è facoltativo per KML, ma rende esplicito nel tuo codice il sistema di coordinate di destinazione.

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. Esegui la conversione

Chiama VectorLayer.Convert con il percorso di origine, il driver Shapefile, il percorso di destinazione, il driver KML e le opzioni appena configurate.

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

Quando una feature non può essere trasformata, il driver KML aggiunge un errore al collector, salta quella feature e continua con la successiva. Nessuna TransformationException viene lanciata.

5. Segnala le funzionalità ignorate e verifica l’output

Una conversione che restituisce normalmente può comunque aver saltato delle funzionalità, quindi controlla sempre il collector dopo. Converte ogni errore in TransformationError per ottenere l’indice della funzionalità e la coordinata che ha fallito, quindi apri il file di output per confermare quante funzionalità sono state scritte.

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

Per il file di esempio, il collector registra un errore per il punto segnaposto e le feature rimanenti (almeno 444) vengono scritte nel file KML.

L’indice delle feature e le coordinate in questo report completano la correzione. Apri lo Shapefile di origine nel tuo flusso di lavoro di pulizia dei dati, individua i record segnalati e correggili o rimuovili. Se molti record falliscono con valori apparentemente corretti, controlla prima il file .prj, poiché un sistema di coordinate non corrispondente è la probabile causa.

6. Codice di esempio completo

L’applicazione console completa riportata di seguito esegue la conversione due volte. La prima esecuzione utilizza le impostazioni predefinite e riproduce la TransformationException. La seconda esecuzione aggiunge un OperationErrorCollector, ignora la funzionalità non valida e stampa un report.

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. Problemi comuni e come evitarli

ProblemaMotivoSoluzione
ErrorCollector o OperationErrorCollector non compilaEntrambi sono stati aggiunti in Aspose.GIS for .NET 26.6.Aggiorna il pacchetto NuGet a 26.6 o successivo.
La conversione genera ancora TransformationExceptionNessun collector è collegato alle opzioni del driver di destinazione.Imposta ErrorCollector sull’oggetto delle opzioni del driver assegnato a ConversionOptions.DestinationDriverOptions.
Una conversione “di successo” manca di featureIl collector sopprime l’eccezione, quindi Convert restituisce normalmente.Verifica errors.HasErrors dopo ogni chiamata e registra i risultati.
Considerare le feature ignorate come corretteIl collector ignora i record non validi; non li ripara.Usa l’indice della feature segnalato e le coordinate per correggere o rimuovere i record nei dati di origine.
Centinaia di feature falliscono contemporaneamenteIl file .prj probabilmente non corrisponde alle coordinate reali.Verifica il sistema di coordinate di origine prima di indagare sui singoli record.
Errori provenienti da più file appaiono in un unico reportLa stessa istanza del collector è stata riutilizzata tra le conversioni.Crea un nuovo OperationErrorCollector per ogni file, oppure chiama Clear() tra le esecuzioni.
Errori di blocco file durante esecuzioni ripetuteUn layer aperto con VectorLayer.Open non è stato rilasciato.Avvolgi VectorLayer.Open in un blocco using.

Ottieni una licenza gratuita

È possibile ottenere una licenza temporanea gratuita per Aspose.GIS dalla pagina di licenza temporanea di Aspose: https://purchase.aspose.com/temporary-license/

Risorse aggiuntive gratuite

Conclusione

Una TransformationException durante la conversione di Shapefile di solito indica che un piccolo numero di record contiene coordinate che non possono essere trasformate, come valori segnaposto, numeri fuori intervallo o dati che non corrispondono al file .prj. Risolverlo in C# richiede due passaggi: collegare un OperationErrorCollector affinché Aspose.GIS for .NET ignori le feature non valide e completi la conversione, quindi utilizzare gli indici delle feature e le coordinate raccolte per riparare i dati di origine. Il risultato è una pipeline che continua a fornire output valido trasformando i fallimenti critici in report di qualità dei dati azionabili.

Domande frequenti

  1. Perché si verifica TransformationException quando si converte uno Shapefile? Si verifica quando una coordinata non può essere trasformata dal sistema di coordinate di origine a quello di destinazione. Le cause più comuni sono valori segnaposto “no data”, coordinate al di fuori dell’intervallo valido del loro sistema di coordinate, un file .prj che non corrisponde ai dati effettivi e record di geometria corrotti.

  2. Cosa succede per impostazione predefinita quando una coordinata non può essere trasformata?
    VectorLayer.Convert genera una TransformationException e la conversione si interrompe. A partire dalla versione 26.6, l’eccezione espone anche i valori X, Y e Z della coordinata che ha fallito.

  3. Quale versione di Aspose.GIS for .NET supporta OperationErrorCollector? OperationErrorCollector e la proprietà DriverOptions.ErrorCollector sono state introdotte in Aspose.GIS for .NET 26.6. Le versioni precedenti non le includono.

  4. OperationErrorCollector ripara le coordinate non valide? No. Salta le feature che non superano la trasformazione e le registra, quindi l’output contiene solo feature valide. Usa l’indice della feature segnalato e le coordinate per correggere o rimuovere i record errati nei dati di origine.

  5. Posso usare OperationErrorCollector con formati di output diversi da KML? ErrorCollector è definito nella classe base DriverOptions, quindi ogni classe di opzioni del driver lo espone. Gli esempi documentati coprono le destinazioni KML e MapInfo TAB; verifica il comportamento con il tuo driver di destinazione prima di fare affidamento su di esso in produzione.

  6. Quali dettagli contiene ciascun errore raccolto? Ogni OperationError fornisce un Message e l’Exception sottostante. I fallimenti di trasformazione sono segnalati come oggetti TransformationError, che aggiungono il FeatureIndex e i valori X, Y e Z della coordinata che ha fallito.

  7. Come faccio a sapere se una conversione è stata completata senza errori? Controlla la proprietà HasErrors o Count del collector dopo che VectorLayer.Convert restituisce. Una conversione che termina senza generare eccezioni potrebbe comunque aver saltato alcune funzionalità.

Leggi di più