【ArcGIS Pro二次开发】(82):玩个花活_控规指标块生成

一、要实现的效果

废话不多说,这次要实现的是类似控规指标块的标注:

这里只是示例,用了5个格子,做成9个格子也是可以的。

实现这个效果最关键的是要用到Pro中的复合标注。

关于复合标注的用法可以搜一下帮助里的【使用复合注释的标注】:

这里要介绍的是如何在SDK实现复合标注的功能。


二、实现思路

1、获取标注类CIMLabelClass

常规操作,获取图层------图层定义------标注类。

cs 复制代码
// 获取图层
FeatureLayer featureLayer = MapView.Active.GetSelectedLayers().FirstOrDefault() as FeatureLayer;
// 获取图层定义
CIMFeatureLayer lyrDefn = featureLayer.GetDefinition() as CIMFeatureLayer;

// 获取标注
var listLabelClasses = lyrDefn.LabelClasses.ToList();
CIMLabelClass theLabelClass = listLabelClasses.FirstOrDefault();
2、修改标注表达式

将标注语言修改为Arcade,这里官方推荐用Arcade,我也就用它了。

按照帮助里的写法,根据图层的字段,修改一下表达式。

cs 复制代码
// 设置标注语言为Arcade
theLabelClass.ExpressionEngine = LabelExpressionEngine.Arcade;
// 设置标注内容
string code = "`<PART position=\"top\">${$feature.DLMC}</PART><PART position=\"left\">${$feature.DLBM}</PART><PART position=\"middle\">${$feature.TBBH}</PART><PART position=\"right\">${$feature.ZLDWMC}</PART><PART position=\"bottom\">${$feature.QSXZ}</PART>`";

theLabelClass.Expression = code;

这里实际上是复制了在Pro里的手动操作,对应的在Pro里的操作步骤如下:

3、设置标注符号

首先获取图层自身的标注符号,然后在这个基础上进行修改。

cs 复制代码
// 创建一个标注符号CIMTextSymbol
CIMTextSymbol textSymbol = theLabelClass.TextSymbol.Symbol as CIMTextSymbol;

设置文本的前后缩进,不然文字会挤在一起,不美观。

cs 复制代码
// 设置文本前后缩进
textSymbol.IndentAfter = 5;
textSymbol.IndentBefore = 5;

以上都是常规设置,下面是最重要的复合标注的设置。

新建一个注释类CIMCompositeCallout。

cs 复制代码
// 创建一个CIMCompositeCallout
CIMCompositeCallout ccs = new CIMCompositeCallout();

给它创建一个背景符号,设置背景颜色、形式、边框颜色等,并应用。

cs 复制代码
// 创建一个面符号CIMPolygonSymbol
CIMPolygonSymbol polySymbol = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.CreateRGBColor(170, 241, 247, 50), SimpleFillStyle.Solid);
// 设置边框线颜色
polySymbol.SetOutlineColor(ColorFactory.Instance.CreateRGBColor(0, 0, 255, 80));

// 应用面符号
ccs.BackgroundSymbol = polySymbol;

默认的边框拐角挺碍眼,给它取消掉。

cs 复制代码
// 拐角半径
ccs.CornerRadius = 0;

文字的边距也设置下,这个随意,美观为主。

cs 复制代码
// 边距
ccs.Margin = new CIMTextMargin()
{
    Left = 2, Top = 2, Right = 2, Bottom = 2
};

对应的Pro操作如下:

下一步是对复合标注各个位置属性的设置。

示例里用到了5个格子,所以只设置【top、left、middle、right、bottom】5个部件就行了。

cs 复制代码
// 设置各部分属性
CIMCompositeTextPartPosition top = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Bottom,
    HorizontalAlignment = HorizontalAlignment.Center,
};
CIMCompositeTextPartPosition left = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Center,
    HorizontalAlignment = HorizontalAlignment.Right,
};
CIMCompositeTextPartPosition middle = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Center,
};
CIMCompositeTextPartPosition right = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Center,
    HorizontalAlignment = HorizontalAlignment.Left,
};
CIMCompositeTextPartPosition bottom = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Top,
};

ccs.Top = top;
ccs.Left = left;
ccs.Middle = middle;
ccs.Right = right;
ccs.Bottom = bottom;

这里设置的主要内容是:在标注框内包含元素,水平和垂直对齐。

其实还可以设置XY偏移等内容,看需要吧。

对应的Pro操作如下:

最后,应用标注给图层就行了。

cs 复制代码
// 应用标注符号
textSymbol.Callout = ccs;

// 应用标注设置
lyrDefn.LabelClasses[0] = theLabelClass; // 假设只有一个标注类别

// 应用标注
featureLayer.SetDefinition(lyrDefn);

