新增点线面简单符号系统设置的MCP
This commit is contained in:
parent
468d13b9d1
commit
2f63c86891
250
client/tool/ArcGisProSymbology.cs
Normal file
250
client/tool/ArcGisProSymbology.cs
Normal file
@ -0,0 +1,250 @@
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Core;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using LinkToolAddin.server;
|
||||
using ModelContextProtocol.Server;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace LinkToolAddin.client.tool
|
||||
{
|
||||
public class ArcGisProSymbology
|
||||
{
|
||||
/// <summary>
|
||||
/// 将 System.Drawing.Color 转换为 CIMColor(支持 RGB 和透明度)
|
||||
/// </summary>
|
||||
private static CIMColor ColorToCIMColor(int r, int g, int b, double alpha =0)
|
||||
{
|
||||
return ColorFactory.Instance.CreateRGBColor(r, g, b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造点符号引用(封装 SymbolFactory 调用)
|
||||
/// </summary>
|
||||
private static CIMSymbolReference GetPointSymbolRef(int r, int g, int b, float size)
|
||||
{
|
||||
CIMColor color = ColorToCIMColor(r, g, b);
|
||||
CIMPointSymbol symbol = SymbolFactory.Instance.ConstructPointSymbol(color, size);
|
||||
return symbol.MakeSymbolReference();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造线符号引用
|
||||
/// </summary>
|
||||
private static CIMSymbolReference GetLineSymbolRef(int r, int g, int b, float width)
|
||||
{
|
||||
CIMColor color = ColorToCIMColor(r, g, b);
|
||||
|
||||
// 手动创建线符号图层
|
||||
CIMSolidStroke stroke = new CIMSolidStroke
|
||||
{
|
||||
Color = color,
|
||||
Width = width,
|
||||
CapStyle = LineCapStyle.Round, // 端点样式:圆头
|
||||
JoinStyle = LineJoinStyle.Round, // 连接处样式:圆角
|
||||
Enable = true // 必须启用!
|
||||
};
|
||||
|
||||
// 创建线符号并设置图层
|
||||
CIMLineSymbol symbol = new CIMLineSymbol
|
||||
{
|
||||
SymbolLayers = new CIMSymbolLayer[] { stroke }
|
||||
};
|
||||
|
||||
return symbol.MakeSymbolReference();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造面符号引用(填充 + 轮廓)
|
||||
/// </summary>
|
||||
private static CIMSymbolReference GetPolygonSymbolRef(
|
||||
int fillR, int fillG, int fillB,
|
||||
int outlineR, int outlineG, int outlineB,
|
||||
float outlineWidth)
|
||||
{
|
||||
// 填充图层
|
||||
CIMSolidFill fillLayer = new CIMSolidFill
|
||||
{
|
||||
Color = ColorToCIMColor(fillR, fillG, fillB)
|
||||
};
|
||||
|
||||
// 轮廓图层
|
||||
CIMSolidStroke outlineLayer = new CIMSolidStroke
|
||||
{
|
||||
Color = ColorToCIMColor(outlineR, outlineG, outlineB),
|
||||
Width = outlineWidth,
|
||||
JoinStyle = LineJoinStyle.Round//圆角
|
||||
};
|
||||
|
||||
CIMPolygonSymbol polygonSymbol = new CIMPolygonSymbol
|
||||
{
|
||||
SymbolLayers = new CIMSymbolLayer[] { fillLayer, outlineLayer }
|
||||
};
|
||||
|
||||
return polygonSymbol.MakeSymbolReference();
|
||||
}
|
||||
|
||||
// ==================== 工具方法 ====================
|
||||
|
||||
[McpServerTool, Description("可以通过调用 ArcGIS Pro 的符号系统,设置点图层的符号颜色和大小。" +
|
||||
"此工具将分析要素数据特征与当前地图布局,智能生成符合视觉美学原则的点状符号。" +
|
||||
"传入参数必须包括红(R)、绿(G)、蓝(B)三种颜色分量(0-255)、符号尺寸(单位:点)以及目标图层名称。" +
|
||||
"系统在设置过程中综合考虑颜色对比度、符号可辨性、形状匹配度及整体地图协调性等因素," +
|
||||
"动态调整或创建新的符号配置,避免视觉拥挤或信息弱化问题。" +
|
||||
"最终输出一个优化后的点符号系统配置,可直接应用于指定的点要素图层,显著提升地图的视觉层次感与信息传达效率。" +
|
||||
"适用于城市位置、监测站点、兴趣点(POI)等点状地理要素的可视化表达场景。")]
|
||||
public static async Task<JsonRpcResultEntity> SetPointColor(string r, string g, string b, string layerName, string size)
|
||||
{
|
||||
return await SetSymbolAsync(layerName, esriGeometryType.esriGeometryPoint, () =>
|
||||
{
|
||||
return GetPointSymbolRef(int.Parse(r), int.Parse(g), int.Parse(b), float.Parse(size));
|
||||
}, "点符号");
|
||||
}
|
||||
|
||||
[McpServerTool, Description("可以通过调用 ArcGIS Pro 的符号系统,设置线图层的符号颜色和宽度。" +
|
||||
"此工具将分析要素数据和当前地图布局,智能选择或生成符合视觉美学原则的线符号。" +
|
||||
"传入参数必须包括 RGB 三种颜色分量、线符号宽度以及目标图层名称。" +
|
||||
"系统会综合考虑颜色对比度、线型协调性、地图整体可读性等因素,动态调整或创建新的符号配置。" +
|
||||
"最终输出一个优化后的线符号系统,可直接应用于指定的线要素图层,显著提升地图的视觉表达效果与信息传达清晰度。" +
|
||||
"适用于道路、河流、边界等线状要素的符号化场景。")]
|
||||
public static async Task<JsonRpcResultEntity> SetLineColor(string r, string g, string b, string layerName, string width)
|
||||
{
|
||||
|
||||
return await SetSymbolAsync(layerName, esriGeometryType.esriGeometryPolyline, () =>
|
||||
{
|
||||
return GetLineSymbolRef(int.Parse(r), int.Parse(g), int.Parse(b), float.Parse(width));
|
||||
}, "线符号");
|
||||
}
|
||||
|
||||
[McpServerTool, Description("设置面图层的填充颜色、轮廓颜色和轮廓宽度。" +
|
||||
"此工具将调用 ArcGIS Pro 符号系统,智能生成符合视觉美学的面符号。" +
|
||||
"传入参数包括:填充颜色的RGB值、轮廓颜色的RGB值、轮廓宽度、图层名称。" +
|
||||
"最终将优化后的符号应用于指定的面要素图层,提升地图可视化效果。")]
|
||||
public static async Task<JsonRpcResultEntity> SetPolygonColor(string fillR, string fillG, string fillB,
|
||||
string outlineR, string outlineG, string outlineB, string outlineWidth, string layerName)
|
||||
{
|
||||
return await SetSymbolAsync(layerName, esriGeometryType.esriGeometryPolygon, () =>
|
||||
{
|
||||
return GetPolygonSymbolRef(int.Parse(fillR), int.Parse(fillG), int.Parse(fillB), int.Parse(outlineR), int.Parse(outlineG), int.Parse(outlineB), float.Parse(outlineWidth));
|
||||
}, "面符号");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通用符号设置逻辑(封装重复代码)
|
||||
/// </summary>
|
||||
private async static Task<JsonRpcResultEntity> SetSymbolAsync(
|
||||
string layerName,
|
||||
esriGeometryType expectedType,
|
||||
Func<CIMSymbolReference> symbolFactory,
|
||||
string symbolTypeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Map map = MapView.Active?.Map;
|
||||
if (map == null)
|
||||
{
|
||||
return new JsonRpcErrorEntity
|
||||
{
|
||||
Error = new Error
|
||||
{
|
||||
Code = "404",
|
||||
Message = "当前没有激活的地图"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
FeatureLayer featureLayer = map.GetLayersAsFlattenedList()
|
||||
.OfType<FeatureLayer>()
|
||||
.FirstOrDefault(l => l.Name == layerName);
|
||||
|
||||
if (featureLayer == null)
|
||||
{
|
||||
return(new JsonRpcErrorEntity
|
||||
{
|
||||
Error = new Error
|
||||
{
|
||||
Code = "404",
|
||||
Message = $"找不到名为 '{layerName}' 的图层"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (featureLayer.ShapeType != expectedType)
|
||||
{
|
||||
return(new JsonRpcErrorEntity
|
||||
{
|
||||
Error = new Error
|
||||
{
|
||||
Code = "400",
|
||||
Message = $"指定图层 '{layerName}' 不是{symbolTypeName}图层"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CIMRenderer renderer = null;
|
||||
|
||||
await QueuedTask.Run(async () =>
|
||||
{
|
||||
renderer = featureLayer.GetRenderer();
|
||||
});
|
||||
CIMSimpleRenderer simpleRenderer = renderer as CIMSimpleRenderer;
|
||||
if (simpleRenderer == null)
|
||||
{
|
||||
return(new JsonRpcErrorEntity
|
||||
{
|
||||
Error = new Error
|
||||
{
|
||||
Code = "400",
|
||||
Message = $"图层 '{layerName}' 的渲染器不是简单渲染器,无法设置"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await QueuedTask.Run(async () =>
|
||||
{
|
||||
CIMSymbolReference symbolRef = symbolFactory();
|
||||
simpleRenderer.Symbol = symbolRef;
|
||||
featureLayer.SetRenderer(renderer);
|
||||
});
|
||||
|
||||
return (new JsonRpcSuccessEntity
|
||||
{
|
||||
Result = $"{symbolTypeName}设置成功",
|
||||
Id = GetIdForType(expectedType)
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 捕获 QueuedTask 外层异常(如线程中断等)
|
||||
return new JsonRpcErrorEntity
|
||||
{
|
||||
Error = new Error
|
||||
{
|
||||
Code = "500",
|
||||
Message = $"任务执行失败: {ex.Message}"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据几何类型返回对应的 ID(用于兼容原逻辑)
|
||||
/// </summary>
|
||||
private static int GetIdForType(esriGeometryType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
esriGeometryType.esriGeometryPoint => 1,
|
||||
esriGeometryType.esriGeometryPolyline => 2,
|
||||
esriGeometryType.esriGeometryPolygon => 3,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,13 @@ public class McpServerList
|
||||
Description = "可以调用arcgis的地理处理工具或执行python代码等",
|
||||
IsActive = true
|
||||
});
|
||||
servers.Add("ArcGisProSymbology", new InnerMcpServer
|
||||
{
|
||||
Name = "ArcGisProSymbology",
|
||||
Type = "inner",
|
||||
Description = "可以调用arcgis的符号系统进行简单符号设置",
|
||||
IsActive = true
|
||||
});
|
||||
servers.Add("KnowledgeBase", new InnerMcpServer
|
||||
{
|
||||
Name = "KnowledgeBase",
|
||||
@ -37,18 +44,18 @@ public class McpServerList
|
||||
// "有地理信息的相关案例步骤参考以及Arcgis Pro的工具详细信息",
|
||||
IsActive = true
|
||||
});
|
||||
servers.Add("filesystem", new StdioMcpServer()
|
||||
{
|
||||
Name = "filesystem",
|
||||
Type = "stdio",
|
||||
Command = "npx",
|
||||
Args = new List<string>()
|
||||
{
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-filesystem",
|
||||
"F:\\secondsemester\\linktool\\test\\LinkTool0607\\LinkTool0607.gdb"
|
||||
}
|
||||
});
|
||||
//servers.Add("filesystem", new StdioMcpServer()
|
||||
//{
|
||||
// Name = "filesystem",
|
||||
// Type = "stdio",
|
||||
// Command = "npx",
|
||||
// Args = new List<string>()
|
||||
// {
|
||||
// "-y",
|
||||
// "@modelcontextprotocol/server-filesystem",
|
||||
// "F:\\secondsemester\\linktool\\test\\LinkTool0607\\LinkTool0607.gdb"
|
||||
// }
|
||||
//});
|
||||
// servers.Add("fetch", new StdioMcpServer()
|
||||
// {
|
||||
// Name = "fetch",
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="24"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Button Grid.Row="0" Content="Test Workflow" Name="TestServer" Click="TestWorkflow_OnClick"></Button>
|
||||
@ -43,5 +44,6 @@
|
||||
<Button Grid.Row="5" Content="Test Arcgis Tool" Name="TestArcGisTool" Click="TestArcGisTool_OnClick"></Button>
|
||||
<Button Grid.Row="6" Content="Test Resource" Name="TestResource" Click="TestResource_OnClick"></Button>
|
||||
<Button Grid.Row="7" Content="测试获取属性表" Name="TestAttrTable" Click="TestAttrTable_OnClick"></Button>
|
||||
<Button Grid.Row="8" Content="测试符号系统" Name="TestSymbology" Click="TestSymbology_Click"></Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -320,5 +320,12 @@ namespace LinkToolAddin.ui.dockpane
|
||||
"LandUse_2005_Copy", "30");
|
||||
log.Info("finish");
|
||||
}
|
||||
|
||||
private async void TestSymbology_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
//await ArcGisProSymbology.SetPointColor(115, 174, 82, "population_XYTableToPoint", 10);
|
||||
//await ArcGisProSymbology.SetLineColor(29,141,213,"testline",50);
|
||||
//await ArcGisProSymbology.SetPolygonColor(149, 2, 8, 255, 153, 0, 30, "county111_popul");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user