수백 번 성공적으로 수행해 온 Shapefiles 변환을 실행했지만 이번에는 TransformationException으로 중단됩니다. 부분 출력이 없으며 어떤 레코드가 문제를 일으켰는지 명확한 표시가 없습니다. 종종 원인은 수천 개의 유효한 피처 중에 숨겨진 단일 잘못된 좌표입니다. 이 문서에서는 Shapefile 변환이 이 오류와 함께 실패하는 이유와 Aspose.GIS for .NET 26.6에 도입된 OperationErrorCollector를 사용하여 C#에서 문제를 해결하는 방법을 설명합니다. 변환을 끝까지 진행하고 모든 유효한 피처를 유지하며, 주의가 필요한 레코드에 대한 정확한 보고서를 얻는 방법을 배울 수 있습니다.
기본 변환 코드만 필요하다면, C#에서 Shapefile을 KML로 변환을 참조하십시오. 이 가이드는 해당 내용을 기반으로 하며 오류 처리에 중점을 둡니다.
Shapefile 변환이 TransformationException을 발생시키는 이유
대부분의 대상 형식은 특정 좌표계의 좌표를 기대합니다. 예를 들어 KML은 항상 WGS 84 경도와 위도를 사용합니다. 변환 중에 Aspose.GIS는 소스 좌표계의 모든 좌표를 대상 좌표계로 변환합니다. 어떤 좌표라도 변환할 수 없으면 라이브러리는 TransformationException을 발생시키고 변환이 중단됩니다.
가장 흔한 원인은 다음과 같습니다:
- 플레이스홀더 “no data” 값. 일부 도구는 기하를 비워두는 대신 sentinel 값을 기록합니다. 이 문서의 샘플 파일에는
(-1.7976931348623157E+308, -1.7976931348623157E+308)위치에 점이 포함되어 있는데, 이는double의 최소값이며 어떤 좌표계도 변환할 수 없습니다. - 범위를 벗어난 좌표. 소스 좌표계의 유효 영역을 넘어서는 값으로, 종종 데이터 입력 오류나 잘못된 단위 변환으로 인해 발생합니다.
- 데이터와 일치하지 않는
.prj파일. 미터 단위의 투영 좌표를 도 단위의 지리 좌표로 선언하면 많은 값이 유효 범위를 크게 벗어나게 됩니다. - 손상된 지오메트리 레코드. 레거시 내보내기 및 손상된 파일은 개별 레코드에 잘못된 숫자 값을 포함할 수 있습니다.
모든 경우에 문제는 일반적으로 소수의 레코드에 국한되지만, 기본 동작은 전체 변환을 버립니다.
이 기능이 중요한 이유
첫 번째 실패에서 중단하는 것이 안전하지만 실제 파이프라인에서는 비용이 많이 듭니다. 하나의 잘못된 레코드 때문에 데이터를 변환하기 전에 파일을 수동으로 정리해야 하며, 예외만으로는 다른 레코드가 얼마나 영향을 받았는지 알 수 없습니다. 오류 수집을 활성화하면 다음을 수행할 수 있습니다:
- 전체 파일을 하나의 잘못된 레코드 때문에 잃어버리는 대신 모든 유효한 피처를 변환합니다.
- 스킵된 각 피처의 인덱스와 좌표를 기록하여 원본 데이터를 복구할 수 있도록 합니다.
- 오염된 입력에서도 충돌 없이 무인 배치 변환 및 ETL 작업을 실행합니다.
- 웹 서비스에서 사용자가 업로드한 Shapefile을 받아들이고 데이터 문제를 사용자에게 보고합니다.
C#와 Aspose.GIS를 사용한 Shapefile 변환 실패 해결 방법
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 드라이버 옵션입니다.DriverOptions에서ErrorCollector속성을 상속합니다. - 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): 좌표를 변환할 수 없고 컬렉터가 연결되지 않은 경우에 발생합니다.
Shapefile 변환 중 TransformationException 해결 방법
수정은 두 부분으로 구성됩니다. 첫 번째로, OperationErrorCollector를 연결하여 변환이 실패하는 대신 잘못된 피처를 건너뛰도록 합니다. 두 번째로, 수집된 보고서를 사용하여 원본에서 해당 레코드를 복구하거나 제거합니다. 아래 단계에서는 Shapefile을 KML로 변환하는 예제를 사용합니다.
1. 환경 준비
- .NET 콘솔 프로젝트를 만들고 Aspose.GIS 26.6+ NuGet 패키지를 추가합니다.
- 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();
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}");
}
샘플 파일의 경우, 컬렉터는 자리 표시자 포인트에 대해 하나의 오류를 기록하고, 나머지 피처(최소 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을 발생시킴 | 대상 드라이버 옵션에 컬렉터가 연결되지 않았습니다. | ConversionOptions.DestinationDriverOptions에 할당된 드라이버 옵션 객체에 ErrorCollector를 설정하십시오. |
| “성공적인” 변환에 기능이 누락됨 | 컬렉터가 예외를 억제하므로 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
결론
Shapefile 변환 중 TransformationException이 발생하면 일반적으로 소수의 레코드에 변환할 수 없는 좌표가 포함되어 있다는 의미이며, 이는 자리표시자 값, 범위를 벗어난 숫자 또는 .prj 파일과 일치하지 않는 데이터일 수 있습니다. C#에서 이를 해결하려면 두 단계가 필요합니다: OperationErrorCollector를 연결하여 Aspose.GIS for .NET이 잘못된 피처를 건너뛰고 변환을 완료하도록 하고, 수집된 피처 인덱스와 좌표를 사용하여 원본 데이터를 복구합니다. 결과적으로 파이프라인은 유효한 출력을 지속적으로 제공하면서 심각한 오류를 실행 가능한 데이터 품질 보고서로 전환합니다.
FAQs
Shapefile을 변환할 때 TransformationException이 발생하는 이유는 무엇인가요? 좌표를 원본 좌표계에서 대상 좌표계로 변환할 수 없을 때 발생합니다. 일반적인 원인으로는 자리 표시자 “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값이 추가됩니다.변환이 오류 없이 완료되었는지 어떻게 알 수 있나요?
VectorLayer.Convert가 반환된 후 컬렉터의HasErrors또는Count속성을 확인하십시오. 예외를 발생시키지 않고 완료된 변환이라도 일부 기능이 건너뛰어졌을 수 있습니다.
