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 וה‑assembly נקראות 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)כאשר ייתכן שהעמודה חסרה או ריקה, מכיוון ש-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 driver אין סיבה להתייחס ל‑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(...) תחילה אם המערכת היעד ניתנת להגדרה בזמן ריצה, והחזר לאובייקט אפשרויות ריק כאשר היא אינה נתמכת.
המרה קבוצתית של תיקייה של קבצי TopoJSON
ה-API זהה לקובץ אחד ולאלף קבצים. הכלל היחיד שכדאי לזכור כאשר ממקבילים הוא שכל עובד צריך את שכבתו ואת אובייקטי האפשרויות שלו.
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שאתה מעביר גם בכתיבה וגם בקריאה, אחרת ל‑driver אין עמודה שממנה לבנות גיאומטריה.אילו חריגות עלי לטפל במהלך ההמרה? המתועדות הן
ArgumentNullExceptionעבור נתיב ריק,ArgumentExceptionכאשר אובייקט האפשרויות אינו תואם למנהל ההתקן,GisExceptionכאשר תכונה לא ניתנת לקריאה מהקובץ, ו-IOExceptionעבור תקלות קלט/פלט בסיסיות.האם אני יכול להמיר אצווה של קבצי TopoJSON בבת אחת? כן. חזור על רשימת הקבצים וקרא ל-
VectorLayer.Convertעבור כל קובץ. אם אתה ממקביל את הלולאה, תן לכל עובד את ה-VectorLayerוהאופציות שלו במקום לשתף אחד בין חוטים.האם ההמרה משנה את מערכת הקואורדינטות? לא באופן ברירת מחדל. כדי לבצע רפרויקט במהלך ההמרה, הגדר
ConversionOptions.DestinationSpatialReferenceSystemלמערכת היעד לפני קריאתConvert.
