TopoJSON je kompaktní kódování geografických dat a je běžné, že každá funkce v souboru TopoJSON nese objekt atributů místo ploché sady klíč‑hodnota párů. Export této struktury do CSV je místem, kde se obvykle věci pokazí: většina nástrojů buď zahodí vnořený objekt, nebo jej vypíše zpět jako řetězec JSON vložený do jedné buňky. Tento průvodce ukazuje jak převést TopoJSON na CSV v C# pomocí Aspose.GIS, přičemž každý atribut je přístupný jako samostatný sloupec a volitelně se zapisuje geometrie vedle něj jako Well‑Known Text.

Výsledkem je, že hierarchický GIS dataset se stane plochou tabulkou, kterou může přímo spotřebovat SQL Server, Power BI, pandas nebo obyčejná tabulka, bez jakékoliv speciální vrstvy pro parsování JSON ve vaší aplikaci.

Proč převádět TopoJSON do CSV pomocí Aspose.GIS

Zvažte TopoJSON prvek, jehož vlastnosti vypadají takto:

{
  "name": "North District",
  "prop1": { "this": "that" }
}

Naivní zapisovač CSV má tři špatné možnosti: zahodit prop1, serializovat jej jako {"this":"that"} do jedné buňky nebo selhat. Všechny tři posunou problém dále, kde ho někdo musí znovu parsovat z JSONu ve sloupci textu, než ho bude moci filtrovat nebo spojovat.

Aspose.GIS přistupuje jinak. Když ovladač TopoJSON načte soubor, promítá vnořený objekt do schématu vrstvy jako plochý atribut pojmenovaný podle jeho cesty, přičemž spojuje nadřazený a podřízený prvek podtržítkem. Výše uvedená funkce je vystavena jako dva běžné sloupce:

SloupecHodnota
nameSeverní okres
prop1_thisto

Protože zploštění probíhá při čtení, krok převodu nevyžaduje žádné zvláštní zpracování. Cokoli vrstva exponuje, je to, co se zapíše, takže prop1_this se objeví v CSV jako plnohodnotný sloupec, na který můžete řadit, filtrovat a provádět spojení.

Požadavky na převod TopoJSON do CSV

  • .NET 6.0 nebo novější, nebo .NET Framework 4.6.2 nebo novější
  • Aspose.GIS for .NET, nainstalováno z NuGet
  • Soubor TopoJSON obsahující alespoň jeden vnořený atributový objekt

Nainstalujte balíček pomocí .NET CLI:

dotnet add package Aspose.GIS

Nebo z konzole správce balíčků:

Install-Package Aspose.GIS

Jedna podrobnost v pojmenování lidi zmátne: NuGet balíček a sestavení se jmenují Aspose.GIS, ale kořenový prostor názvů je Aspose.Gis s malým is. Možnosti ovladače CSV jsou umístěny v Aspose.Gis.Formats.Csv.

using Aspose.Gis;
using Aspose.Gis.Formats.Csv;

Podrobnosti o produktu jsou na Aspose.GIS for .NET stránka produktu, s úplným výpisem typů v referenci API.

Zkontrolujte zploštělé schéma před konverzí

Co dosáhnete: Otevřete vrstvu TopoJSON a vytiskněte její názvy atributů, abyste přesně věděli, které sloupce bude CSV obsahovat.

Tento krok stojí za to provést jednou na reprezentativním souboru. Řekne vám skutečné názvy sloupců vytvořené zploštěním, což je mnohem spolehlivější než hádat je z původního JSONu.

using System;
using Aspose.Gis;

using (VectorLayer layer = VectorLayer.Open("data/regions.topojson", Drivers.TopoJson))
{
    Console.WriteLine($"Features: {layer.Count}");

foreach (FeatureAttribute attribute in layer.Attributes)
    {
        Console.WriteLine($"  {attribute.Name} ({attribute.DataType})");
    }
}

Pro ukázkovou funkci zobrazenou dříve tento vytiskne name (String) a prop1_this (String). Vnořený objekt se nikdy neobjeví jako atribut sám o sobě, což je přesně to, co chcete.

