شما یک تبدیل Shapefiles را اجرا می‌کنید که صد بار موفق بوده است، اما این بار با یک 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 Aspise.GIS

یا از Package Manager Console استفاده کنید:

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. اتصال جمع‌کننده از طریق 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. اجرای تبدیل

با مسیر منبع، درایور Shapefile، مسیر مقصد، درایور KML و گزینه‌هایی که همین‌اکنون پیکربندی کرده‌اید، VectorLayer.Convert را فراخوانی کنید.

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

برای فایل نمونه، جمع‌کننده یک خطا برای نقطهٔ جای‌دار ثبت می‌کند و ویژگی‌های باقی‌مانده (حداقل ۴۴۴) در فایل 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 یا OperationErrorCollector کامپایل نمی‌شودهر دو در Aspose.GIS for .NET نسخه ۲۶.۶ اضافه شده‌اند.پکیج NuGet را به نسخه ۲۶.۶ یا بالاتر ارتقا دهید.
تبدیل همچنان TransformationException را پرتاب می‌کندهیچ جمع‌کننده‌ای به گزینه‌های درایور مقصد متصل نشده است.ErrorCollector را روی شیء گزینه‌های درایور که به ConversionOptions.DestinationDriverOptions اختصاص داده شده است تنظیم کنید.
یک تبدیل «موفق» ویژگی‌هایی را از دست می‌دهدجمع‌کننده استثنا را سرکوب می‌کند، بنابراین Convert به‌طور معمول باز می‌گردد.پس از هر فراخوانی errors.HasErrors را بررسی کنید و نتایج را ثبت کنید.
در نظر گرفتن ویژگی‌های صرف‌نظر شده به‌عنوان اصلاح‌شدهجمع‌کننده رکوردهای نامعتبر را نادیده می‌گیرد؛ آن‌ها را تعمیر نمی‌کند.از اندیس ویژگی گزارش‌شده و مختصات برای اصلاح یا حذف رکوردها در داده‌های منبع استفاده کنید.
صدها ویژگی به‌صورت همزمان شکست می‌خورندبه‌نظر می‌رسد فایل .prj با مختصات واقعی مطابقت ندارد.سیستم مختصات منبع را پیش از بررسی رکوردهای جداگانه تأیید کنید.
خطاهای چندین فایل در یک گزارش ظاهر می‌شوندنمونهٔ یکسان جمع‌کننده در تبدیل‌های مختلف دوباره استفاده شده بود.برای هر فایل یک OperationErrorCollector جدید ایجاد کنید یا بین اجراها Clear() را فراخوانی کنید.
خطاهای قفل‌گذاری فایل در اجراهای مکررلایه‌ای که با VectorLayer.Open باز شده بود، آزاد (Dispose) نشده بود.VectorLayer.Open را در یک بلوک using بپیچید.

دریافت یک لایسنس رایگان

می‌توانید یک مجوز موقت رایگان برای Aspose.GIS از صفحه مجوز موقت Aspose دریافت کنید: https://purchase.aspose.com/temporary-license/

منابع اضافی رایگان

نتیجه‌گیری

یک TransformationException در حین تبدیل Shapefile معمولاً به این معنی است که تعداد کمی از رکوردها شامل مختصاتی هستند که نمی‌توانند تبدیل شوند، مانند مقادیر جایگزین، اعداد خارج از محدوده، یا داده‌هایی که با فایل .prj آن مطابقت ندارند. رفع این مشکل در C# دو مرحله نیاز دارد: یک OperationErrorCollector را متصل کنید تا Aspose.GIS for .NET ویژگی‌های نامعتبر را نادیده بگیرد و تبدیل را تکمیل کند، سپس از شاخص‌ها و مختصات ویژگی‌های جمع‌آوری‌شده برای تعمیر داده‌های منبع استفاده کنید. نتیجه یک خط لوله است که به‌صورت مداوم خروجی معتبر ارائه می‌دهد و در عین حال شکست‌های جدی را به گزارش‌های قابل اقدام درباره کیفیت داده تبدیل می‌کند.

سوالات متداول

  1. چرا هنگام تبدیل یک Shapefile استثنای TransformationException رخ می‌دهد؟
    این خطا زمانی رخ می‌دهد که یک مختصات نتواند از سیستم مختصات منبع به سیستم هدف تبدیل شود. علل رایج شامل مقادیر جایگزین «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. چگونه می‌توانم بفهمم که یک تبدیل بدون هیچ خطایی تکمیل شده است؟ پس از بازگشت VectorLayer.Convert، ویژگی HasErrors یا Count جمع‌کننده را بررسی کنید. یک تبدیل که بدون پرتاب استثنا به پایان می‌رسد ممکن است هنوز ویژگی‌هایی را نادیده گرفته باشد.

بیشتر بخوانید