DayDreamInGIS 之 ArcGIS Pro二次开发 锐角检查

功能:检查图斑中所有的夹角,如果为锐角,在单独的标记图层中标记。生成的结果放在默认gdb中,以 图层名_锐角检查 的方式命名

大体实现方式:遍历图层中的所有要素(多部件要素分别处理),对每个夹角进行判断。

具体功能与ArcMap中锐角检查工具类似

DayDreamInGIS数据处理工具 V1.1.5_beta 锐角检查工具源码与解析_daydreamingistool-CSDN博客

工具界面:

(使用prowindow,样式确实更和谐)

界面代码:

<controls:ProWindow x:Class="DayDreamInGISTool.CornerCheck.CornerCheckWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:controls="clr-namespace:ArcGIS.Desktop.Framework.Controls;assembly=ArcGIS.Desktop.Framework"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions"mc:Ignorable="d"Title="锐角检查" Width="500" Height="200" WindowStartupLocation="CenterOwner"><controls:ProWindow.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><extensions:DesignOnlyResourceDictionary Source="pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></controls:ProWindow.Resources><Grid Margin="5"><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="90"></ColumnDefinition><ColumnDefinition></ColumnDefinition></Grid.ColumnDefinitions><Label VerticalAlignment="Center" HorizontalAlignment="Right">图层</Label><ComboBox Grid.Column="1" Name="cmbLayer" VerticalAlignment="Center" Height="27"></ComboBox></Grid><Grid Grid.Row="1"><Grid.ColumnDefinitions><ColumnDefinition Width="90"></ColumnDefinition><ColumnDefinition></ColumnDefinition></Grid.ColumnDefinitions><Label VerticalAlignment="Center" HorizontalAlignment="Right">角度阈值(度)</Label><TextBox Grid.Column="1" Name="txtYuzhi" VerticalAlignment="Center" Height="27" Text="10"></TextBox></Grid><Grid Grid.Row="2"><Grid.ColumnDefinitions><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition></Grid.ColumnDefinitions><Button Width="140" Height="35" Name="btnOK" Click="btnOK_Click">确定</Button><Button Width="140" Height="35" Grid.Column="1" Name="btnCancel" Click="btnCancel_Click">取消</Button></Grid></Grid>
</controls:ProWindow>

界面交互代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using RGeometry=ArcGIS.Core.Geometry;
using GISCommonHelper;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Core;
using ArcGIS.Core.Data.DDL;
using ArcGIS.Desktop.Editing;
using ArcGIS.Core.Data.Exceptions;
using ArcGIS.Core.Internal.CIM;namespace DayDreamInGISTool.CornerCheck
{/// <summary>/// Interaction logic for CornerCheckWindow.xaml/// </summary>public partial class CornerCheckWindow : ArcGIS.Desktop.Framework.Controls.ProWindow{private FeatureLayer player;private double yuzhi;public CornerCheckWindow(){InitializeComponent();try{var map = MapView.Active.Map;cmbLayer.setLyrlist<FeatureLayer>(map, (o, e) =>{if (cmbLayer.SelectedIndex != -1){Player = this.cmbLayer.SelectedValue as FeatureLayer;}});}catch (Exception){}}public FeatureLayer Player { get => player; set => player = value; }public double Yuzhi { get => yuzhi; set => yuzhi = value; }private void btnCancel_Click(object sender, RoutedEventArgs e){this.DialogResult = false;}private void btnOK_Click(object sender, RoutedEventArgs e){if (this.cmbLayer.SelectedIndex == -1){MessageBox.Show("请设置图层");return;}if(double.TryParse(txtYuzhi.Text,out yuzhi)){}else{MessageBox.Show("阈值必须为数字");return;}this.DialogResult = true;}}
}

核心逻辑代码,放在ProWindow的showButton中。

