אתה מריץ המרת קבצי Shapefile שכבר הצליחה מאה פעמים, והפעם היא נעצרת עם TransformationException. אין פלט חלקי ואין אינדיקציה ברורה לאיזה רשומה גרמה לבעיה. לעיתים הקרבן הוא קואורדינטה לא חוקית אחת שנקברה בין אלפי תכונות תקינות. מאמר זה מסביר מדוע המרת Shapefile נכשלת עם השגיאה הזו ואיך לתקן זאת ב‑C# באמצעות OperationErrorCollector, שהוצג ב‑Aspose.GIS for .NET 26.6. תלמד איך לאפשר להמרה להסתיים, לשמור כל תכונה תקינה, ולקבל דוח מדויק של הרשומות שדורשות תשומת לב.

אם אתה צריך רק את קוד ההמרה הבסיסי, ראה המרת Shapefile ל‑KML ב‑C#. מדריך זה מבוסס על זה ומתמקד בטיפול בשגיאות.

מדוע המרת Shapefile גורמת ל-TransformationException

רוב פורמטי היעד מצפים לקואורדינטות במערכת קואורדינטות ספציפית. KML, למשל, תמיד משתמש ב‑WGS 84 של קו רוחב וקו אורך. במהלך ההמרה, Aspose.GIS ממיר כל קואורדינטה ממערכת הקואורדינטות המקורית למערכת היעד. אם קואורדינטה כלשהי אינה ניתנת להמרה, הספרייה זורקת TransformationException וההמרה נעצרת.

הסיבות הנפוצות ביותר הן:

  • ערכי מציין מקום “אין נתונים”. חלק מהכלים כותבים ערך סנטינל במקום להשאיר גאומטריה ריקה. קובץ הדוגמה במאמר זה מכיל נקודה ב‑(-1.7976931348623157E+308, -1.7976931348623157E+308), הערך המינימלי של double, שאף מערכת קואורדינטות אינה יכולה להמיר.
  • קואורדינטות מחוץ לטווח. ערכים שנופלים מחוץ לאזור התקף של מערכת הקואורדינטות המקורית, לרוב נגרמים משגיאות קלט נתונים או המרות יחידות שגויות.
  • קובץ .prj שאינו תואם לנתונים. אם קואורדינטות ממופות במטרים מוגדרות כקואורדינטות גאוגרפיות במעלות, ערכים רבים מסתיימים רחוק מחוץ לטווח התקף.
  • רשומות גאומטריה פגומות. ייצוא ישן וקבצים פגומים יכולים להכיל ערכי מספרים לא תקינים ברשומות בודדות.

בכל מקרה, הבעיה מוגבלת בדרך כלל למספר מצומצם של רשומות, אך ההתנהגות המוגדרת כברירת מחדל מסירה את כל ההמרה.

למה תכונה זו חשובה

עצירה על הכשל הראשון היא בטוחה, אך היא יקרה בצינורות אמיתיים. רשומה פגומה אחת מכריחה אותך לנקות את הקובץ ידנית לפני שניתן להמיר כל נתון, והחריגה עצמה אינה מודיעה לך כמה רשומות אחרות מושפעות. עם אפשרות איסוף השגיאות מופעלת, אתה יכול:

  • המרת כל התכונות התקינות במקום לאבד את כל הקובץ ברשומה אחת פגומה.
  • תעד את האינדקס והקואורדינטות של כל תכונה שהודחה כדי שניתן יהיה לתקן את נתוני המקור.
  • הפעל המרות אצווה ו‑ETL ללא פיקוח ללא קריסה בקלט מלוכלך.
  • קבל קבצי Shapefile שהועלו על ידי משתמשים בשירותי רשת ודווח על בעיות נתונים בחזרה למשתמש.

כיצד לתקן כשלי המרת Shapefile ב‑C# עם Aspose.GIS

Aspose.GIS for .NET היא ספרייה מנוהלת לקריאה, כתיבה והמרה של פורמטים גאוגרפיים כגון Shapefile, KML, GeoJSON, GML, ו‑File Geodatabase ללא צורך בתוכנת GIS אחרת מותקנת. איסוף שגיאות דורש גרסה 26.6 או מאוחרת יותר. התקן את החבילה מ‑NuGet:

dotnet add package Aspose.GIS

או השתמשו בקונסול של מנהל החבילות:

Install-Package Aspose.GIS

