在二维坐标系统中,常见转换坐标:平移、缩放、旋转。在ArcGIS中可以通过工具实现移动 、旋转 和缩放,具体操作如下:
(1)移动要素:可通过指针或指定值以交互方式操作所选要素。移动要素:要移动要素,请使用指针选择并对其进行拖动。选择多个要素后,您可以单击鼠标右键并对齐或分配要素。
(2)旋转要素:要使用指针旋转要素,请对其进行选择并拖动。主选择锚点可指定旋转中心。辅助锚点可将旋转角度捕捉到其他要素。
(3)旋转要素:要使用指针旋转要素,请对其进行选择并拖动。主选择锚点可指定旋转中心。辅助锚点可将旋转角度捕捉到其他要素。
对于实际工作中,会遇到各种复杂的数据,基于不同基点(原点),平移、缩放、旋转的量都不同,要根据具体情况具体分析。本文想实现坐标转换的通用方法,基于基点信息,对图层所有要素进行平移、缩放、旋转。
实现主体函数执行流程如下:
for (int i = 0; i < BasePoints.Rows.Count; i++)
{
TransformCoordinate MoveCoor = new TransformCoordinate();
DataRow BaseBow = BasePoints.Rows[i];
//1.获取基点信息
MoveCoor.getBaseInfo(BaseBow);
string shpName = MoveCoor.shpFileName;
string output = outputPath + @"\" + shpName;
if (inputTargetNameList.Exists(t => t.Equals(shpName)))//判断List是否含某个属性
{
//2.将所有同名(shpName)文件,从源路径复制至输出路径下,不区分文件后缀名
FileCopy.CopyOneShpFile(inputTargetFile, outputPath, shpName,true);//复制文件
//3.判断图层中有无图形元素,同时初始化图层即给in_FeatureClass赋值
if (MoveCoor.isExistFeatures(output) == false)
{
remind2 += shpName + " ";//图层缺少要素
}
//4.转换坐标
MoveCoor.ExecutePan();//平移
MoveCoor.ExecuteRotate();//旋转
MoveCoor.ExecuteTelescopic();//缩放
MoveCoor.updateExtend();//更新图层extent
}
else
{
remind += shpName + " ";//缺少图层
continue;
}
}
我这里的基点(PointA和PointB)的坐标信息、旋转角度,缩放比例等坐标转换信息都保存在Excel文件中,如下图所示坐标转换参数表,可以根据不同的项目修改坐标转换的参数,实现通用的坐标转换功能。
坐标转换类:
/// <summary>
/// 根据已知基点信息,批量实现图层要素的平移、缩放、旋转。
/// 处理Shapefile文件
/// </summary>
public class TransformCoordinate
{
//基点信息
public string shpFileName;
private IPoint PointA;//基点A是图层坐标转换前的基点
private IPoint PointB;//基点B是图层坐标转换后的基点
private double scale;//缩放比例
private double angle;//旋转角度,读取的是角度(°),旋转时用的是弧度,需要角度转为弧度
private IFeatureClass in_FeatureClass;
public TransformCoordinate()
{
//基点
PointA = new Point();
PointB = new Point();
}
//判断图层中有无图形元素,同时初始化图层
public bool isExistFeatures(string in_filePath)
{
IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
IWorkspaceFactoryLockControl pWorkspaceFactoryLockControl = pWorkspaceFactory as IWorkspaceFactoryLockControl;
if (pWorkspaceFactoryLockControl.SchemaLockingEnabled)
{
pWorkspaceFactoryLockControl.DisableSchemaLocking();
}
IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(in_filePath), 0);
IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;
in_FeatureClass = pFeatureWorkspace.OpenFeatureClass(System.IO.Path.GetFileName(in_filePath));
if (in_FeatureClass.FeatureCount(null) > 0)
{ return true; }
else
{ return false; }
}
//获取基点信息
public void getBaseInfo(DataRow rows)
{
shpFileName = rows[0].ToString().Trim() + ".shp";
PointA.X = Convert.ToDouble(rows[1].ToString());
PointA.Y = Convert.ToDouble(rows[2].ToString());
PointB.X = Convert.ToDouble(rows[3].ToString());
PointB.Y = Convert.ToDouble(rows[4].ToString());
scale = Convert.ToDouble(rows[5].ToString());
angle = Math.PI / 180 * Convert.ToDouble(rows[6].ToString());//角度(°)转为弧度
}
//平移
public bool ExecutePan()
{
// 获取游标
IFeatureCursor in_FeatureCursor = in_FeatureClass.Update(null, true);
IFeature in_Feature = in_FeatureCursor.NextFeature();
if (in_Feature == null)
{
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(in_FeatureCursor);
return false;
}
while (in_Feature != null)
{
IGeometry pGeometry = in_Feature.Shape;
in_Feature.Shape = Pan(pGeometry, PointB.X - PointA.X, PointB.Y - PointA.Y);
in_FeatureCursor.UpdateFeature(in_Feature);
in_Feature = in_FeatureCursor.NextFeature();
}
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(in_FeatureCursor);
return true;
}
//旋转
public bool ExecuteRotate()
{
// 获取游标
IFeatureCursor in_FeatureCursor = in_FeatureClass.Update(null, true);
IFeature in_Feature = in_FeatureCursor.NextFeature();
if (in_Feature == null)
{
return false;
}
while (in_Feature != null)
{
IGeometry pGeometry = in_Feature.Shape;
in_Feature.Shape = Rotate(pGeometry, PointB, angle);
in_FeatureCursor.UpdateFeature(in_Feature);
in_Feature = in_FeatureCursor.NextFeature();
}
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(in_FeatureCursor);
return true;
}
//缩放
public bool ExecuteTelescopic()
{
// 获取游标
IFeatureCursor in_FeatureCursor = in_FeatureClass.Update(null, true);
IFeature in_Feature = in_FeatureCursor.NextFeature();
if (in_Feature == null)
{
return false;
}
while (in_Feature != null)
{
IGeometry pGeometry = in_Feature.Shape;
in_Feature.Shape = Telescopic(pGeometry, PointB, scale);
in_FeatureCursor.UpdateFeature(in_Feature);
in_Feature = in_FeatureCursor.NextFeature();
}
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(in_FeatureCursor);
return true;
}
// 平移变换
private IGeometry Pan(IGeometry pGeometry, double dx, double dy)
{
ITransform2D pTransform2D = pGeometry as ITransform2D;
pTransform2D.Move(dx, dy);
return pTransform2D as IGeometry;
}
/// <summary>
/// 伸缩变换
/// </summary>
/// <param name="pGeometry"></param>
/// <param name="originPoint">原点或基点</param>
/// <param name="scale"></param>
/// <returns></returns>
private IGeometry Telescopic(IGeometry pGeometry, IPoint originPoint, double scale)
{
ITransform2D pTransform2D = pGeometry as ITransform2D;
pTransform2D.Scale(originPoint, scale, scale);
return pTransform2D as IGeometry;
}
// 旋转变换
private IGeometry Rotate(IGeometry pGeometry, IPoint originPoint, double angle)
{
IPointCollection pPointCollection = pGeometry as IPointCollection;
ITransform2D pTransform2D = pGeometry as ITransform2D;
pTransform2D.Rotate(originPoint, angle);
return pTransform2D as IGeometry;
}
//extent更新
public void updateExtend()
{
((IFeatureClassManage)in_FeatureClass).UpdateExtent();
}
}