地图平移校正,当加载两幅空间参考一样的影像,其中一幅影像有点偏移,这时就以另一幅影像为基准将其进行平移校正,然后保存,再次加载就不会出现偏移了。
下面来介绍下实现的主要代码:
首先通过选中目录树中的要平移的图层,拖动图层进行平移校正,计算出图层平移的偏移量,然后修改栅格数据集的仿射变换参数的坐标即可,核心方法就是PIE SDK的SetOffset 和GetOffset方法;
平移校正的过程主要涉及到鼠标的MouseDown、MouseUp和MouseMove事件。
当鼠标按下,记录鼠标的坐标,为开始坐标点m_StartPoint,鼠标移动就记录鼠标移动的坐标,为结束坐标点m_EndPoint,两个坐标去差值就是图层当前偏移的距离,然后设置图层的偏移量SetOffset()就可以移动图层。要注意的是当移动一次的时候再在上一次移动的基础上进行移动,需要设置开始坐标点的坐标为鼠标按下的点加上地图上一次偏移的距离的和,具体过程如代码所示。
1 /// <summary> 2 /// 图层平移校正按钮 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void tbn_PanConrrection_Click(object sender, EventArgs e) 7 { 8 //选中图层 根据目录树选中的图层为平移图层 9 IHookHelper hookHelper = new HookHelper(); 10 hookHelper.Hook = mapControlMain; 11 IPmdContents pmdContents = hookHelper.GetContent(); 12 PIETOCNodeTag tag = pmdContents.CustomerProperty as PIETOCNodeTag; 13 if (tag == null) return; 14 if (tag.Layer == null) return; 15 m_SelectedLayer = tag.Layer; 16 m_IsPan = true; 17 } 18 /// <summary> 19 /// 保存平移校正结果按钮 20 /// </summary> 21 /// <param name="sender"></param> 22 /// <param name="e"></param> 23 private void btn_SavePan_Click(object sender, EventArgs e) 24 { 25 if (m_IsPan != true) return; 26 double offsetX = 0; 27 double offsetY = 0; 28 m_SelectedLayer.GetOffset(ref offsetX, ref offsetY);//获取偏移量 29 30 string filePath = m_SelectedLayer.DataSourcePath; 31 IRasterDataset RasterDataset = DatasetFactory.OpenRasterDataset(filePath, OpenMode.Update); 32 double[] geoTrans = RasterDataset.GetGeoTransform(); 33 34 geoTrans[0] = geoTrans[0] - offsetX; 35 geoTrans[3] = geoTrans[3] - offsetY; 36 RasterDataset.SetGeoTransform(geoTrans); 37 (RasterDataset as IDisposable).Dispose();//将平移校正后的结果进行保存 38 MessageBox.Show("保存成功"); 39 m_IsPan = false; 40 }/// <summary> 41 /// 还原按钮 42 /// </summary> 43 /// <param name="sender"></param> 44 /// <param name="e"></param> 45 private void tbn_CancelPan_Click(object sender, EventArgs e) 46 { 47 if (m_SelectedLayer == null) return; 51 m_SelectedLayer.SetOffset(0, 0); 52 mapControlMain.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
}
一、鼠标按下事件,触发MouseDown事件,记录开始坐标
1 /// <summary> 2 /// 鼠标按下 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void mapControlMain_MouseDown(object sender, MouseEventArgs e) 7 { 8 if (m_IsPan == false || m_SelectedLayer == null) return; 9 mapControlMain.CurrentTool = null;//防止点击平移等其他按钮冲突问题 10 m_StartPoint = mapControlMain.ActiveView.DisplayTransformation.ToMapPoint(e.X, e.Y); 11 double offsetX = 0; 12 double offsetY = 0; 13 m_SelectedLayer.GetOffset(ref offsetX, ref offsetY);//获取偏移量 14 m_StartPoint.PutCoords(m_StartPoint.X + offsetX, m_StartPoint.Y + offsetY);//在上一次移动的基础上继续平移 15 }
二、当鼠标在地图上移动时会触发MouseMove事件,计算平移量,设置图层平移
1 /// <summary> 2 /// 鼠标移动 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void mapControlMain_MouseMove(object sender, MouseEventArgs e) 7 { 8 if (m_IsPan == false) return; 9 if (m_StartPoint == null || m_SelectedLayer == null) return; 10 m_EndPoint = mapControlMain.ActiveView.DisplayTransformation.ToMapPoint(e.X, e.Y); 11 12 double offsetX = 0; 13 double offsetY = 0; 14 //计算偏移量 15 offsetX = m_StartPoint.X - m_EndPoint.X; 16 offsetY = m_StartPoint.Y - m_EndPoint.Y; 17 18 m_SelectedLayer.SetOffset(offsetX, offsetY);//设置图层平移 19 mapControlMain.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll); 20 }
三、最后鼠标弹起时,将开始点的坐标设置为空。
1 /// <summary> 2 /// 鼠标弹起事件 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void mapControlMain_MouseUp(object sender, MouseEventArgs e) 7 { 8 m_StartPoint = null; 9 }
代码路径:
项目名称 |
百度云盘地址下/PIE示例程序/13.小工具集锦/地图平移校正/ MapPanCorrectionDemo |
数据路径 |
百度云盘地址下/PIE示例数据/栅格数据/04.World/World.tif |
视频路径 |
百度云盘地址下/PIE视频教程/13.小工具集锦/地图平移校正.avi |
注意:
在地图初始化的时候,图层树控件需要手动绑定地图控件:
tocControlMain.SetBuddyControl(mapControlMain as PIE.Carto.IPmdContents);
效果图:
加载时,China.tif在World.tif之上,两幅图坐标系一致,但是却没有重合
平移保存之后,再次加载: