Saya akhirnya menyelesaikan ini dengan memodifikasi kode ekstraksi khusus untuk memperhitungkan ketepatan referensi spasial sumber dan tujuan.
Kode:
public ISpatialReference createDestinationSpatialRef(IGeoDataset srcDataset, IFeatureWorkspace destinationWorkspace)
{
ISpatialReference result = srcDataset.SpatialReference;
IControlPrecision2 sourceDatasetPrecision = result as IControlPrecision2;
if (sourceDatasetPrecision.IsHighPrecision)
{
if (geodatabaseSupportsHighPrecision(destinationWorkspace))
{
// HP to HP, no conversion
}
else
{
IEnvelope extent = srcDataset.Extent;
result = ConvertSpatialReferenceFromHighToLowPrecision(result, extent);
}
}
else
{
if (geodatabaseSupportsHighPrecision(destinationWorkspace))
{
result = ConvertSpatialReferenceFromLowToHighPrecision(result, -1, 0, 0);
}
else
{
// LP to LP, no conversion
}
}
return result;
}
public bool geodatabaseSupportsHighPrecision(IFeatureWorkspace fws)
{
IGeodatabaseRelease2 release = fws as IGeodatabaseRelease2;
// geodatabase release is numbered 2.2 at 9.2
return ((release != null) && ((release.MajorVersion + 7) >= 9) && (release.MinorVersion >= 2));
}
/// <summary>
/// Converts an existing low precision spatial reference and returns a new high precision spatial reference.
/// </summary>
/// <param name="lowSpatialReference">An ISpatialReference interface that is the low spatial reference to be converted.</param>
/// <param name="xyDoubler">A System.Int32 that is the amount of doubling (2^x) based on the input resolution; -1 produces a value close to the default resolution. Example: -1</param>
/// <param name="mDoubler">A System.Int32 that determines doubling of m-resolution based on input m-resolution; the default is 0. Example: 0</param>
/// <param name="zDoubler">A System.Int32 that determines doubling of z-resolution based on input z-resolution; default is 0. Example: 0</param>
/// <returns>An ISpatialReference interface that is the new high precision spatial reference.</returns>
public ISpatialReference ConvertSpatialReferenceFromLowToHighPrecision(ISpatialReference lowSpatialReference, int xyDoubler, int mDoubler, int zDoubler)
{
IControlPrecision2 controlPrecision2 = lowSpatialReference as IControlPrecision2;
if (controlPrecision2.IsHighPrecision)
throw new ArgumentException("Expected a low precision spatial reference.", "lowSpatialReference");
ISpatialReferenceFactory3 spatialReferenceFactory3 = new SpatialReferenceEnvironmentClass();
ISpatialReference highSpatialReference = spatialReferenceFactory3.ConstructHighPrecisionSpatialReference(lowSpatialReference, xyDoubler, zDoubler, mDoubler);
return highSpatialReference;
}
/// <summary>
/// Converts an existing high precision spatial reference and returns a new low precision spatial reference.
/// </summary>
/// <param name="highSpatialReference">An ISpatialReference interface that is a high precision spatial reference.</param>
/// <param name="envelope">An IEnvelope that is the area covering the extent of the new low precision spatial reference.</param>
/// <returns>An ISpatialReference interface that is the new low precision spatial reference.</returns>
public ISpatialReference ConvertSpatialReferenceFromHighToLowPrecision(ISpatialReference highSpatialReference, IEnvelope envelope)
{
IControlPrecision2 controlPrecision2 = highSpatialReference as IControlPrecision2;
if (!controlPrecision2.IsHighPrecision)
throw new ArgumentException("Expected a high precision spatial reference.", "highSpatialReference");
ISpatialReference lowSpatialReference = null;
ISpatialReferenceFactory3 spatialReferenceFactory3 = new SpatialReferenceEnvironmentClass();
try
{
lowSpatialReference = spatialReferenceFactory3.ConstructLowPrecisionSpatialReference(true, highSpatialReference, envelope);
}
catch (System.Runtime.InteropServices.COMException ex)
{
if (ex.ErrorCode == -2147220986)
{
lowSpatialReference = spatialReferenceFactory3.ConstructLowPrecisionSpatialReference(false, highSpatialReference, envelope);
}
}
return lowSpatialReference;
}