using ArcGIS.Core.CIM;
using ArcGIS.Core.Data;
using ArcGIS.Core.Data.DDL;
using ArcGIS.Core.Data.Exceptions;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing;
using ArcGIS.Desktop.Extensions;
using ArcGIS.Desktop.Framework;
using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Layouts;
using ArcGIS.Desktop.Mapping;
using GISCommonHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;namespace DayDreamInGISTool.CornerCheck
{internal class ShowCornerCheckWindow : Button{private CornerCheckWindow _cornercheckwindow = null;private FeatureClass resultFtCls = null;string orignoidfdnm = "Orign_OId";  //源oidstring corneranglefdnm = "CornerAngle";  //夹角string targetanglefdnm = "Angle";  //指向角string summaryfdnm = "Summary";  //其他说明private FeatureLayer pftlyr;private double yuzhi;ProgressDialog progDlg = null;CancelableProgressorSource progSrc = null;protected override void OnClick(){//already open?if (_cornercheckwindow != null)return;_cornercheckwindow = new CornerCheckWindow();_cornercheckwindow.Owner = FrameworkApplication.Current.MainWindow;//_cornercheckwindow.Closed += (o, e) => { _cornercheckwindow = null; };//_cornercheckwindow.Show();//uncomment for modaltry{progDlg = new ProgressDialog($"锐角检查中...", "取消", 100, true);bool? res = _cornercheckwindow.ShowDialog();if (res.Value){yuzhi = _cornercheckwindow.Yuzhi;pftlyr = _cornercheckwindow.Player;//{pftlyr.GetDefinition().Name} progDlg.Show();progSrc = new CancelableProgressorSource(progDlg);execute();}}catch (Exception ex){MessageBox.Show("发生未知异常_"+ex.Message);}finally{if (progDlg != null){progDlg.Hide();progDlg.Dispose();}_cornercheckwindow = null;}}private void execute(){//暂时不做进度条QueuedTask.Run(() =>{long ftcount=pftlyr.GetFeatureClass().GetCount();progSrc.Progressor.Max = (uint)ftcount;resultFtCls = createResultFtCls();FeatureClass ftcls = pftlyr.GetFeatureClass();using (RowCursor cursor = ftcls.Search()){EditOperation editOperation = new EditOperation();while (cursor.MoveNext()){using (Feature feature = cursor.Current as Feature){long oid = feature.GetObjectID();Geometry geo = feature.GetShape();if (geo.GeometryType == ArcGIS.Core.Geometry.GeometryType.Polygon){var polygon = geo as Polygon;check(polygon, oid, editOperation);}progSrc.Progressor.Value++;progSrc.Message = $"要素:{oid} 检查完成";}}string message = "";try{// 执行编辑操作bool creationResult = editOperation.Execute();// 如果操作失败,存储错误消息if (!creationResult) { message = editOperation.ErrorMessage; }}catch (GeodatabaseException exObj){// 如果出现地理数据库异常,存储异常消息message = exObj.Message;throw;}}},progSrc.Progressor);}private void check(Polygon polygon, long oid, EditOperation editOperation){//多部件要素,每个部分单独处理var list = GeometryEngine.Instance.MultipartToSinglePart(polygon);foreach (var item in list){CornerAngleCheck(item as Polygon, yuzhi, oid, editOperation);}}private void CornerAngleCheck(Polygon pPolygon, double tolerance, long oid, EditOperation editOperation){var pntCol = pPolygon.Points;for (int i = 0; i < pntCol.Count - 1; i++)  //循环,多边形的点首尾相接,最后一个点不用核查{MapPoint currentpnt = pntCol[i];MapPoint prePoint = null;MapPoint nextPoint = null;if (i == 0){prePoint = pntCol[pntCol.Count - 2];  //获取倒数第二个点,即为肉眼意义上的前一个点}else{prePoint = pntCol[i - 1];}if (i == pntCol.Count - 2){nextPoint = pntCol[0];}else{nextPoint = pntCol[i + 1];}double ca = calcCornerAngle(currentpnt, prePoint, nextPoint);double aindegredd = GISCommonHelper.MathHelper.Radian2Degree(ca);double d1 = GISCommonHelper.GeometryHelper.getDistance(currentpnt, prePoint);double d2 = GISCommonHelper.GeometryHelper.getDistance(currentpnt, nextPoint);//定位点距离大致算double dis = (d1 + d2) / 5.0;  //平均边长的十分之一处//生成定位点MapPoint pc = GeometryEngine.Instance.ConstructPointFromAngleDistance(currentpnt, GISCommonHelper.GeometryHelper.getAngle(currentpnt, prePoint) + ca / 2.0, dis);if (aindegredd <= tolerance){editOperation.Callback(context => {using RowBuffer rowBuffer = resultFtCls.CreateRowBuffer();rowBuffer[orignoidfdnm] = oid;rowBuffer[corneranglefdnm] = aindegredd;//rowBuffer[targetanglefdnm] = 0;  //指向角度//构建线Polyline pln = GISCommonHelper.GeometryHelper.getPolyline(pc, currentpnt, MapView.Active.Map.SpatialReference);rowBuffer[resultFtCls.GetDefinition().GetShapeField()] = pln;using Feature feature = resultFtCls.CreateRow(rowBuffer);context.Invalidate(feature);}, resultFtCls);}else{//非锐角}}}/// <summary>/// 计算夹角 返回结果弧度/// </summary>/// <param name="cPnt">顶点</param>/// <param name="p1">起点</param>/// <param name="p2">结点</param>/// <returns>弧度</returns>public double calcCornerAngle(MapPoint cPnt, MapPoint p1, MapPoint p2){double a1 = GISCommonHelper.GeometryHelper.getAngle(cPnt, p1);double a2 = GISCommonHelper.GeometryHelper.getAngle(cPnt, p2);double a = a2 - a1;if (a < 0){a = a + Math.PI * 2;}return a;}string ruijiaojcfcname = "锐角检查";/// <summary>/// 创建结果要素类 默认/// </summary>/// <returns></returns>private FeatureClass createResultFtCls(){ruijiaojcfcname = $"{pftlyr.GetDefinition().Name}_锐角检查";var sr = pftlyr.GetFeatureClass().GetDefinition().GetSpatialReference();//在当前数据库中创建var DefaultGDB = Project.Current.DefaultGeodatabasePath;using (Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(DefaultGDB)))){bool isexist = gdb.FeatureClassExists(ruijiaojcfcname);//如果存在,则先删除if (isexist){var dr=MessageBox.Show("工作空间已经存在锐角检查数据集,是否删除?", "提示", System.Windows.MessageBoxButton.YesNo);if(dr== System.Windows.MessageBoxResult.Yes){//删除已有var featureclass = gdb.OpenDataset<FeatureClass>(ruijiaojcfcname);FeatureClassDescription fdc = new FeatureClassDescription(featureclass.GetDefinition());SchemaBuilder sb3 = new SchemaBuilder(gdb);sb3.Delete(fdc);}else{ruijiaojcfcname = $"锐角检查_{DateTime.Now.GetTimeStamp()}";}progSrc.Progressor.Message = $"创建结果数据集 {ruijiaojcfcname} 完成";}var hasZ = false;var hasM = false;var shapeDescription = new ShapeDescription(GeometryType.Polyline, sr){HasM = hasM,HasZ = hasZ};var f0 = new ArcGIS.Core.Data.DDL.FieldDescription("OBJECTID", FieldType.OID);var f1 = new ArcGIS.Core.Data.DDL.FieldDescription(orignoidfdnm, FieldType.Integer);var f2 = new ArcGIS.Core.Data.DDL.FieldDescription(corneranglefdnm, FieldType.Double);var f3 = new ArcGIS.Core.Data.DDL.FieldDescription(targetanglefdnm, FieldType.Double);var f4 = new ArcGIS.Core.Data.DDL.FieldDescription(summaryfdnm, FieldType.String);f4.Length = 80;var fieldDescriptions = new List<ArcGIS.Core.Data.DDL.FieldDescription>(){f0,f1,f2,f3,f4};//创建FeatureClassDescriptionvar fcDescription = new FeatureClassDescription(ruijiaojcfcname, fieldDescriptions, shapeDescription);//创建SchemaBuilderSchemaBuilder sb = new SchemaBuilder(gdb);sb.Create(fcDescription);bool success = sb.Build();var featureclass2 = gdb.OpenDataset<FeatureClass>(ruijiaojcfcname); ;  //再次打开//添加图层Uri uu = featureclass2.GetPath();var layer = LayerFactory.Instance.CreateLayer(uu, MapView.Active.Map, 0, ruijiaojcfcname);return featureclass2;}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/276922.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SQL Server】实验七 数据完整性

1 实验目的 掌握实体完整性、参照完整性和用户自定义完整性约束的创建方法。掌握完整性约束的运行检查机制。掌握参照完整性的级联删除和修改方法。掌握正确设计关系模式完整性约束的方法。 2 实验内容 2.1 掌握实体完整性约束的创建和使用方法 创建表时定义由一个属性组成…

最好用的流程编辑器bpmn-js系列之基本使用

BPMN&#xff08;Business Process Modeling Notation&#xff09;是由业务流程管理倡议组织BPMI&#xff08;The Business Process Management Initiative&#xff09;开发的一套标准的业务流程建模符号规范。其目的是为用户提供一套容易理解的标准符号&#xff0c;这些符号作…

C++笔记:从零开始一步步手撕高阶数据结构AVL树

文章目录 高度平衡二叉搜索树实现一颗AVL树结点与树的描述——定义类AVL树的插入操作步骤1&#xff1a;按照二叉搜索树的方法插入结点步骤2&#xff1a;自底向上调整平衡因子步骤3&#xff1a;触发旋转操作&#xff08;AVL树平衡的精髓&#xff09;右单旋左单旋左右双旋右左双旋…

基于openresty构建运维工具链实践

本文字数&#xff1a;4591字 预计阅读时间&#xff1a;25 01 导读 如今OpenResty已广泛被各个互联网公司在实际生产环境中应用&#xff0c;在保留Nginx高并发、高稳定等特性基础上&#xff0c;通过嵌入Lua来提升在负载均衡层的开发效率并保证其高性能。本文主要介绍接口鉴权、流…

Spring Cloud Alibab 入门搭建,包含Nacos中心,注册服务发现服务,Feign请求,GateWay网关,sentinel限流

源码在最后 一、安装Nacos注册中心 1.1查看Nacos官网&#xff0c;安装Nacos服务&#xff0c;下载源码或者安装包 1.2启动服务&#xff0c;默认端口为8848&#xff0c; 二、创建服务注册&发现 2.1使用脚手架&#xff0c;创建注册服务和发现服务项目&#xff0c;我用的版…

.NET开源快速、强大、免费的电子表格组件

今天大姚给大家分享一个.NET开源&#xff08;MIT License&#xff09;、快速、强大、免费的电子表格组件&#xff0c;支持数据格式、冻结、大纲、公式计算、图表、脚本执行等。兼容 Excel 2007 (.xlsx) 格式&#xff0c;支持WinForm、WPF和Android平台&#xff1a;ReoGrid。 项…

【机器学习300问】34、决策树对于数值型特征如果确定阈值?

还是用之前的猫狗二分类任务举例&#xff08;这个例子出现在【机器学习300问】第33问中&#xff09;&#xff0c;我们新增一个数值型特征&#xff08;体重&#xff09;&#xff0c;下表是数据集的详情。如果想了解更多决策树的知识可以看看我之前的两篇文章&#xff1a; 【机器…

Linux从0到1——Linux第一个小程序:进度条

Linux从0到1——Linux第一个小程序&#xff1a;进度条 1. 输出缓冲区2. 回车和换行的本质3. 实现进度条3.1 简单原理版本3.2 实际工程版本 1. 输出缓冲区 1. 小实验&#xff1a; 编写一个test.c文件&#xff0c;&#xff1a; #include <stdio.h> #include <unistd.h…

详解命令docker run -d --name container_name -e TZ=Asia/Shanghai your_image

docker run 是Docker的主要命令&#xff0c;用于从镜像启动一个新的容器。下面详细解释并举例说明 -d, --name, -e TZ 参数的用法&#xff1a; -d 或 --detach&#xff1a; 这个标志告诉Docker以守护进程&#xff08;后台&#xff09;模式运行容器。这意味着当你执行 docker ru…

学习笔记-华为IPD转型2020:1,IPD的重要意义

华为产品开发转型&#xff1a;IPD计划 大多数公司发现&#xff0c;当公司大幅增长时&#xff0c;在较小规模上有效的管理实践不再有效。产品开发过程也是如此。随着华为的发展&#xff0c;该公司遇到了产品故障率更高、开发周期更长和研发成本增加等问题。然后&#xff0c;它转…

Lord 3DMCV7-AHRS 时间同步硬件触发设置

目的:通过FPGA发送脉冲触发IMU采集数据。FPGA发送脉冲时,IMU才有数据产生。 FPGA与IMU的硬件接线就不讲了,这里主要说明的是IMU的设置以及ROS驱动的config文件更改。 1. WIN上位机设置 通过IMU在WINDOWS的上位机SensorConnect对IMU的GPIO、波特率等基本功能进行设值,具体…

Unity PS5开发 天坑篇 之 申请开发者与硬件部署01

腾了好几天终于把PS5开发机调试部署成功, 希望能帮到国内的开发者, 主机游戏PlayStation/Nintendo Switch都是比较闭塞的&#xff0c;开发者账号是必须的。 开发环境有两个部分&#xff0c;一是DEV Kit 开发机, TEST Kit测试机两部分组成&#xff0c;二是Unity的支持库(安装后…

vue使用elementPlus ui框架,如何给Dialog 对话框添加Loading 自定义类名显示隐藏

vue使用elementPlus ui框架时&#xff0c;如何给Dialog 对话框添加Loading 自定义类名&#xff0c;想要实现dialog对话框区域有loading效果 官方给出的这个API配置项customClass&#xff0c;使用不太明确。暂时无法实现绑定class。 最后的实现方式&#xff1a; <template&…

3、设计模式之工厂模式2(Factory)

一、什么是工厂模式 工厂模式属于创建型设计模式&#xff0c;它用于解耦对象的创建和使用。通常情况下&#xff0c;我们创建对象时需要使用new操作符&#xff0c;但是使用new操作符创建对象会使代码具有耦合性。工厂模式通过提供一个公共的接口&#xff0c;使得我们可以在不暴露…

【小白学机器学习8】统计里的自由度DF=degree of freedom, 以及关于df=n-k, df=n-k-1, df=n-1 等自由度公式

目录 1 自由度 /degree of freedom / df 1.1 物理学的自由度 1.2 数学里的自由度 1.2.1 数学里的自由度 1.2.2 用线性代数来理解自由度&#xff08;需要补充&#xff09; 1.2.3 统计里的自由度 1.3 统计学里自由度的定义 2 不同对象的自由度 2.1 纯公式的自由度&#…

idea:忽略不要搜索unpackage文件夹

开发vue时搜索关键字&#xff0c;会搜索到编译后的文件&#xff0c;如unpackage。&#xff08;注意这个是idea工具&#xff0c;和Git忽略是有区别的&#xff09; File->Settings->Editor->File Types

【C++ 设计模式】策略模式与简单工厂模式的结合

文章目录 前言一、为什么需要策略模式简单工厂模式二、策略模式简单工厂模式实现原理三、UML图四、示例代码总结 前言 在软件设计中&#xff0c;常常会遇到需要根据不同情况选择不同算法或行为的情况。策略模式和简单工厂模式是两种常见的设计模式&#xff0c;它们分别解决了对…

.Net Core 中间件验签

文章目录 为什么是用中间件而不是筛选器&#xff1f;代码实现技术要点context.Request.EnableBuffering()指针问题 小结 为什么是用中间件而不是筛选器&#xff1f; 为什么要用中间件验签&#xff0c;而不是筛选器去验签? 1、根据上图我们可以看到&#xff0c;中间件在筛选器之…

专业无网设备如何远程运维?向日葵远程控制能源场景案例解析

清洁能源领域&#xff0c;拥有庞大的上下游产业链&#xff0c;涉及的相关工业设备门类多、技术覆盖全、行业应用广。在这一领域内&#xff0c;相关专业设备的供应商的核心竞争力除了本身产品的技术能力之外&#xff0c;服务也是重要的一环。 某企业作为致力于节能环保方向的气…

spy分析文件另存为弹框【selenium】

有时需要下载多个文件&#xff0c;但是不想保存在同一个目录下&#xff0c;需要做两步 selenium设置浏览器默认下载路径&#xff0c;这个路径需要是个不存在的路径操作文件另存为弹框 文章目录 selenium设置浏览器默认下载路径操作文件另存为弹框 selenium设置浏览器默认下载路…