أنت تقوم بتنفيذ تحويل Shapefiles الذي نجح مئات المرات، ولكن هذه المرة يتوقف مع TransformationException. لا يوجد إخراج جزئي ولا إشارة واضحة إلى السجل الذي تسبب في المشكلة. غالبًا ما يكون السبب إحداثيًا غير صالح واحد مدفون بين آلاف الميزات الصالحة. توضح هذه المقالة لماذا يفشل تحويل Shapefile مع هذا الخطأ وكيفية إصلاحه في C# باستخدام OperationErrorCollector، الذي تم تقديمه في Aspose.GIS for .NET 26.6. ستتعلم كيفية السماح للتحويل بالانتهاء، الاحتفاظ بكل ميزة صالحة، والحصول على تقرير دقيق للسجلات التي تحتاج إلى اهتمام.
إذا كنت تحتاج فقط إلى كود التحويل الأساسي، راجع Convert Shapefile to KML in C#. يَبني هذا الدليل على ذلك ويركّز على معالجة الأخطاء.
لماذا ينتج عن تحويل Shapefile استثناء TransformationException
معظم صيغ الهدف تتوقع إحداثيات في نظام إحداثيات محدد. على سبيل المثال، KML دائمًا يستخدم خطوط الطول والعرض بنظام WGS 84. أثناء التحويل، تقوم Aspose.GIS بتحويل كل إحداثية من نظام الإحداثيات المصدر إلى نظام الهدف. إذا تعذر تحويل أي إحداثية، فإن المكتبة تُطلق استثناء TransformationException ويتوقف التحويل.
الأسباب الأكثر شيوعًا هي:
- قيم العنصر النائب “no data”. بعض الأدوات تكتب قيمة إشارة بدلاً من ترك الشكل الهندسي فارغًا. يحتوي ملف العينة في هذه المقالة على نقطة عند
(-1.7976931348623157E+308, -1.7976931348623157E+308), وهو الحد الأدنى لقيمةdouble، والتي لا يمكن لأي نظام إحداثيات تحويلها. - إحداثيات خارج النطاق. القيم التي تقع خارج المنطقة الصالحة لنظام الإحداثيات المصدر، غالبًا ما تكون ناتجة عن أخطاء إدخال البيانات أو تحويلات وحدات سيئة.
- ملف
.prjلا يتطابق مع البيانات. إذا تم إعلان الإحداثيات المُسقطة بالمتر كإحداثيات جغرافية بالدرجات، فإن العديد من القيم تنتهي بعيدًا خارج النطاق الصالح. - سجلات هندسية تالفة. يمكن أن تحتوي الصادرات القديمة والملفات التالفة على قيم رقمية غير صالحة في سجلات فردية.
في كل حالة، عادةً ما تكون المشكلة محدودة بعدد قليل من السجلات، ومع ذلك يتجاهل السلوك الافتراضي التحويل بأكمله.
لماذا هذه الميزة مهمة
التوقف عند أول فشل هو أمر آمن، لكنه مكلف في خطوط الأنابيب الحقيقية. سجل واحد سيء يجبرك على تنظيف الملف يدويًا قبل أن يتم تحويل أي بيانات، والاستثناء وحده لا يخبرك بعدد السجلات الأخرى المتأثرة. مع تمكين جمع الأخطاء، يمكنك:
- تحويل جميع الميزات الصالحة بدلاً من فقدان الملف بأكمله لسجل واحد سيء.
- تسجيل الفهرس والإحداثيات لكل ميزة تم تخطيها حتى يمكن إصلاح بيانات المصدر.
- تشغيل عمليات التحويل الدفعي غير المراقبة ومهام ETL دون التعطل عند وجود مدخلات غير نظيفة.
- قبول ملفات Shapefiles التي يرفعها المستخدم في خدمات الويب والإبلاغ عن مشكلات البيانات للمستخدم.
كيفية إصلاح فشل تحويل ملفات 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 و TransformationError (
Aspose.Gis.Operations): كل خطأ يحتوي علىMessageوException.TransformationErrorيضيفFeatureIndex،X،Y، وZ. - TransformationException (
Aspose.Gis.SpatialReferencing): يُرمى عندما لا يمكن تحويل إحداثية ولا يوجد جامع مرفق.
كيفية إصلاح TransformationException أثناء تحويل Shapefile
الإصلاح يتألف من جزأين. أولاً، إرفاق OperationErrorCollector بحيث يتخطى التحويل الميزات غير الصالحة بدلاً من الفشل. ثانياً، استخدم التقرير المجمّع لإصلاح أو إزالة تلك السجلات في المصدر. الخطوات أدناه تستخدم تحويل Shapefile إلى KML كمثال.
1. إعداد البيئة
- أنشئ مشروع وحدة تحكم .NET وأضف حزمة NuGet الخاصة بـ Aspose.GIS 26.6+.
- انسخ ملف Shapefile والملفات المصاحبة له (
.shp،.shx،.dbf، و.prj) إلى مجلد واحد. يستخدم هذا المثال الملفdata/light-traffics.shp. - أضف المساحات الاسمية المطلوبة:
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. تشغيل التحويل
استدعِ 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 أو OperationErrorCollector لا يتم تجميعه | كلاهما تمت إضافتهما في Aspose.GIS for .NET 26.6. | قم بترقية حزمة NuGet إلى الإصدار 26.6 أو أحدث. |
ما زال التحويل يطرح TransformationException | لم يتم إرفاق أي جامع بخيارات برنامج تشغيل الوجهة. | قم بتعيين ErrorCollector على كائن خيارات برنامج التشغيل المخصص لـ ConversionOptions.DestinationDriverOptions. |
| تحويل “ناجح” يفتقد إلى ميزات | يقوم الجامع (collector) بكتم الاستثناء، لذا تعود الدالة Convert بشكل طبيعي. | تحقق من errors.HasErrors بعد كل استدعاء وسجِّل النتائج. |
| معاملة الميزات المتخطاة كأنها مُصَحَّحة | الجامع يتخطى السجلات غير الصالحة؛ ولا يقوم بإصلاحها. | استخدم فهرس الميزة والإحداثيات المبلّغ عنها لتصحيح أو إزالة السجلات في البيانات المصدر. |
| مئات الميزات تفشل مرة واحدة | من المحتمل أن ملف .prj لا يتطابق مع الإحداثيات الفعلية. | تحقق من نظام الإحداثيات المصدر قبل فحص السجلات الفردية. |
| الأخطاء من عدة ملفات تظهر في تقرير واحد | تم إعادة استخدام نفس كائن الجامع عبر عمليات التحويل. | أنشئ OperationErrorCollector جديد لكل ملف، أو استدعِ Clear() بين عمليات التشغيل. |
| أخطاء قفل الملف عند تشغيلات متكررة | لم يتم تحرير الطبقة المفتوحة باستخدام VectorLayer.Open. | ضع VectorLayer.Open داخل كتلة using. |
احصل على ترخيص مجاني
يمكنك الحصول على ترخيص مجاني مؤقت لـ Aspose.GIS من صفحة الترخيص المؤقتة الخاصة بـ Aspose: https://purchase.aspose.com/temporary-license/
موارد إضافية مجانية
- الوثائق: https://docs.aspose.com/gis/net/
- مرجع API: https://reference.aspose.com/gis/net/
- تطبيقات ويب مجانية: https://products.aspose.app/gis/family
الخلاصة
عادةً ما يعني حدوث TransformationException أثناء تحويل Shapefile أن عددًا صغيرًا من السجلات يحتوي على إحداثيات لا يمكن تحويلها، مثل قيم العنصر النائب، أو أرقام خارج النطاق، أو بيانات لا تتطابق مع ملف .prj الخاص بها. إصلاح ذلك في C# يتطلب خطوتين: إرفاق OperationErrorCollector حتى يتخطى Aspose.GIS for .NET الميزات غير الصالحة ويكمل التحويل، ثم استخدام فهارس الميزات والإحداثيات التي تم جمعها لإصلاح البيانات المصدرية. النتيجة هي خط أنابيب يستمر في تقديم مخرجات صالحة بينما يحول الفشل الحاد إلى تقارير جودة بيانات قابلة للتنفيذ.
الأسئلة المتكررة
لماذا يحدث TransformationException عند تحويل ملف Shapefile؟
يحدث ذلك عندما لا يمكن تحويل إحداثية من نظام الإحداثيات المصدر إلى النظام الهدف. الأسباب الشائعة هي قيم placeholder “no data”، إحداثيات خارج النطاق الصالح لنظام إحداثياتها، ملف.prjلا يتطابق مع البيانات الفعلية، وسجلات هندسية تالفة.ماذا يحدث بشكل افتراضي عندما لا يمكن تحويل إحداثي؟
VectorLayer.ConvertيرميTransformationExceptionويتوقف التحويل. بدءًا من الإصدار 26.6، يكشف الاستثناء أيضًا عن قيمXوYوZللإحداثي الذي فشل.أي نسخة من Aspose.GIS for .NET تدعم OperationErrorCollector؟
OperationErrorCollectorو الخاصيةDriverOptions.ErrorCollectorتم تقديمهما في Aspose.GIS for .NET 26.6. الإصدارات السابقة لا تشملهما.هل يقوم OperationErrorCollector بإصلاح الإحداثيات غير الصالحة؟ لا. يتخطى العناصر التي تفشل في التحويل ويسجلها، وبالتالي يحتوي الناتج على عناصر صالحة فقط. استخدم فهرس العنصر والإحداثيات المبلغ عنها لإصلاح أو إزالة السجلات السيئة في بيانات المصدر.
هل يمكنني استخدام OperationErrorCollector مع تنسيقات الإخراج غير KML؟
ErrorCollectorمعرف في الفئة الأساسيةDriverOptions، لذا كل فئة خيارات السائق تكشف عنه. تغطي الأمثلة الموثقة وجهات KML وMapInfo TAB؛ اختبر السلوك مع السائق الهدف الخاص بك قبل الاعتماد عليه في الإنتاج.ما هي التفاصيل التي يحتويها كل خطأ تم جمعه؟ كل
OperationErrorيوفرMessageوExceptionالأساسي. يتم الإبلاغ عن فشل التحويل ككائناتTransformationError، والتي تضيفFeatureIndexوقيمXوYوZللإحداثية الفاشلة.كيف يمكنني معرفة ما إذا كانت عملية التحويل قد اكتملت دون أي أخطاء؟ تحقق من خاصية
HasErrorsأوCountللمجمع بعد عودةVectorLayer.Convert. قد تنتهي عملية التحويل دون رمي استثناء ولكنها لا تزال قد تخطت بعض الميزات.
