Spouštíte konverzi Shapefiles, která fungovala stovkykrát, a tentokrát se zastaví s výjimkou TransformationException. Neexistuje žádný částečný výstup ani jasná indikace, který záznam způsobil problém. Často je viníkem jedna neplatná souřadnice ukrytá mezi tisíci platnými prvky. Tento článek vysvětluje, proč konverze Shapefile selhává s touto chybou a jak ji opravit v C# pomocí OperationErrorCollector, představeného v Aspose.GIS for .NET 26.6. Naučíte se, jak nechat konverzi dokončit, zachovat každý platný prvek a získat přesnou zprávu o záznamech, které vyžadují pozornost.
Pokud potřebujete pouze základní kód pro konverzi, podívejte se na Convert Shapefile to KML in C#. Tento průvodce na tom staví a zaměřuje se na zpracování chyb.
Proč konverze Shapefile vyvolává TransformationException
Většina cílových formátů očekává souřadnice v konkrétním souřadnicovém systému. KML například vždy používá zeměpisnou délku a šířku WGS 84. Během konverze Aspose.GIS převádí každou souřadnici ze zdrojového souřadnicového systému do cílového. Pokud nelze některou souřadnici převést, knihovna vyhodí výjimku TransformationException a konverze se zastaví.
Nejčastější příčiny jsou:
- Placeholder “no data” values. Některé nástroje zapíšou sentinel hodnotu místo toho, aby nechaly geometrii prázdnou. Vzorový soubor v tomto článku obsahuje bod na
(-1.7976931348623157E+308, -1.7976931348623157E+308), což je minimální hodnota typudouble, kterou žádný souřadnicový systém nedokáže transformovat. - Out-of-range coordinates. Hodnoty, které spadají mimo platnou oblast zdrojového souřadnicového systému, často způsobené chybami při zadávání dat nebo špatnými převody jednotek.
- A
.prjfile that does not match the data. Soubor.prj, který neodpovídá datům. Pokud jsou projekční souřadnice v metrech deklarovány jako geografické souřadnice ve stupních, mnoho hodnot skončí daleko mimo platný rozsah. - Corrupted geometry records. Starší exporty a poškozené soubory mohou obsahovat neplatné číselné hodnoty v jednotlivých záznamech.
V každém případě je problém obvykle omezen na několik záznamů, avšak výchozí chování zahodí celou konverzi.
Proč je tato funkce důležitá
Zastavení při první chybě je bezpečné, ale v reálných pipelinech to stojí hodně. Jeden špatný záznam vás nutí ručně vyčistit soubor, než může být jakýkoli údaj převeden, a samotná výjimka neříká, kolik dalších záznamů je ovlivněno. Při povoleném sběru chyb můžete:
- Převést všechny platné prvky místo ztráty celého souboru kvůli jedné špatné položce.
- Zaznamenat index a souřadnice každého přeskočeného prvku, aby mohla být opravená zdrojová data.
- Spouštět neřízené dávkové konverze a ETL úlohy bez zhroucení při špinavém vstupu.
- Přijímat uživateli nahrané Shapefily ve webových službách a hlásit problémy s daty zpět uživateli.
Jak opravit selhání konverze Shapefile v C# s Aspose.GIS
Aspose.GIS for .NET je spravovaná knihovna pro čtení, zápis a konverzi geoprostorových formátů, jako jsou Shapefile, KML, GeoJSON, GML a File Geodatabase, bez nutnosti instalace jiného GIS softwaru. Sběr chyb vyžaduje verzi 26.6 nebo novější. Nainstalujte balíček z NuGet:
dotnet add package Aspose.GIS
Nebo použijte konzoli správce balíčků:
Install-Package Aspose.GIS
V tomto tutoriálu jsou použity následující typy:
- VectorLayer (
Aspose.Gis): otevírá, vytváří a převádí vektorové vrstvy.VectorLayer.Convertprovádí převod. - ConversionOptions (
Aspose.Gis): obsahuje nastavení převodu, včetněDestinationDriverOptionsaDestinationSpatialReferenceSystem. - KmlOptions (
Aspose.Gis.Formats.Kml): možnosti ovladače KML. Dědí vlastnostErrorCollectorzDriverOptions. - OperationErrorCollector (
Aspose.Gis.Operations): ukládá opravitelná (recoverable) chyby. PoskytujeErrors,Count,HasErrors,AddaClear. - OperationError a TransformationError (
Aspose.Gis.Operations): každá chyba máMessageaException.TransformationErrorpřidáváFeatureIndex,X,YaZ. - TransformationException (
Aspose.Gis.SpatialReferencing): vyvolána, když nelze souřadnici transformovat a není připojen žádný sběrač.
Jak opravit TransformationException při konverzi Shapefile
Oprava má dvě části. Nejprve připojte OperationErrorCollector, aby konverze přeskočila neplatné prvky místo selhání. Druhým krokem je použít shromážděnou zprávu k opravě nebo odstranění těchto záznamů ve zdroji. Níže uvedené kroky používají konverzi Shapefile do KML jako příklad.
1. Připravte prostředí
- Vytvořte .NET konzolový projekt a přidejte balíček NuGet Aspose.GIS 26.6+.
- Zkopírujte soubor Shapefile a jeho doprovodné soubory (
.shp,.shx,.dbfa.prj) do jedné složky. Tento příklad používádata/light-traffics.shp. - Přidejte požadované jmenné prostory:
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;
2. Vytvořte OperationErrorCollector
Sběrač zaznamenává každou opravitelnou chybu, která se vyskytne během konverze. Vytvořte novou instanci pro každou konverzi, aby se chyby z různých souborů neproplétaly.
// Records recoverable errors instead of throwing them.
var errors = new OperationErrorCollector();
3. Připojte kolektor pomocí ConversionOptions
Přiřaďte kolektor k KmlOptions.ErrorCollector, poté předávejte možnosti KML jako DestinationDriverOptions. Nastavení DestinationSpatialReferenceSystem na WGS 84 je pro KML volitelné, ale v kódu explicitně určuje cílový souřadnicový systém.
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. Spusťte převod
Zavolejte VectorLayer.Convert se zdrojovou cestou, ovladačem Shapefile, cílovou cestou, ovladačem KML a možnostmi, které jste právě nakonfigurovali.
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);
Když nelze prvek transformovat, ovladač KML přidá chybu do sběrače, přeskočí tento prvek a pokračuje dalším. Žádná TransformationException není vyhozena.
5. Nahlaste přeskočené funkce a ověřte výstup
Konverze, která vrátí normálně, může stále přeskočit některé prvky, proto vždy po ní zkontrolujte kolektor. Přetypujte každou chybu na TransformationError, abyste získali index prvku a souřadnici, která selhala, a poté otevřete výstupní soubor, abyste potvrdili, kolik prvků bylo zapsáno.
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}");
}
Pro ukázkový soubor kolektor zaznamená jednu chybu pro zástupný bod a zbývající prvky (alespoň 444) jsou zapsány do souboru KML.
Index prvku a souřadnice v této zprávě dokončují opravu. Otevřete zdrojový Shapefile ve svém workflow pro čištění dat, najděte nahlášené záznamy a opravte je nebo je odstraňte. Pokud mnoho záznamů selže s hodnotami, které vypadají rozumně, nejprve zkontrolujte soubor .prj, protože pravděpodobnou příčinou je nesoulad souřadnicového systému.
6. Kompletní ukázkový kód
Kompletní konzolová aplikace níže spustí konverzi dvakrát. První spuštění používá výchozí nastavení a reprodukuje TransformationException. Druhé spuštění připojí OperationErrorCollector, přeskočí neplatnou funkci a vytiskne zprávu.
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. Časté úskalí a jak se jim vyhnout
| Problém | Důvod | Řešení |
|---|---|---|
ErrorCollector nebo OperationErrorCollector se nedaří zkompilovat | Obě byly přidány v Aspose.GIS for .NET 26.6. | Aktualizujte NuGet balíček na verzi 26.6 nebo novější. |
Převod stále vyhazuje TransformationException | Není připojen žádný sběrač k možnostem cílového ovladače. | Nastavte ErrorCollector na objekt možností ovladače přiřazený k ConversionOptions.DestinationDriverOptions. |
| „Úspěšný“ převod postrádá prvky | Sběrač potlačuje výjimku, takže Convert vrací normálně. | Zkontrolujte errors.HasErrors po každém volání a zaznamenejte výsledky. |
| Považování přeskočených prvků za opravené | Sběrač přeskočí neplatné záznamy; neopravuje je. | Použijte nahlášený index prvku a souřadnice k opravě nebo odstranění záznamů ve zdrojových datech. |
| Stovky prvků selžou najednou | Soubor .prj pravděpodobně neodpovídá skutečným souřadnicím. | Ověřte souřadnicový systém zdroje před zkoumáním jednotlivých záznamů. |
| Chyby z několika souborů se objeví v jedné zprávě | Stejná instance sběrače byla znovu použita napříč převody. | Vytvořte nový OperationErrorCollector pro každý soubor nebo mezi běhy zavolejte Clear(). |
| Chyby zamčení souboru při opakovaných spuštěních | Vrstva otevřená pomocí VectorLayer.Open nebyla uvolněna. | Zabalte VectorLayer.Open do bloku using. |
Získejte bezplatnou licenci
Můžete získat dočasnou bezplatnou licenci pro Aspose.GIS na stránce dočasné licence Aspose: https://purchase.aspose.com/temporary-license/.
Bezplatné další zdroje
- Dokumentace: https://docs.aspose.com/gis/net/
- Reference API: https://reference.aspose.com/gis/net/
- Bezplatné webové aplikace: https://products.aspose.app/gis/family
Závěr
Výjimka TransformationException během konverze Shapefile obvykle znamená, že malé množství záznamů obsahuje souřadnice, které nelze transformovat, například zástupné hodnoty, čísla mimo rozsah nebo data, která neodpovídají souboru .prj. Oprava v C# vyžaduje dva kroky: připojit OperationErrorCollector, aby Aspose.GIS for .NET přeskočil neplatné prvky a dokončil konverzi, a poté použít shromážděné indexy prvků a souřadnice k opravě zdrojových dat. Výsledkem je pipeline, která nadále poskytuje platný výstup a zároveň převádí tvrdé selhání na akční zprávy o kvalitě dat.
Často kladené otázky
Proč dochází k výskytu výjimky TransformationException při převodu souboru Shapefile? Vyskytuje se, když nelze souřadnici převést ze zdrojového souřadnicového systému do cílového. Mezi běžné příčiny patří zástupné hodnoty “no data”, souřadnice mimo platný rozsah jejich souřadnicového systému, soubor
.prj, který neodpovídá skutečným datům, a poškozené záznamy geometrie.Co se standardně stane, když nelze souřadnici transformovat?
VectorLayer.ConvertvyhodíTransformationExceptiona konverze se zastaví. Od verze 26.6 výjimka také odhalí hodnotyX,YaZsouřadnice, která selhala.Která verze Aspose.GIS for .NET podporuje OperationErrorCollector?
OperationErrorCollectora vlastnostDriverOptions.ErrorCollectorbyly zavedeny v Aspose.GIS for .NET 26.6. Starší verze je neobsahují.Opravuje OperationErrorCollector neplatné souřadnice? Ne. Přeskakuje prvky, které selžou při transformaci, a zaznamenává je, takže výstup obsahuje pouze platné prvky. Použijte nahlášený index prvku a souřadnice k opravě nebo odstranění špatných záznamů ve zdrojových datech.
Mohu použít OperationErrorCollector s výstupními formáty jinými než KML?
ErrorCollectorje definován v základní tříděDriverOptions, takže každá třída možností ovladače ji vystavuje. Dokumentované příklady pokrývají cíle KML a MapInfo TAB; otestujte chování s vlastním cílovým ovladačem, než se na něj spolehnete v produkci.Jaké podrobnosti obsahuje každá shromážděná chyba? Každý
OperationErrorposkytujeMessagea podkladovouException. Selhání transformace jsou hlášena jako objektyTransformationError, které přidávajíFeatureIndexa hodnotyX,YaZselhávající souřadnice.Jak zjistím, zda konverze proběhla bez jakýchkoli chyb? Zkontrolujte vlastnost
HasErrorsneboCountkolektoru po návratuVectorLayer.Convert. Konverze, která skončí bez vyhození výjimky, může stále mít přeskočené prvky.
