You run a Shapefiles conversion that has worked a hundred times, and this time it stops with a TransformationException. There is no partial output and no clear indication of which record caused the problem. Often the culprit is a single invalid coordinate buried among thousands of valid features. This article explains why Shapefile conversion fails with this error and how to fix it in C# using OperationErrorCollector, introduced in Aspose.GIS for .NET 26.6. You will learn how to let the conversion finish, keep every valid feature, and get a precise report of the records that need attention.
If you only need the basic conversion code, see Convert Shapefile to KML in C#. This guide builds on that and focuses on handling the errors.
Why Shapefile Conversion Throws TransformationException
Most target formats expect coordinates in a specific coordinate system. KML, for example, always uses WGS 84 longitude and latitude. During conversion, Aspose.GIS transforms every coordinate from the source coordinate system into the target one. If any coordinate cannot be transformed, the library throws a TransformationException and the conversion stops.
The most common causes are:
- Placeholder “no data” values. Some tools write a sentinel value instead of leaving a geometry empty. The sample file in this article contains a point at
(-1.7976931348623157E+308, -1.7976931348623157E+308), the minimum value of adouble, which no coordinate system can transform. - Out-of-range coordinates. Values that fall outside the valid area of the source coordinate system, often caused by data-entry errors or bad unit conversions.
- A
.prjfile that does not match the data. If projected coordinates in meters are declared as geographic coordinates in degrees, many values end up far outside the valid range. - Corrupted geometry records. Legacy exports and damaged files can contain invalid numeric values in individual records.
In every case, the problem is usually limited to a handful of records, yet the default behavior discards the entire conversion.
Why This Feature Matters
Stopping at the first failure is safe, but it is costly in real pipelines. One bad record forces you to clean the file by hand before any data can be converted, and the exception alone does not tell you how many other records are affected. With error collection enabled, you can:
- Convert all valid features instead of losing the whole file to one bad record.
- Log the index and coordinates of every skipped feature so the source data can be repaired.
- Run unattended batch conversions and ETL jobs without crashing on dirty input.
- Accept user-uploaded Shapefiles in web services and report data problems back to the user.
How to Fix Shapefile Conversion Failures in C# with Aspose.GIS
Aspose.GIS for .NET is a managed library for reading, writing, and converting geospatial formats such as Shapefile, KML, GeoJSON, GML, and File Geodatabase without any other GIS software installed. Error collection requires version 26.6 or later. Install the package from NuGet:
dotnet add package Aspose.GIS
Or use the Package Manager Console:
Install-Package Aspose.GIS
The following types are used in this tutorial:
- VectorLayer (
Aspose.Gis): opens, creates, and converts vector layers.VectorLayer.Convertperforms the conversion. - ConversionOptions (
Aspose.Gis): holds conversion settings, includingDestinationDriverOptionsandDestinationSpatialReferenceSystem. - KmlOptions (
Aspose.Gis.Formats.Kml): KML driver options. It inherits theErrorCollectorproperty fromDriverOptions. - OperationErrorCollector (
Aspose.Gis.Operations): stores recoverable errors. It exposesErrors,Count,HasErrors,Add, andClear. - OperationError and TransformationError (
Aspose.Gis.Operations): each error has aMessageand anException.TransformationErroraddsFeatureIndex,X,Y, andZ. - TransformationException (
Aspose.Gis.SpatialReferencing): thrown when a coordinate cannot be transformed and no collector is attached.
How to Fix TransformationException During Shapefile Conversion
The fix has two parts. First, attach an OperationErrorCollector so the conversion skips invalid features instead of failing. Second, use the collected report to repair or remove those records at the source. The steps below use a Shapefile to KML conversion as the example.
1. Prepare the Environment
- Create a .NET console project and add the Aspose.GIS 26.6+ NuGet package.
- Copy the Shapefile and its companion files (
.shp,.shx,.dbf, and.prj) into one folder. This example usesdata/light-traffics.shp. - Add the required namespaces:
using System;
using System.IO;
using Aspose.Gis;
using Aspose.Gis.Formats.Kml;
using Aspose.Gis.Operations;
using Aspose.Gis.SpatialReferencing;
2. Create an OperationErrorCollector
The collector records every recoverable error raised during the conversion. Create a new instance for each conversion so that errors from different files are not mixed together.
// Records recoverable errors instead of throwing them.
var errors = new OperationErrorCollector();
3. Attach the Collector Through ConversionOptions
Assign the collector to KmlOptions.ErrorCollector, then pass the KML options as DestinationDriverOptions. Setting DestinationSpatialReferenceSystem to WGS 84 is optional for KML, but it makes the target coordinate system explicit in your code.
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. Run the Conversion
Call VectorLayer.Convert with the source path, the Shapefile driver, the destination path, the KML driver, and the options you just configured.
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);
When a feature cannot be transformed, the KML driver adds an error to the collector, skips that feature, and continues with the next one. No TransformationException is thrown.
5. Report Skipped Features and Verify the Output
A conversion that returns normally may still have skipped features, so always check the collector afterwards. Cast each error to TransformationError to get the feature index and the coordinate that failed, then open the output file to confirm how many features were written.
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}");
}
For the sample file, the collector records one error for the placeholder point, and the remaining features (at least 444) are written to the KML file.
The feature index and coordinates in this report complete the fix. Open the source Shapefile in your data-cleaning workflow, locate the reported records, and correct or remove them. If many records fail with reasonable-looking values, check the .prj file first, because a mismatched coordinate system is the likely cause.
6. Full Sample Code
The complete console application below runs the conversion twice. The first run uses default settings and reproduces the TransformationException. The second run attaches an OperationErrorCollector, skips the invalid feature, and prints a report.
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. Common Pitfalls and How to Avoid Them
| Pitfall | Reason | Fix |
|---|---|---|
ErrorCollector or OperationErrorCollector does not compile | Both were added in Aspose.GIS for .NET 26.6. | Upgrade the NuGet package to 26.6 or later. |
The conversion still throws TransformationException | No collector is attached to the destination driver options. | Set ErrorCollector on the driver options object assigned to ConversionOptions.DestinationDriverOptions. |
| A “successful” conversion is missing features | The collector suppresses the exception, so Convert returns normally. | Check errors.HasErrors after every call and log the results. |
| Treating skipped features as fixed | The collector skips invalid records; it does not repair them. | Use the reported feature index and coordinates to correct or remove records in the source data. |
| Hundreds of features fail at once | The .prj file likely does not match the actual coordinates. | Verify the source coordinate system before investigating individual records. |
| Errors from several files appear in one report | The same collector instance was reused across conversions. | Create a new OperationErrorCollector per file, or call Clear() between runs. |
| File-lock errors on repeated runs | A layer opened with VectorLayer.Open was not disposed. | Wrap VectorLayer.Open in a using block. |
Get a Free License
You can obtain a temporary free license for Aspose.GIS from the Aspose temporary‑license page: https://purchase.aspose.com/temporary-license/.
Free Additional Resources
- Documentation: https://docs.aspose.com/gis/net/
- API Reference: https://reference.aspose.com/gis/net/
- Free Web Apps: https://products.aspose.app/gis/family
Conclusion
A TransformationException during Shapefile conversion usually means a small number of records contain coordinates that cannot be transformed, such as placeholder values, out-of-range numbers, or data that does not match its .prj file. Fixing it in C# takes two steps: attach an OperationErrorCollector so Aspose.GIS for .NET skips invalid features and completes the conversion, then use the collected feature indexes and coordinates to repair the source data. The result is a pipeline that keeps delivering valid output while turning hard failures into actionable data-quality reports.
FAQs
Why does TransformationException occur when converting a Shapefile? It occurs when a coordinate cannot be transformed from the source coordinate system to the target one. Common causes are placeholder “no data” values, coordinates outside the valid range of their coordinate system, a
.prjfile that does not match the actual data, and corrupted geometry records.What happens by default when a coordinate cannot be transformed?
VectorLayer.Convertthrows aTransformationExceptionand the conversion stops. Starting with version 26.6, the exception also exposes theX,Y, andZvalues of the coordinate that failed.Which version of Aspose.GIS for .NET supports OperationErrorCollector?
OperationErrorCollectorand theDriverOptions.ErrorCollectorproperty were introduced in Aspose.GIS for .NET 26.6. Earlier versions do not include them.Does OperationErrorCollector repair invalid coordinates? No. It skips the features that fail transformation and records them, so the output contains only valid features. Use the reported feature index and coordinates to fix or remove the bad records in the source data.
Can I use OperationErrorCollector with output formats other than KML?
ErrorCollectoris defined on the baseDriverOptionsclass, so every driver options class exposes it. Documented examples cover KML and MapInfo TAB destinations; test the behavior with your own target driver before relying on it in production.What details does each collected error contain? Every
OperationErrorprovides aMessageand the underlyingException. Transformation failures are reported asTransformationErrorobjects, which add theFeatureIndexand theX,Y, andZvalues of the failing coordinate.How do I know whether a conversion completed without any errors? Check the collector’s
HasErrorsorCountproperty afterVectorLayer.Convertreturns. A conversion that finishes without throwing may still have skipped features.
