using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Client; using ESRI.ArcGIS.Client.FeatureService.Symbols; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.DataSourcesRaster; using ESRI.ArcGIS.Geodatabase; using KGIS.Framework.Maps; using KGIS.Framework.OpenData.Control; using KGIS.Framework.OpenData.Filter; using KGIS.Framework.OpenData.InterFace; using KGIS.Framework.Utils; using KGIS.Framework.Utils.Helper; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Security.AccessControl; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Client.Geometry; using ESRI.ArcGIS; using ESRI.ArcGIS.Display; using TestMultiGetPointsTranslate.Model; using OSGeo.GDAL; using System.Threading; using System.IO; namespace TestMultiGetPointsTranslate.View { public partial class TestMultiGetPointsTranslateForm : Form { MultiPointTranslate multiPointTranslates; string SourceImgPath = string.Empty; public TestMultiGetPointsTranslateForm() { ESRI.ArcGIS.RuntimeManager.Bind(ProductCode.EngineOrDesktop); InitializeComponent(); multiPointTranslates = new MultiPointTranslate(); this.Icon = new Icon("Main.ico"); } private void TestMultiGetPointsTranslateForm_Load(object sender, EventArgs e) { axMapControl1.OnMouseMove += AxMapControl1_OnMouseMove; axMapControl2.OnMouseMove += AxMapControl2_OnMouseMove; } private void btSetSpatialReference_Click(object sender, EventArgs e) { try { IGeoDataset s = GetGisFileSource(); if (s == null || s.SpatialReference == null) { return; } axMapControl1.SpatialReference = s.SpatialReference; } catch (Exception ex) { //LogAPI.Debug("新建工程 页面 中 导入坐标系 时失败,异常原因: " + ex + " ; "); //MessageHelper.ShowTips("导入坐标参考系异常:" + ex.Message); } } private IGeoDataset GetGisFileSource() { try { OpenDataDialog pDialog = new OpenDataDialog(); ISpatialDataObjectFilter pOFilter; pOFilter = new FilterDatasetsAndLayers(); pDialog.AddFilter(pOFilter, true); pDialog.Title = "选择矢量图层数据"; pDialog.AllowMultiSelect = false; pDialog.RestoreLocation = true; pDialog.StartLocation = pDialog.FinalLocation; if (pDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK && pDialog.Selection.Count != 0) { foreach (ISpatialDataObject distObj in pDialog.Selection) { if (distObj.DatasetType == esriDatasetType.esriDTFeatureClass) { return (distObj.DatasetName as ESRI.ArcGIS.esriSystem.IName).Open() as IGeoDataset; } } } return null; } catch (Exception ex) { LogAPI.Debug("获取GIS文件源时失败,异常原因: " + ex + " ; "); return null; } } private void AxMapControl1_OnMouseMove(object sender, AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e) { // 获取当前鼠标位置的屏幕坐标 System.Drawing.Point screenPoint = new System.Drawing.Point(e.x, e.y); // 将屏幕坐标转换为地图坐标 IPoint mapPoint = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(screenPoint.X, screenPoint.Y); // 显示地图坐标点 tbCoordinates.Text = $"X: {mapPoint.X}, Y: {mapPoint.Y}"; } private void AxMapControl2_OnMouseMove(object sender, AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e) { // 获取当前鼠标位置的屏幕坐标 System.Drawing.Point screenPoint = new System.Drawing.Point(e.x, e.y); // 将屏幕坐标转换为地图坐标 IPoint mapPoint = axMapControl2.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(screenPoint.X, screenPoint.Y); // 显示地图坐标点 tbCoordinates.Text = $"X: {mapPoint.X}, Y: {mapPoint.Y}"; } private void btAddMapLeft_Click(object sender, EventArgs e) { LoadMap(this.axMapControl1); } private void btAddMapRight_Click(object sender, EventArgs e) { SourceImgPath = LoadMap(this.axMapControl2); } IRasterDataset pRasterDataset = null; private string LoadMap(AxESRI.ArcGIS.Controls.AxMapControl axMapControl) { try { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = "选择影像文件"; openFileDialog.Filter = "栅格文件|*.img;*.tiff;*.tif"; openFileDialog.RestoreDirectory = true; openFileDialog.Multiselect = false; if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return string.Empty; } string selectPath = openFileDialog.FileName; string Path = System.IO.Path.GetDirectoryName(selectPath); string strFileName = System.IO.Path.GetFileName(selectPath); IWorkspaceFactory pWorkspaceFactory = new RasterWorkspaceFactory(); IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(Path, 0); IRasterWorkspace pRasterWorkspace = pWorkspace as IRasterWorkspace; pRasterDataset = pRasterWorkspace.OpenRasterDataset(strFileName); IRaster pRaster = pRasterDataset.CreateDefaultRaster(); IRasterLayer pRasterLayer = new RasterLayer(); pRasterLayer.CreateFromRaster(pRaster); ILayer featureLayer = pRasterLayer as ILayer; if (axMapControl == axMapControl1) { featureLayer.SpatialReference = axMapControl1.SpatialReference; } else { featureLayer.SpatialReference = null; axMapControl.SpatialReference = null; } axMapControl.AddLayer(featureLayer); axMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewBackground, null, axMapControl.Extent); return selectPath; } catch (Exception ex) { LogAPI.Debug("加载影像数据 异常:" + ex.Message); LogAPI.Debug("加载影像数据 异常:" + ex.StackTrace); MessageHelper.ShowError("加载影像数据失败:" + ex.Message); } return string.Empty; } // 查找已有点的方法 private IElement FindExisting1Point(IPoint point, double tolerance) { IEnumElement enumElement = axMapControl1.ActiveView.GraphicsContainer.LocateElements(point, tolerance); if (enumElement == null) return null; IElement element = enumElement.Next(); while (element != null) { return element; } return null; } private IElement FindExisting2Point(IPoint point, double tolerance) { IEnumElement enumElement = axMapControl2.ActiveView.GraphicsContainer.LocateElements(point, tolerance); if (enumElement == null) return null; IElement element = enumElement.Next(); while (element != null) { return element; } return null; } private void axMapControl1_OnMouseDown(object sender, AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e) { if (e.button == 2) // 检测是否为右键点击 { ControlsMapPanToolClass pan = new ControlsMapPanToolClass(); pan.OnCreate(axMapControl1.Object); ControlsMapPanToolClass pan2 = new ControlsMapPanToolClass(); pan2.OnCreate(axMapControl2.Object); axMapControl1.CurrentTool = pan; axMapControl2.CurrentTool = pan2; button1.Text = "选取像控点"; this.axMapControl1.OnMouseDown -= axMapControl1_OnMouseDown; this.axMapControl2.OnMouseDown -= axMapControl2_OnMouseDown; } else if (e.button == 1) { if (button1.Text == "选取像控点") return; // 获取当前鼠标位置的屏幕坐标 System.Drawing.Point screenPoint = new System.Drawing.Point(e.x, e.y); // 将屏幕坐标转换为地图坐标 IPoint clickedPoint = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(screenPoint.X, screenPoint.Y); // 判断是否已有附近点存在 IElement existingPoint = FindExisting1Point(clickedPoint, 1); // 在 10 像素范围内查找已有点 if (existingPoint != null) { // 删除附近的点 axMapControl1.ActiveView.GraphicsContainer.DeleteElement(existingPoint); IPoint geometryPoint = existingPoint.Geometry as IPoint; foreach (var item in listBox1.Items) { if (item == null || string.IsNullOrEmpty(item.ToString())) continue; double x = double.Parse(item.ToString().Split(',')[0].Split(':')[1]); double y = double.Parse(item.ToString().Split(',')[1].Split(':')[1]); if (Math.Abs(Math.Abs(geometryPoint.X) - x) < 0.001 && Math.Abs(Math.Abs(geometryPoint.Y) - y) < 0.001) { listBox1.Items.Remove(item); break; } } } else { IRgbColor color = new RgbColor(); // 设置颜色属性 color.Red = 255; color.Green = 0; color.Blue = 0; IMarkerElement pointEle = new MarkerElementClass(); IMarkerSymbol symbol = new SimpleMarkerSymbolClass(); symbol.Color = color; symbol.Size = 10; pointEle.Symbol = symbol; (pointEle as IElement).Geometry = clickedPoint; axMapControl1.ActiveView.GraphicsContainer.AddElement(pointEle as IElement, 0); double clickpointX = Math.Abs(clickedPoint.X); double clickpointY = Math.Abs(clickedPoint.Y); object removeItem = $"X: {clickpointX}, Y: {clickpointY}"; listBox1.Items.Add(removeItem); } axMapControl1.ActiveView.Refresh(); } } private void axMapControl2_OnMouseDown(object sender, AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e) { if (e.button == 2) // 检测是否为右键点击 { ControlsMapPanToolClass pan = new ControlsMapPanToolClass(); pan.OnCreate(axMapControl1.Object); ControlsMapPanToolClass pan2 = new ControlsMapPanToolClass(); pan2.OnCreate(axMapControl2.Object); axMapControl1.CurrentTool = pan; axMapControl2.CurrentTool = pan2; button1.Text = "选取像控点"; this.axMapControl1.OnMouseDown -= axMapControl1_OnMouseDown; this.axMapControl2.OnMouseDown -= axMapControl2_OnMouseDown; } else if (e.button == 1) { if (button1.Text == "选取像控点") return; IRasterLayer rLayer = axMapControl2.get_Layer(0) as IRasterLayer; // 获取栅格Band IRaster2 raster = (IRaster2)rLayer.Raster; IRasterProps rasterProps = (IRasterProps)raster; int width = rasterProps.Width; int height = rasterProps.Height; // 获取当前鼠标位置的屏幕坐标 System.Drawing.Point screenPoint = new System.Drawing.Point(e.x, e.y); // 将屏幕坐标转换为地图坐标 IPoint clickedPoint = axMapControl2.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(screenPoint.X, screenPoint.Y); // 判断是否已有附近点存在 IElement existingPoint = FindExisting2Point(clickedPoint, 10); // 在 10 像素范围内查找已有点 IPoint pixelLocation = new PointClass(); raster.MapToPixel(clickedPoint.X, clickedPoint.Y, out int pCol, out int pRow); if (existingPoint != null) { // 删除附近的点 axMapControl2.ActiveView.GraphicsContainer.DeleteElement(existingPoint); IPoint geometryPoint = existingPoint.Geometry as IPoint; foreach (var item in listBox2.Items) { if (item == null || string.IsNullOrEmpty(item.ToString())) continue; int x = int.Parse(item.ToString().Split(',')[0].Split(':')[1]); int y = int.Parse(item.ToString().Split(',')[1].Split(':')[1]); if (Math.Abs(Math.Abs(geometryPoint.X) - x) < 0.5 && Math.Abs(Math.Abs(geometryPoint.Y) - y) < 0.5) { listBox2.Items.Remove(item); break; } } } else { IRgbColor color = new RgbColor(); // 设置颜色属性 color.Red = 255; color.Green = 0; color.Blue = 0; IMarkerElement pointEle = new MarkerElementClass(); IMarkerSymbol symbol = new SimpleMarkerSymbolClass(); symbol.Color = color; symbol.Size = 10; pointEle.Symbol = symbol; (pointEle as IElement).Geometry = clickedPoint; axMapControl2.ActiveView.GraphicsContainer.AddElement(pointEle as IElement, 0); double clickpointX = Math.Abs(pCol); double clickpointY = Math.Abs(pRow); object removeItem = $"X: {clickpointX}, Y: {clickpointY}"; listBox2.Items.Add(removeItem); } axMapControl2.ActiveView.Refresh(); } } //矫正 private void btRectify_Click(object sender, EventArgs e) { try { List multiPointTranslates = new List(); if (listBox1.Items.Count == 0 || listBox2.Items.Count == 0) { MessageHelper.ShowTips("请在两个地图同时添加相同点!"); return; } if (listBox1.Items.Count != listBox2.Items.Count) { MessageHelper.ShowTips("请在两个地图添加相同数量及位置点!"); return; } for (int i = 0; i < listBox1.Items.Count; i++) { if (string.IsNullOrEmpty(listBox1.Items[i].ToString()) || string.IsNullOrEmpty(listBox2.Items[i].ToString())) { continue; } string leftPoint = listBox1.Items[i].ToString(); string rightPoint = listBox2.Items[i].ToString(); MultiPointTranslates tempMultiPointTranslate = new MultiPointTranslates(); tempMultiPointTranslate.leftMultiPointTranslate = new MultiPointTranslate(); tempMultiPointTranslate.leftMultiPointTranslate.X = double.Parse(leftPoint.Split(',')[0].Split(':')[1]); tempMultiPointTranslate.leftMultiPointTranslate.Y = double.Parse(leftPoint.Split(',')[1].Split(':')[1]); //tempMultiPointTranslate.leftMultiPointTranslate.X -= 40494788.4837301; //tempMultiPointTranslate.leftMultiPointTranslate.Y -= Math.Abs(3351402.7119641); //tempMultiPointTranslate.leftMultiPointTranslate.Y = Math.Abs(tempMultiPointTranslate.leftMultiPointTranslate.Y); tempMultiPointTranslate.rightMultiPointTranslate = new MultiPointTranslate(); tempMultiPointTranslate.rightMultiPointTranslate.X = double.Parse(rightPoint.Split(',')[0].Split(':')[1]); tempMultiPointTranslate.rightMultiPointTranslate.Y = double.Parse(rightPoint.Split(',')[1].Split(':')[1]); multiPointTranslates.Add(tempMultiPointTranslate); } if (multiPointTranslates.Count == 0) { MessageHelper.ShowTips("请添加像控点!"); return; } if (MergeEngineByTranslate(multiPointTranslates)) { MessageHelper.ShowTips("影像输出成功!"); } else { MessageHelper.ShowTips("影像输出失败!"); } } catch (Exception ex) { LogAPI.Debug("影像输出 异常!" + ex.Message); LogAPI.Debug("影像输出 异常!" + ex.StackTrace); MessageHelper.ShowError("影像输出 异常!" + ex.Message); } } private bool MergeEngineByTranslate(List multiPointTranslates) { try { //N1 40492054.91 4111849.536 58.554 //N4 40492132.05 4111920.127 57.559 //N9 40492240.92 4111969.941 57.517 //N10 40492286.12 4111903.787 56.783 //N3 40492281.81 4111837.745 55.921 //N8 40492374.94 4111839.677 54.573 //N7 40492258.78 4111768.812 56.923 //N6 40492181.75 4111702.181 58.649 //N5 40492124.32 4111739.376 58.718 //N2 40492172.34 4111844.982 57.241 string command = "-of GTiff "; foreach (var item in multiPointTranslates) { command += "-gcp " + item.rightMultiPointTranslate.X + " " + item.rightMultiPointTranslate.Y + " " + item.leftMultiPointTranslate.X + " " + item.leftMultiPointTranslate.Y + " "; } var options = Gdal.ParseCommandLine(command); //var options = Gdal.ParseCommandLine("-of GTiff -gcp 404 249 38495722.906 3446828.873 -gcp 571 176 38496055.59 3447078.64"); var suntmpdir = System.IO.Path.Combine(Environment.CurrentDirectory, Guid.NewGuid().ToString().Split('-')[0]); Gdal.GDALProgressFuncDelegate progressFuncDelegate = new Gdal.GDALProgressFuncDelegate((complete, msg, data) => { if (complete >= 1) { //isProgressCompleted = true; } return 1; }); FolderBrowserDialog m_Dialog = new FolderBrowserDialog(); System.Windows.Forms.DialogResult result = m_Dialog.ShowDialog(); if (result != System.Windows.Forms.DialogResult.OK) return false; string m_Dir = m_Dialog.SelectedPath.Trim(); //Dataset inputDataset = Gdal.OpenShared(System.IO.Path.Combine(m_Dir, Guid.NewGuid().ToString() + ".tif"), Access.GA_ReadOnly); string OutTempFile = System.IO.Path.Combine(m_Dir, "Temp"); if (!Directory.Exists(OutTempFile)) { Directory.CreateDirectory(OutTempFile); } OutTempFile = System.IO.Path.Combine(OutTempFile, Guid.NewGuid().ToString() + ".tif"); Dataset inputDataset = Gdal.OpenShared(SourceImgPath, Access.GA_ReadOnly); FileInfo fInfo = new FileInfo(SourceImgPath); string OutFilePath = System.IO.Path.Combine(m_Dir, fInfo.Name); //var newtagtiff = System.IO.Path.Combine(OutTempFile); var outDataset = Gdal.wrapper_GDALTranslate(OutTempFile, inputDataset, new GDALTranslateOptions(options), progressFuncDelegate, "Test"); options = Gdal.ParseCommandLine("-r near -tps -co COMPRESS=PNG"); Dataset[] ds = new Dataset[] { outDataset }; //newtagtiff = System.IO.Path.Combine(suntmpdir, "bb.tif"); outDataset = Gdal.Warp(OutFilePath, ds, new GDALWarpAppOptions(options), progressFuncDelegate, "out"); //重新设置坐标参考 //var tmptiff = System.IO.Path.Combine(suntmpdir,"Tiffs", System.IO.Path.GetFileName(tifles[0])); //var tmptifdataset = Gdal.Open(tmptiff, Access.GA_ReadOnly); //string wktproj = ""; //outDataset.GetSpatialRef().ExportToWkt(out wktproj, new string[] { }); //outDataset.SetSpatialRef(tmptifdataset.GetSpatialRef()); outDataset.FlushCache(); outDataset.Dispose(); //tmptifdataset.FlushCache(); //tmptifdataset.Dispose(); GC.Collect(); Thread.Sleep(100); //File.Delete(OutTempFile); return true; } catch (Exception ex) { LogAPI.Debug("影像输出计算 异常!" + ex.Message); LogAPI.Debug("影像输出计算 异常!" + ex.StackTrace); return false; } finally { } } private void button1_Click(object sender, EventArgs e) { if (button1.Text == "取消") { this.axMapControl1.OnMouseDown -= axMapControl1_OnMouseDown; this.axMapControl2.OnMouseDown -= axMapControl2_OnMouseDown; //this.axMapControl1.OnMouseUp -= AxMapControl1_OnMouseUp; //this.axMapControl2.OnMouseUp -= AxMapControl2_OnMouseUp; button1.Text = "选取像控点"; } else { this.axMapControl1.OnMouseDown += axMapControl1_OnMouseDown; this.axMapControl2.OnMouseDown += axMapControl2_OnMouseDown; //this.axMapControl1.OnMouseUp += AxMapControl1_OnMouseUp; //this.axMapControl2.OnMouseUp += AxMapControl2_OnMouseUp; button1.Text = "取消"; axMapControl1.CurrentTool = null; axMapControl2.CurrentTool = null; } } } }