// 打开标注
if (!featureLayer.IsLabelVisible) { featureLayer.SetLabelVisibility(true); }

三、完整代码

cs 复制代码
// 获取图层
FeatureLayer featureLayer = MapView.Active.GetSelectedLayers().FirstOrDefault() as FeatureLayer;
// 获取图层定义
CIMFeatureLayer lyrDefn = featureLayer.GetDefinition() as CIMFeatureLayer;

// 获取标注
var listLabelClasses = lyrDefn.LabelClasses.ToList();
CIMLabelClass theLabelClass = listLabelClasses.FirstOrDefault();

// 设置标注语言为Arcade
theLabelClass.ExpressionEngine = LabelExpressionEngine.Arcade;
// 设置标注内容
string code = "`<PART position=\"top\">${$feature.DLMC}</PART><PART position=\"left\">${$feature.DLBM}</PART><PART position=\"middle\">${$feature.TBBH}</PART><PART position=\"right\">${$feature.ZLDWMC}</PART><PART position=\"bottom\">${$feature.QSXZ}</PART>`";

theLabelClass.Expression = code;

// 创建一个标注符号CIMTextSymbol
CIMTextSymbol textSymbol = theLabelClass.TextSymbol.Symbol as CIMTextSymbol;
// 设置文本前后缩进
textSymbol.IndentAfter = 5;
textSymbol.IndentBefore = 5;

// 创建一个CIMCompositeCallout
CIMCompositeCallout ccs = new CIMCompositeCallout();

// 创建一个面符号CIMPolygonSymbol
CIMPolygonSymbol polySymbol = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.CreateRGBColor(170, 241, 247, 50), SimpleFillStyle.Solid);
// 设置边框线颜色
polySymbol.SetOutlineColor(ColorFactory.Instance.CreateRGBColor(0, 0, 255, 80));

// 应用面符号
ccs.BackgroundSymbol = polySymbol;
// 拐角半径
ccs.CornerRadius = 0;
// 边距
ccs.Margin = new CIMTextMargin()
{
    Left = 2,
    Top = 2,
    Right = 2,
    Bottom = 2
};

// 设置各部分属性
CIMCompositeTextPartPosition top = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Bottom,
    HorizontalAlignment = HorizontalAlignment.Center,
};
CIMCompositeTextPartPosition left = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Center,
    HorizontalAlignment = HorizontalAlignment.Right,
};
CIMCompositeTextPartPosition middle = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Center,
};
CIMCompositeTextPartPosition right = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Center,
    HorizontalAlignment = HorizontalAlignment.Left,
};
CIMCompositeTextPartPosition bottom = new CIMCompositeTextPartPosition()
{
    IsPartWithinCalloutBox = true,
    VerticalAlignment = VerticalAlignment.Top,
};

ccs.Top = top;
ccs.Left = left;
ccs.Middle = middle;
ccs.Right = right;
ccs.Bottom = bottom;

// 应用标注符号
textSymbol.Callout = ccs;

// 应用标注设置
lyrDefn.LabelClasses[0] = theLabelClass; // 假设只有一个标注类别

// 应用标注
featureLayer.SetDefinition(lyrDefn);

// 打开标注
if (!featureLayer.IsLabelVisible) { featureLayer.SetLabelVisibility(true); }
相关推荐
q__y__L1 小时前
C# WaitHandle类的几个有用的函数
java·开发语言·c#
步、步、为营2 小时前
.NET8 正式发布, C#12 新变化
ui·c#·.net
伽蓝_游戏3 小时前
Unity UI的未来之路:从UGUI到UI Toolkit的架构演进与特性剖析(7)
游戏·ui·unity·架构·c#·游戏引擎·.net
q__y__L7 小时前
C#线程同步(三)线程安全
安全·性能优化·c#
程序设计实验室9 小时前
纯 C#实现+AOT 打造的多功能图片处理工具 ImageGlider
c#·aot
新中地GIS开发老师11 小时前
2025Mapbox零基础入门教程(14)定位功能
前端·javascript·arcgis·gis·mapbox·gis开发·地理信息科学
BuHuaX16 小时前
Unity_数据持久化_IXmlSerializable接口
xml·unity·c#·游戏引擎·游戏策划
格林威16 小时前
Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现路口车辆速度的追踪识别(C#代码UI界面版)
人工智能·深度学习·数码相机·yolo·计算机视觉·c#·视觉检测
CodeCraft Studio17 小时前
国产化Word处理控件Spire.Doc教程:Python提取Word文档中的文本、图片、表格等
python·c#·word·国产化·spire.doc·word文档处理·文档开发控件
Kookoos17 小时前
ABP VNext + Quartz.NET vs Hangfire:灵活调度与任务管理
c#·.net·hangfire·quartz.net·abp vnext