Převod TopoJSON na CSV při zachování vnořených atributů

Co dosáhnete: Načtěte soubor TopoJSON, zapište každý zploštělý atribut do souboru CSV a načtěte výsledek zpět, abyste potvrdili, že sloupec prošel.

Postup krok za krokem

  1. Definujte cestu ke zdrojovému souboru TopoJSON a cestu k cílovému souboru CSV.
  2. Otevřete zdroj pomocí VectorLayer.Open a potvrďte, že existuje zploštělý atribut.
  3. Zavolejte statické přetížení VectorLayer.Convert se zdrojovými a cílovými ovladači.
  4. Znovu otevřete CSV pomocí Drivers.Csv a zkontrolujte počet sloupců a hodnoty.

Následující příklad převádí soubor TopoJSON do CSV a při tom vyrovnává vnořené vlastnosti.

using System;
using System.IO;
using Aspose.Gis;

class TopoJsonToCsv
{
    static void Main()
    {
        string sourcePath = Path.Combine("data", "regions.topojson");
        string destinationPath = Path.Combine("output", "regions.csv");

Directory.CreateDirectory("output");

// Confirm the nested property was flattened when the layer was opened.
        using (VectorLayer source = VectorLayer.Open(sourcePath, Drivers.TopoJson))
        {
            Console.WriteLine($"Source features: {source.Count}");
            Console.WriteLine($"Has prop1_this: {source.Attributes.Contains("prop1_this")}");
        }

// No options are needed. The conversion writes whatever columns the
        // source layer exposes, flattened attributes included.
        VectorLayer.Convert(sourcePath, Drivers.TopoJson, destinationPath, Drivers.Csv);

// Read the CSV back and verify the schema survived the round trip.
        using (VectorLayer csv = VectorLayer.Open(destinationPath, Drivers.Csv))
        {
            Console.WriteLine($"Rows: {csv.Count}, Columns: {csv.Attributes.Count}");

if (csv.Attributes.Contains("prop1_this"))
            {
                Console.WriteLine($"First value: {csv[0].GetValue<string>("prop1_this")}");
            }

// No WKT column was requested, so features read back without geometry.
            Console.WriteLine($"Geometry empty: {csv[0].Geometry.IsEmpty}");
        }
    }
}

Vysvětlení

  • VectorLayer.Open(string, FileDriver) otevře soubor jen pro čtení. Drivers.TopoJson vrací ovladač pro formát TopoJSON.
  • FeatureAttributeCollection.Contains(string) je nejlevnější způsob, jak otestovat existenci sloupce podle názvu. IndexOf vám poskytne jeho pozici, pokud ji potřebujete.
  • VectorLayer.Convert(string, FileDriver, string, FileDriver) je statický pomocník, který jedním voláním streamuje zdroj do cílového formátu. Existuje také přetížení přijímající ConversionOptions, které se používá v následující sekci.
  • Feature.GetValue<T>(string) načte typovanou hodnotu atributu. Použijte GetValueOrDefault<T>(string), pokud může sloupec chybět nebo být null, protože GetValue<T> předpokládá, že hodnota je přítomna.
  • Poslední kontrola je ta, která lidi překvapuje. CSV soubor nemá sloupec geometrie, pokud jej nevytvoříte, takže každá funkce se vrátí s prázdnou geometrií. To je výchozí chování, ne selhání konverze, a následující sekce to opraví.

Zabalení obou vrstev do bloků using je zde důležité: VectorLayer implementuje IDisposable a není zaručeno, že cílový soubor bude vyprázdněn a uzavřen, dokud nebude uvolněn.

Zahrnout geometrii jako WKT pomocí CsvOptions

Co dosáhnete: Vytvořte CSV, které obsahuje jak zploštěné atributy a sloupec s geometrií každého prvku ve formátu Well-Known Text.

Postup krok za krokem

  1. Vytvořte instanci CsvOptions a nastavte ColumnWkt na název sloupce, který chcete použít.
  2. Přiřaďte ji k ConversionOptions.DestinationDriverOptions.
  3. Zavolejte přetížení VectorLayer.Convert, které přijímá možnosti konverze.
  4. Znovu otevřete CSV se stejným CsvOptions, aby řadič věděl, který sloupec má parsovat jako geometrie.
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Csv;