הסוגים הבאים משמשים במדריך זה:

  • VectorLayer (Aspose.Gis): פותח, יוצר וממיר שכבות וקטור. VectorLayer.Convert מבצע את ההמרה.
  • ConversionOptions (Aspose.Gis): מחזיק הגדרות המרה, כולל DestinationDriverOptions ו-DestinationSpatialReferenceSystem.
  • KmlOptions (Aspose.Gis.Formats.Kml): אפשרויות מנהג KML. הוא יורש את המאפיין ErrorCollector מ-DriverOptions.
  • OperationErrorCollector (Aspose.Gis.Operations): מאחסן שגיאות שניתן לשחזר. הוא מציג את Errors, Count, HasErrors, Add ו-Clear.
  • OperationError and TransformationError (Aspose.Gis.Operations): לכל שגיאה יש Message ו-Exception. TransformationError מוסיף FeatureIndex, X, Y ו-Z.
  • TransformationException (Aspose.Gis.SpatialReferencing): נזרק כאשר קואורדינטה לא ניתנת להמרה ואין אוסף מצורף.

איך לתקן TransformationException במהלך המרת Shapefile

התיקון מורכב משני חלקים. ראשית, צרף OperationErrorCollector כך שההמרה תדלג על תכונות לא תקינות במקום להיכשל. שנית, השתמש בדוח שנאסף כדי לתקן או להסיר את הרשומות במקור. השלבים למטה משתמשים בדוגמה של המרת Shapefile ל‑KML.

1. הכן את הסביבה

  1. צור פרויקט קונסול .NET והוסף את חבילת NuGet Aspose.GIS 26.6+.
  2. העתק את קובץ ה‑Shapefile ואת קבצי הליווי שלו (.shp, .shx, .dbf, ו‑.prj) לתיקייה אחת. בדוגמה זו נעשה שימוש ב‑data/light-traffics.shp.
  3. הוסף את המרחבים הנדרשים:
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;

2. צור OperationErrorCollector

האוסף מתעד כל שגיאה שניתנת לשחזור שנוצרה במהלך ההמרה. צור מופע חדש עבור כל המרה כדי שהשגיאות מקבצים שונים לא יתערבבו יחד.

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

3. צירוף ה-Collector דרך ConversionOptions

הקצה את האוסף ל-KmlOptions.ErrorCollector, ולאחר מכן העבר את אפשרויות KML כ-DestinationDriverOptions. הגדרת DestinationSpatialReferenceSystem ל‑WGS 84 היא אופציונלית עבור KML, אך היא עושה את מערכת הקואורדינטות של היעד ברורה בקוד שלך.

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. הפעל את ההמרה

קרא VectorLayer.Convert עם נתיב המקור, מנהל ההתקן של Shapefile, נתיב היעד, מנהל ההתקן של KML, והאפשרויות שהגדרת זה עתה.

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

כאשר תכונה אינה ניתנת להמרה, מנהל ההתקן KML מוסיף שגיאה למאגרים, מדלג על אותה תכונה וממשיך עם הבאה. לא נזרקת TransformationException.

5. דווח על תכונות שהושמטו וודא את הפלט

המרה שמחזירה באופן רגיל עדיין עשויה לדלג על תכונות, ולכן תמיד יש לבדוק את האוסף לאחר מכן. המר כל שגיאה ל-TransformationError כדי לקבל את אינדקס התכונה ואת הקואורדינטה שהכשלו, ואז פתח את קובץ הפלט כדי לאשר כמה תכונות נכתבו.

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

בקובץ הדוגמה, האוסף רושם שגיאה אחת עבור נקודת המיקום המוחלפת, והמאפיינים הנותרים (לפחות 444) נכתבים לקובץ KML.

האינדקס של הפיצ’ר והקואורדינטות בדו״ח זה משלים את התיקון. פתח את קובץ ה‑Shapefile המקורי בתהליך ניקוי הנתונים שלך, מצא את הרשומות המדווחות ותקן או מחק אותן. אם רשומות רבות נכשלות עם ערכים שנראים סבירים, בדוק תחילה את הקובץ .prj, מכיוון שמערכת קואורדינטות לא תואמת היא הסיבה הסבירה.

6. קוד לדוגמה מלא

היישום הקונסול המלא למטה מריץ את ההמרה פעמיים. הריצה הראשונה משתמשת בהגדרות ברירת המחדל ומשחזרת את TransformationException. הריצה השנייה מצרפת OperationErrorCollector, מדלגת על התכונה הלא תקינה ומדפיסה דוח.

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. בעיות נפוצות וכיצד להימנע מהן

