/// <summary> /// Reprojects layer of undefined type /// </summary> /// <param name="filename">Filename of layer to reproject. A changed name will be returned when new file was created</param> /// <param name="projection">New projection</param> /// <param name="inPlace">Whether new files should be written</param> /// <param name="report">A reference to report form</param> /// <returns>True on success and false otherwise</returns> public static TestingResult ReprojectLayer(string filename, out string newFilename, MapWinGIS.GeoProjection projection, frmTesterReport callback) { newFilename = ""; LayerSource source = new LayerSource(filename, callback); if (source.Type != LayerSourceType.Undefined) { LayerSource sourceNew = null; TestingResult result = CoordinateTransformation.ReprojectLayer(source, out sourceNew, projection, callback); if (sourceNew != null) { newFilename = sourceNew.Filename; } return(result); } else { return(TestingResult.Error); } }
/// <summary> /// 测试单层投影 /// </summary> /// <param name="layer">图层源(Shapefile或grid对象)</param> /// <param name="newLayer">输出新图层</param> /// <returns>返回测试结果</returns> public TestingResult TestLayer(LayerSource layer, out LayerSource newLayer) { if (layer == null) { throw new ArgumentException("空图层引用被通过"); } newLayer = null; MapWinGIS.GeoProjection projectProj = m_mapWin.Project.GeoProjection; MapWinGIS.GeoProjection layerProj = layer.Projection; bool isSame = projectProj.get_IsSameExt(layerProj, layer.Extents, 10); // 让我们看看我们是否有项目的投影的一种方言 if (!isSame && !projectProj.IsEmpty) { ProjectionDatabase db = (ProjectionDatabase)m_mapWin.ProjectionDatabase;//投影数据源 if (db != null) { CoordinateSystem cs = db.GetCoordinateSystem(projectProj, ProjectionSearchType.Enhanced);//坐标系统 if (cs != null) { db.ReadDialects(cs); foreach (string dialect in cs.Dialects) { MapWinGIS.GeoProjection projTemp = new MapWinGIS.GeoProjection(); if (!projTemp.ImportFromAutoDetect(dialect)) { continue; } if (layerProj.get_IsSame(projTemp)) { isSame = true; break; } } } } } // 投影中可以包含的文件的后缀名,让我们试着用正确的后缀搜索文件 if (!isSame) { if (CoordinateTransformation.SeekSubstituteFile(layer, projectProj, out newLayer)) { m_report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.Substituted, newLayer.Filename); return(TestingResult.Substituted); } } if (!layer.Projection.IsEmpty) { if (projectProj.IsEmpty) { // 层具有投影,项目没有;分配到投影,不提示用户 // 让我们找个众所周知的投影与EPSG编码 ProjectionDatabase db = m_mapWin.ProjectionDatabase as ProjectionDatabase; if (db != null) { CoordinateSystem cs = db.GetCoordinateSystem(layerProj, ProjectionSearchType.UseDialects); if (cs != null) { MapWinGIS.GeoProjection proj = new MapWinGIS.GeoProjection(); if (proj.ImportFromEPSG(cs.Code)) { layerProj = proj; } } } m_mapWin.Project.GeoProjection = layerProj; return(TestingResult.Ok); } else if (isSame) { // 相同投影 return(TestingResult.Ok); } else { // 用户必须被提示 if (!m_usePreviousAnswerMismatch && !m_mapWin.ApplicationInfo.NeverShowProjectionDialog) { bool dontShow = false; bool useForOthers = false; ArrayList list = new ArrayList(); list.Add("Ignore mismatch"); list.Add("Reproject file"); //list.Add("Skip file"); // PM 2013-05-03: list.Add("Don't load the layer"); frmProjectionMismatch form = new frmProjectionMismatch((ProjectionDatabase)m_mapWin.ProjectionDatabase); int choice = form.ShowProjectionMismatch(list, (int)m_mapWin.ApplicationInfo.ProjectionMismatchBehavior, projectProj, layer.Projection, out useForOthers, out dontShow); form.Dispose(); if (choice == -1) { return(TestingResult.CancelOperation); } m_usePreviousAnswerMismatch = useForOthers; m_mapWin.ApplicationInfo.ProjectionMismatchBehavior = (ProjectionMismatchBehavior)choice; m_mapWin.ApplicationInfo.NeverShowProjectionDialog = dontShow; } MapWinGIS.Interfaces.ProjectionMismatchBehavior behavior = m_mapWin.ApplicationInfo.ProjectionMismatchBehavior; switch (behavior) { case ProjectionMismatchBehavior.Reproject: TestingResult result = CoordinateTransformation.ReprojectLayer(layer, out newLayer, projectProj, m_report); if (result == TestingResult.Ok || result == TestingResult.Substituted) { ProjectionOperaion oper = result == TestingResult.Ok ? ProjectionOperaion.Reprojected : ProjectionOperaion.Substituted; string newName = newLayer == null ? "" : newLayer.Filename; m_report.AddFile(layer.Filename, layer.Projection.Name, oper, newName); return(newName == layer.Filename ? TestingResult.Ok : TestingResult.Substituted); } else { m_report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.FailedToReproject, ""); return(TestingResult.Error); } case ProjectionMismatchBehavior.IgnoreMismatch: m_report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.MismatchIgnored, ""); return(TestingResult.Ok); case ProjectionMismatchBehavior.SkipFile: m_report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.Skipped, ""); return(TestingResult.SkipFile); } } } else if (!projectProj.IsEmpty) // 图层投影是空的 { bool projectProjectionExists = !projectProj.IsEmpty; // 用户必须被提示 if (!m_usePreviousAnswerAbsence && !m_mapWin.ApplicationInfo.NeverShowProjectionDialog) { bool dontShow = false; bool useForOthers = false; ArrayList list = new ArrayList(); // 当在投影第一变体应排除 int val = projectProjectionExists ? 0 : 1; if (projectProjectionExists) { // PM 2013-05-03: //list.Add("Assign projection from project"); list.Add("Use the project's projection"); } // list.Add("Ignore the absence"); // list.Add("Skip the file"); list.Add("Ignore the missing of projection file"); list.Add("Don't load the layer"); frmProjectionMismatch form = new frmProjectionMismatch((ProjectionDatabase)m_mapWin.ProjectionDatabase); int choice = form.ShowProjectionAbsence(list, (int)m_mapWin.ApplicationInfo.ProjectionAbsenceBehavior - val, projectProj, out useForOthers, out dontShow); form.Dispose(); if (choice == -1) { return(TestingResult.CancelOperation); } choice += val; m_usePreviousAnswerAbsence = useForOthers; m_mapWin.ApplicationInfo.ProjectionAbsenceBehavior = (ProjectionAbsenceBehavior)choice; m_mapWin.ApplicationInfo.NeverShowProjectionDialog = dontShow; } // 当在项目没有投影,它不能分配层 ProjectionAbsenceBehavior behavior = m_mapWin.ApplicationInfo.ProjectionAbsenceBehavior; if (!projectProjectionExists && m_mapWin.ApplicationInfo.ProjectionAbsenceBehavior == ProjectionAbsenceBehavior.AssignFromProject) { behavior = ProjectionAbsenceBehavior.IgnoreAbsence; } switch (behavior) { case ProjectionAbsenceBehavior.AssignFromProject: m_report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.Assigned, ""); layer.Projection = projectProj; return(TestingResult.Ok); case ProjectionAbsenceBehavior.IgnoreAbsence: m_report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.AbsenceIgnored, ""); return(TestingResult.Ok); case ProjectionAbsenceBehavior.SkipFile: m_report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.Skipped, ""); return(TestingResult.SkipFile); } } else { // 层没有投影,项目也没有,不在这里 } System.Diagnostics.Debug.Print("Invalid result in projection tester"); return(TestingResult.Ok); }
/// <summary> /// Does the reprojection work /// </summary> private void DoReprojection(IEnumerable <string> filenames, MapWinGIS.GeoProjection projection, bool inPlace) { frmTesterReport report = new frmTesterReport(); report.InitProgress(projection); List <string> files = new List <string>(); int count = 0; // number of successfully reprojected shapefiles foreach (string filename in filenames) { LayerSource layer = new LayerSource(filename); LayerSource layerNew = null; if (projection.get_IsSame(layer.Projection)) { report.AddFile(layer.Filename, projection.Name, ProjectionOperaion.SameProjection, ""); files.Add(layer.Filename); } else { TestingResult result = CoordinateTransformation.ReprojectLayer(layer, out layerNew, projection, report); if (result == TestingResult.Ok || result == TestingResult.Substituted) { ProjectionOperaion oper = result == TestingResult.Ok ? ProjectionOperaion.Reprojected : ProjectionOperaion.Substituted; string newName = layerNew == null ? "" : layerNew.Filename; report.AddFile(layer.Filename, layer.Projection.Name, oper, newName); files.Add(newName == "" ? layer.Filename : newName); count++; } else { ProjectionOperaion operation = result == TestingResult.Error ? ProjectionOperaion.FailedToReproject : ProjectionOperaion.Skipped; report.AddFile(layer.Filename, layer.Projection.Name, ProjectionOperaion.Skipped, ""); } } layer.Close(); if (layerNew != null) { layerNew.Close(); } } report.ShowReport(projection, "Reprojection results:", ReportType.Loading); IEnumerable <string> names = m_mapWin.Layers.Select(l => l.FileName); names = files.Except(names); if (count > 0) { if (projection.get_IsSame(m_mapWin.Project.GeoProjection)) { if (names.Count() > 0) { if (MessageBox.Show("Do you want to add layers to the project?", m_mapWin.ApplicationInfo.ApplicationName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { m_mapWin.Layers.StartAddingSession(); foreach (string filename in names) { m_mapWin.Layers.Add(filename); } m_mapWin.Layers.StopAddingSession(); } } else { MessageBox.Show("No files to add to the map.", m_mapWin.ApplicationInfo.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information); } } else { MessageBox.Show("Chosen projection is different from the project one. The layers can't be added to map.", m_mapWin.ApplicationInfo.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information); } } else { MessageBox.Show("No files to add to the map.", m_mapWin.ApplicationInfo.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information); } }