Tôi đã kết thúc việc giải quyết điều này bằng cách sửa đổi mã trích xuất tùy chỉnh để tính đến độ chính xác của các refs không gian nguồn và đích.
Mã số:
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;
}