בעיהסיבהפתרון
ErrorCollector or OperationErrorCollector אינו מתקמפלשניהם נוספו ב Aspose.GIS for .NET 26.6.שדרג את חבילת NuGet לגרסה 26.6 או מאוחרת יותר.
ההמרה עדיין זורקת TransformationExceptionלא מצורף collector לאפשרויות מנהל ההתקן של היעד.הגדר ErrorCollector על אובייקט אפשרויות מנהל ההתקן שהוקצה ל-ConversionOptions.DestinationDriverOptions.
המרה “מוצלחת” חסרה תכונותה-collector מדכא את החריגה, ולכן Convert מחזיר תוצאה רגילה.בדוק errors.HasErrors אחרי כל קריאה ותעד את התוצאות.
התייחסות לתכונות שהדולגו כמתוקנותה-collector מדלג על רשומות לא תקינות; הוא אינו מתקן אותן.השתמש במפתח התכונה והקואורדינטות המדווחים כדי לתקן או להסיר רשומות בנתוני המקור.
מאות תכונות נכשלות בבת אחתקובץ ה-.prj ככל הנראה אינו תואם לקואורדינטות האמיתיות.אמת את מערכת הקואורדינטות של המקור לפני חקירת רשומות בודדות.
שגיאות ממספר קבצים מופיעות בדוח אחדאותו מופע של collector שומש מחדש בין המרות.צור OperationErrorCollector חדש לכל קובץ, או קרא Clear() בין הריצות.
שגיאות נעילת קובץ בריצות חוזרותשכבה שנפתחה עם VectorLayer.Open לא שוחררה.עטוף את VectorLayer.Open בבלוק using.

קבל רישיון חינמי

ניתן לקבל רישיון חינמי זמני עבור Aspose.GIS מדף הרישיון הזמני של Aspose: https://purchase.aspose.com/temporary-license/

משאבים נוספים בחינם

סיכום

שגיאת TransformationException במהלך המרת Shapefile בדרך כלל משמעותה שמספר קטן של רשומות מכילות קואורדינטות שלא ניתן להמיר, כגון ערכי מציין מקום, מספרים מחוץ לטווח, או נתונים שאינם תואמים לקובץ .prj שלה. תיקון הבעיה ב‑C# דורש שני שלבים: לצרף OperationErrorCollector כך ש‑Aspose.GIS for .NET ידלג על תכונות לא תקינות ויסיים את ההמרה, ולאחר מכן להשתמש באינדקסים ובקואורדינטות שנאספו כדי לתקן את הנתונים המקוריים. התוצאה היא צינור עבודה שממשיך לספק פלט תקף תוך הפיכת כשלונות קשים לדוחות איכות נתונים שניתן לפעול על פיהם.

שאלות נפוצות

  1. מדוע מתרחשת TransformationException בעת המרת Shapefile? זה קורה כאשר קואורדינטה לא ניתנת להמרה ממערכת הקואורדינטות המקורית למערכת היעד. הגורמים הנפוצים הם ערכי מציין מקום “no data”, קואורדינטות מחוץ לטווח התקף של מערכת הקואורדינטות שלהן, קובץ .prj שאינו תואם לנתונים האמיתיים, ורשומות גיאומטריה פגומות.

  2. מה קורה כברירת מחדל כאשר קואורדינטה לא ניתנת להמרה?
    VectorLayer.Convert זורק TransformationException וההמרה נעצרת. החל מגרסה 26.6, החריגה גם חושפת את ערכי X, Y, ו-Z של הקואורדינטה שנכשלה.

  3. איזו גרסה של Aspose.GIS for .NET תומכת ב-OperationErrorCollector? OperationErrorCollector והמאפיין DriverOptions.ErrorCollector הוצגו ב‑Aspose.GIS for .NET 26.6. גרסאות קודמות אינן כוללות אותם.

  4. האם OperationErrorCollector מתקן קואורדינטות לא חוקיות? לא. הוא מדלג על הפיצ’רים שנכשלו בהמרה ורושם אותם, ולכן הפלט מכיל רק פיצ’רים תקינים. השתמש באינדקס הפיצ’ר המדווח ובקואורדינטות כדי לתקן או להסיר את הרשומות השגויות בנתוני המקור.

  5. האם ניתן להשתמש ב‑OperationErrorCollector עם פורמטים של פלט אחרים מ‑KML? ErrorCollector מוגדר במחלקת הבסיס DriverOptions, ולכן כל מחלקת אפשרויות מנהק חושפת אותו. דוגמאות מתועדות מכסות יעדי KML ו‑MapInfo TAB; יש לבדוק את ההתנהגות עם מנהק היעד שלכם לפני ההסתמכות עליו בייצור.

  6. אילו פרטים מכיל כל שגיאה שנאספה? כל OperationError מספק Message ואת ה-Exception הבסיסי. כישלונות במרה מדווחים כאובייקטים TransformationError, שמוסיפים את FeatureIndex ואת ערכי X, Y ו-Z של הקואורדינטה הכושלת.

  7. איך אני יודע אם המרה הושלמה ללא שגיאות? בדוק את המאפיין HasErrors או Count של האוסף אחרי שה‑VectorLayer.Convert מחזיר. המרה שמסתיימת ללא זריקה של חריגה עדיין עשויה לדלג על תכונות.

קרא עוד