TopoJSON — це компактне кодування географічних даних, і зазвичай кожна функція у файлі TopoJSON містить об’єкт атрибутів, а не простий набір пар ключ‑значення. Експорт цієї структури у CSV — це те місце, де зазвичай виникають проблеми: більшість інструментів або відкидає вкладений об’єкт, або виводить його назад як рядок JSON, вставлений в одну клітинку. У цьому посібнику показано, як конвертувати TopoJSON у CSV на C# за допомогою Aspose.GIS, зберігаючи кожен атрибут доступним у власному стовпці та за потреби записуючи геометрію поруч у вигляді Well‑Known Text.
Перевага полягає в тому, що ієрархічний GIS‑набір даних перетворюється на плоску таблицю, яку SQL Server, Power BI, pandas або проста електронна таблиця можуть безпосередньо використовувати, без спеціального шару розбору JSON у вашому застосунку.
Чому конвертувати TopoJSON у CSV за допомогою Aspose.GIS
Розгляньте TopoJSON‑об’єкт, властивості якого виглядають так:
{
"name": "North District",
"prop1": { "this": "that" }
}
Наївний CSV‑записувач має три погані варіанти: відкинути prop1, серіалізувати його як {"this":"that"} в одну клітинку або завершити роботу з помилкою. Усі три передають проблему вниз по потоку, де хтось має повторно розпарсити JSON з текстового стовпця, перш ніж зможе фільтрувати або приєднувати його.
Aspose.GIS застосовує інший підхід. Коли драйвер TopoJSON читає файл, він проєктує вкладений об’єкт у схему шару як плоский атрибут, названий за його шляхом, об’єднуючи батьківський і дочірній елементи підкресленням. Наведена вище функція представлена як два звичайні стовпці:
| Стовпець | Значення |
|---|---|
name | Північний район |
prop1_this | те |
Оскільки сплющування відбувається під час читання, крок перетворення не потребує жодного спеціального оброблення. Те, що шар експонує, саме і записується, тому prop1_this потрапляє у CSV як колонка першого класу, яку можна сортувати, фільтрувати та приєднувати.
Вимоги до конвертації TopoJSON у CSV
- .NET 6.0 або новіший, або .NET Framework 4.6.2 або новіший
- Aspose.GIS for .NET, встановлений з NuGet
- Файл TopoJSON, що містить принаймні один вкладений об’єкт атрибуту
Встановіть пакет за допомогою .NET CLI:
dotnet add package Aspose.GIS
Або з консолі диспетчера пакетів:
Install-Package Aspose.GIS
Одна деталь назви вводить людей в оману: пакет NuGet та збірка називаються Aspose.GIS, але кореневий простір імен — Aspose.Gis з маленькими літерами is. Параметри драйвера CSV розташовані в Aspose.Gis.Formats.Csv.
using Aspose.Gis;
using Aspose.Gis.Formats.Csv;
Деталі продукту доступні на Aspose.GIS for .NET сторінка продукту, а повний перелік типів — у довідник API.
Перевірте сплющену схему перед конвертацією
Що ви досягнете: Відкрийте шар TopoJSON і виведіть назви його атрибутів, щоб точно знати, які стовпці міститиме CSV.
Цей крок варто виконати один раз на представницькому файлі. Він підкаже вам реальні назви стовпців, отримані в результаті згладжування, що набагато надійніше, ніж вгадувати їх з необробленого JSON.
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})");
}
}
Для прикладу функції, показаної раніше, це виводить name (String) та prop1_this (String). Вкладений об’єкт ніколи не з’являється як окремий атрибут, що саме й потрібно.
Конвертувати TopoJSON у CSV, зберігаючи вкладені атрибути
Що ви досягнете: Завантажте файл TopoJSON, запишіть кожен сплющений атрибут у CSV‑файл і прочитайте результат, щоб переконатися, що стовпець пройшов.
Покроковий процес
- Визначте шлях до вихідного TopoJSON та шлях до цільового CSV.
- Відкрийте джерело за допомогою
VectorLayer.Openі переконайтеся, що існує сплощений атрибут. - Викличте статичне перевантаження
VectorLayer.Convertз драйверами джерела та призначення. - Знову відкрийте CSV за допомогою
Drivers.Csvі перевірте кількість стовпців та значення.
Наступний приклад конвертує файл TopoJSON у CSV, розплющуючи вкладені властивості під час процесу.
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}");
}
}
}
Пояснення
VectorLayer.Open(string, FileDriver)відкриває файл у режимі лише для читання.Drivers.TopoJsonповертає драйвер для формату TopoJSON.FeatureAttributeCollection.Contains(string)— найпростіший спосіб перевірити наявність стовпця за назвою.IndexOfдає його позицію, якщо вона потрібна.VectorLayer.Convert(string, FileDriver, string, FileDriver)— статичний допоміжний метод, який передає дані з джерела у формат призначення одним викликом. Існує також перевантаження, яке приймаєConversionOptions, використане в наступному розділі.Feature.GetValue<T>(string)читає типізоване значення атрибуту. ВикористовуйтеGetValueOrDefault<T>(string), коли стовпець може бути відсутнім або мати значення null, оскількиGetValue<T>передбачає, що значення присутнє.- Остання перевірка — та, що здивовує людей. У CSV‑файлі немає колонки геометрії, якщо ви її не створите, тому кожна функція повертається з порожньою геометрією. Це поведінка за замовчуванням, а не помилка конвертації, і наступний розділ виправляє це.
Обгортання обох шарів у блоки using має значення тут: VectorLayer реалізує IDisposable, і файл призначення не гарантовано буде очищений і закритий, доки не буде вивільнений.
Включення геометрії у форматі WKT за допомогою CsvOptions
Що ви досягнете: Створіть CSV, який містить як сплощені атрибути і стовпець, що містить геометрію кожного об’єкта у форматі Well-Known Text.
Покроковий процес
- Створіть екземпляр
CsvOptionsі встановітьColumnWktу назву вибраного стовпця. - Призначте його
ConversionOptions.DestinationDriverOptions. - Викличте перевантаження
VectorLayer.Convert, яке приймає параметри конверсії. - Знову відкрийте CSV з тим же
CsvOptions, щоб драйвер знав, який стовпець розбирати як геометрію.
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}");
}
}
}
}
Пояснення
CsvOptions.ColumnWktназиває стовпець, який містить геометрію кожного об’єкта у вигляді WKT. За замовчуванням має значенняnull, і залишення його null або порожнім саме тому, що попередній приклад не створив геометрії.ConversionOptions.DestinationDriverOptionsмає типDriverOptions, базовий клас для об’єкта налаштувань кожного драйвера. ПередачаCsvOptions, коли цільовий драйвер —Drivers.Csv, саме забезпечує застосування налаштування; передача параметрів неправильного типу для драйвера викликаєArgumentException.- Той самий екземпляр
CsvOptionsвикористовується повторно на стороні читання. Без нього CSV‑драйвер не має підстав розглядатиGeometryWktяк щось інше, ніж звичайний стовпець‑рядок. IGeometry.AsText()повертає представлення ISO WKT, тому надрукований результат відповідає тому, що було записано у файл.
Симетрія — це суть: стовпці атрибутів поводяться ідентично, незалежно від того, чи включена геометрія, тому ви можете вмикати та вимикати стовпець WKT, не торкаючись решти вашого конвеєра.
Перепроектування під час конвертації
Якщо система‑споживач очікує певну систему координат, запитайте її як частину конвертації, а не під час пост‑обробки CSV. ConversionOptions містить просторове посилання разом з параметрами драйвера:
var conversionOptions = new ConversionOptions
{
DestinationDriverOptions = new CsvOptions { ColumnWkt = "GeometryWkt" },
DestinationSpatialReferenceSystem = SpatialReferenceSystem.Wgs84
};
VectorLayer.Convert(sourcePath, Drivers.TopoJson, destinationPath, Drivers.Csv, conversionOptions);
Не кожен драйвер призначення підтримує всі системи просторових посилань. Спочатку викличте Drivers.Csv.SupportsSpatialReferenceSystem(...), якщо цільова система може бути налаштована під час виконання, і, якщо вона не підтримується, поверніться до об’єкта параметрів зі значенням null.
Пакетне перетворення папки файлів TopoJSON
API ідентичний для одного файлу і для тисячі. Єдине правило, яке варто пам’ятати під час паралелізації, — кожен воркер потребує власних об’єктів layer і options.
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}");
}
});
}
Перехоплення GisException для кожного файлу замість навколо всього циклу означає, що один пошкоджений файл TopoJSON записує попередження замість того, щоб перервати пакет.
Отримати безкоштовну ліцензію
Aspose.GIS працює в режимі оцінки, доки не буде застосована ліцензія. Запросіть безкоштовну тимчасову ліцензію на сторінці тимчасової ліцензії Aspose і застосуйте її один раз під час запуску програми, перед будь‑яким іншим викликом Aspose.GIS:
var license = new Aspose.Gis.License();
license.SetLicense("Aspose.GIS.NET.lic");
Безкоштовні додаткові ресурси
Висновок
Перетворення TopoJSON з вкладеними властивостями у CSV у .NET зводиться до однієї корисної поведінки: Aspose.GIS розгортає вкладені об’єкти атрибутів у названі стовпці, наприклад prop1_this, під час читання шару, тому VectorLayer.Convert не потребує спеціальної логіки для їх збереження. Додайте CsvOptions.ColumnWkt, коли нижчестояща система потребує геометрії, додайте DestinationSpatialReferenceSystem, коли потрібна конкретна проекція, і повторюйте той самий виклик у циклі, коли потрібно обробити папку. Результатом є плоска, готова до аналізу таблиця, створена кількома рядками C#, без необхідності підтримувати власний шар парсингу JSON.
Часті запитання
Чи може Aspose.GIS сплющувати вкладені об’єкти JSON під час конвертації у CSV?
Так. Драйвер TopoJSON представляє вкладений об’єкт атрибутів як окремі стовпці, коли шар відкривається, об’єднуючи імена батька та дитини підкресленням, тому сплющування вже виконано до запуску конвертації.Чи потрібно писати власний код для обробки вкладених властивостей? Ні.
VectorLayer.Convertзаписує всі стовпці, які надає вихідний шар, тому вкладені властивості не потребують додаткового коду парсингу з вашого боку.Як я можу включити геометрію у CSV‑вивід? Створіть екземпляр
CsvOptions, встановіть його властивістьColumnWktу назву стовпця, яку ви хочете, призначте йогоConversionOptions.DestinationDriverOptionsі передайте його вVectorLayer.Convert.Чому геометрія порожня, коли я читаю свій CSV назад? CSV не має стовпця геометрії, якщо ви явно не запитаєте його. Встановіть
ColumnWktуCsvOptions, які ви передаєте як під час запису, так і під час читання, інакше драйвер не матиме стовпця, з якого можна створити геометрію.Які виключення слід обробляти під час перетворення? Документовані виключення:
ArgumentNullExceptionдля null шляху,ArgumentExceptionколи об’єкт параметрів не відповідає драйверу,GisExceptionколи функція не може бути прочитана з файлу, таIOExceptionдля помилок нижчого рівня вводу/виводу.Чи можу я конвертувати пакет TopoJSON файлів одночасно? Так. Пройдіться по списку файлів і викличте
VectorLayer.Convertдля кожного файлу. Якщо ви паралелізуєте цикл, дайте кожному робітнику його власний екземплярVectorLayerта параметрів, а не діліться одним між потоками.Чи змінює конвертація систему координат? За замовчуванням — ні. Щоб виконати репроекцію під час конвертації, встановіть
ConversionOptions.DestinationSpatialReferenceSystemу цільову систему перед викликомConvert.