class TopoJsonToCsvWithGeometry
{
    static void Main()
    {
        string sourcePath = Path.Combine("data", "regions.topojson");
        string destinationPath = Path.Combine("output", "regions-wkt.csv");

Directory.CreateDirectory("output");

// Ask the CSV driver for a geometry column named "GeometryWkt".
        var csvOptions = new CsvOptions
        {
            ColumnWkt = "GeometryWkt"
        };

var conversionOptions = new ConversionOptions
        {
            DestinationDriverOptions = csvOptions
        };

VectorLayer.Convert(
            sourcePath,
            Drivers.TopoJson,
            destinationPath,
            Drivers.Csv,
            conversionOptions);

// Pass the same options when reading, or the WKT column is just text.
        using (VectorLayer layer = VectorLayer.Open(destinationPath, Drivers.Csv, csvOptions))
        {
            foreach (Feature feature in layer)
            {
                string name = feature.GetValueOrDefault<string>("name");
                string wkt = feature.Geometry.IsEmpty ? "(empty)" : feature.Geometry.AsText();

Console.WriteLine($"{name}: {wkt}");
            }
        }
    }
}

Vysvětlení

  • CsvOptions.ColumnWkt pojmenovává sloupec, který obsahuje geometrii každého prvku ve formátu WKT. Výchozí hodnota je null a ponechání hodnoty null nebo prázdné je přesně důvod, proč předchozí příklad nevytvořil žádnou geometrii.
  • ConversionOptions.DestinationDriverOptions je typu DriverOptions, základní třídy pro nastavení každého ovladače. Předání CsvOptions, když je cílový ovladač Drivers.Csv, způsobí, že nastavení nabude účinku; předání možností nesprávného typu pro ovladač vyvolá ArgumentException.
  • Stejná instance CsvOptions je znovu použita na straně čtení. Bez ní nemá CSV ovladač důvod zacházet s GeometryWkt jako s něčím jiným než jen dalším sloupcem typu string.
  • IGeometry.AsText() vrací ISO WKT reprezentaci, takže vytištěný výstup odpovídá tomu, co bylo zapsáno do souboru.

Symetrie je podstatou: sloupce atributů se chovají identicky, ať už je geometrie zahrnuta, nebo ne, takže můžete zapínat a vypínat sloupec WKT, aniž byste zasahovali do zbytku vašeho pipeline.

Přepočítat během konverze

Pokud spotřebitelský systém očekává konkrétní souřadnicový systém, požádejte o něj jako součást konverze místo následného zpracování CSV. ConversionOptions nese prostorový odkaz spolu s možnostmi ovladače:

var conversionOptions = new ConversionOptions
{
    DestinationDriverOptions = new CsvOptions { ColumnWkt = "GeometryWkt" },
    DestinationSpatialReferenceSystem = SpatialReferenceSystem.Wgs84
};

VectorLayer.Convert(sourcePath, Drivers.TopoJson, destinationPath, Drivers.Csv, conversionOptions);

Ne každý cílový ovladač podporuje každý prostorový referenční systém. Zavolejte Drivers.Csv.SupportsSpatialReferenceSystem(...) nejprve, pokud je cílový systém konfigurovatelný za běhu, a v případě, že není podporován, použijte objekt s nulovými možnostmi.

Hromadně převést složku souborů TopoJSON

API je stejné pro jeden soubor i pro tisíc. Jediným pravidlem, které stojí za zapamatování při paralelizaci, je, že každý pracovník potřebuje vlastní objekty vrstvy a možnosti.

using System;
using System.IO;
using System.Threading.Tasks;
using Aspose.Gis;
using Aspose.Gis.Formats.Csv;

static void ConvertFolder(string inputFolder, string outputFolder)
{
    Directory.CreateDirectory(outputFolder);

var files = Directory.GetFiles(inputFolder, "*.topojson");

Parallel.ForEach(files, file =>
    {
        string destination = Path.Combine(
            outputFolder,
            Path.GetFileNameWithoutExtension(file) + ".csv");

// Fresh options per iteration: nothing is shared across threads.
        var options = new ConversionOptions
        {
            DestinationDriverOptions = new CsvOptions { ColumnWkt = "GeometryWkt" }
        };

try
        {
            VectorLayer.Convert(file, Drivers.TopoJson, destination, Drivers.Csv, options);
        }
        catch (GisException ex)
        {
            Console.Error.WriteLine($"Skipped {Path.GetFileName(file)}: {ex.Message}");
        }
    });
}

Zachycení GisException pro každý soubor místo kolem celého cyklu znamená, že jeden poškozený soubor TopoJSON zaznamená varování místo přerušení dávky.

Získat bezplatnou licenci

Aspose.GIS běží v evaluačním režimu, dokud není použita licence. Požádejte o bezplatnou dočasnou licenci na stránce dočasné licence Aspose a aplikujte ji jednou při spuštění aplikace, před jakýmkoli jiným voláním Aspose.GIS:

var license = new Aspose.Gis.License();
license.SetLicense("Aspose.GIS.NET.lic");

Bezplatné další zdroje

Závěr

Převod TopoJSON s vnořenými vlastnostmi na CSV v .NET spočívá v jedné užitečné funkci: Aspose.GIS rozplácí vnořené atributové objekty do pojmenovaných sloupců, například prop1_this, během čtení vrstvy, takže VectorLayer.Convert nepotřebuje žádnou vlastní logiku k jejich zachování. Přidejte CsvOptions.ColumnWkt, když downstream systém potřebuje geometrii, přidejte DestinationSpatialReferenceSystem, když potřebuje konkrétní projekci, a opakujte stejné volání, když potřebujete zpracovat složku. Výsledek je plochá, připravená k analýze tabulka vytvořená několika řádky C#, bez nutnosti udržovat vlastní vrstvu pro parsování JSON.

Často kladené otázky

  1. Může Aspose.GIS zploštit vnořené objekty JSON při převodu do CSV? Ano. Ovladač TopoJSON zpřístupňuje vnořený objekt atributů jako samostatné sloupce při otevření vrstvy, přičemž spojuje názvy rodiče a potomka podtržítkem, takže zploštění je již provedeno před spuštěním převodu.

  2. Potřebuji psát vlastní kód pro zpracování vnořených vlastností? Ne. VectorLayer.Convert zapisuje všechny sloupce, které zdrojová vrstva poskytuje, takže vnořené vlastnosti nevyžadují žádný další parsovací kód od vás.

  3. Jak mohu zahrnout geometrii do výstupu CSV? Vytvořte instanci CsvOptions, nastavte její vlastnost ColumnWkt na název sloupce, který chcete, přiřaďte ji k ConversionOptions.DestinationDriverOptions a předávejte ji metodě VectorLayer.Convert.

  4. Proč je geometrie prázdná, když si CSV znovu načtu? CSV nemá sloupec geometrie, pokud o něj nepožádáte. Nastavte ColumnWkt na CsvOptions, které předáváte jak při zápisu, tak při čtení, jinak ovladač nemá žádný sloupec, ze kterého by mohl vytvořit geometrii.

  5. Jaké výjimky bych měl během konverze ošetřit? Dokumentované jsou ArgumentNullException pro nulovou cestu, ArgumentException když objekt možností neodpovídá ovladači, GisException když nelze ze souboru načíst prvek, a IOException pro základní selhání I/O.

  6. Mohu najednou převést dávku souborů TopoJSON? Ano. Procházejte seznam souborů a pro každý soubor zavolejte VectorLayer.Convert. Pokud smyčku paralelizujete, dejte každému pracovníkovi vlastní instance VectorLayer a možnosti místo sdílení jedné napříč vlákny.

  7. Mění konverze souřadnicový systém? Ne, ve výchozím nastavení. Pro reprojekci během konverze nastavte ConversionOptions.DestinationSpatialReferenceSystem na cílový systém před voláním Convert.

Číst dál