223 lines
8.4 KiB
C#
223 lines
8.4 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using ArcGIS.Core.Data;
|
||
using ArcGIS.Core.Data.Raster;
|
||
using ArcGIS.Core.Geometry;
|
||
using ArcGIS.Desktop.Core.Geoprocessing;
|
||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||
using LinkToolAddin.server;
|
||
using LinkToolAddin.ui.dockpane;
|
||
using log4net;
|
||
using ModelContextProtocol.Server;
|
||
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
|
||
namespace LinkToolAddin.client.tool;
|
||
|
||
public class ArcGisPro
|
||
{
|
||
private static ILog log = LogManager.GetLogger(typeof(ArcGisPro));
|
||
[McpServerTool, Description("可以通过调用ArcGIS Pro的地理处理工具实现一些数据处理功能,传入参数必须严格遵循ArcGIS Pro调用工具的标准调用名和参数要求知识库。")]
|
||
public static async Task<JsonRpcResultEntity> ArcGisProTool(string toolName, List<string> toolParams)
|
||
{
|
||
IGPResult results = await Geoprocessing.ExecuteToolAsync(toolName, toolParams,null,null,null,GPExecuteToolFlags.InheritGPOptions|GPExecuteToolFlags.GPThread);
|
||
JsonRpcResultEntity jsonRpcResultEntity;
|
||
if (results.IsFailed)
|
||
{
|
||
log.Error(results.ErrorMessages);
|
||
jsonRpcResultEntity = new JsonRpcErrorEntity()
|
||
{
|
||
Error = new Error()
|
||
{
|
||
Code = results.ErrorCode.ToString(),
|
||
Message = GetMessagesString(results.ErrorMessages)+"\n"+GetMessagesString(results.Messages)
|
||
}
|
||
};
|
||
}else if(results.HasWarnings)
|
||
{
|
||
log.Warn(results.Messages);
|
||
jsonRpcResultEntity = new JsonRpcSuccessEntity
|
||
{
|
||
Result = GetMessagesString(results.Messages)
|
||
};
|
||
}
|
||
else
|
||
{
|
||
log.Info("success gp tool");
|
||
jsonRpcResultEntity = new JsonRpcSuccessEntity
|
||
{
|
||
Result = GetMessagesString(results.Messages)
|
||
};
|
||
}
|
||
return jsonRpcResultEntity;
|
||
}
|
||
|
||
[McpServerTool, Description("查看指定数据的坐标系、范围、几何类型、是否有Z坐标和M坐标,获取字段列表等")]
|
||
public static async Task<JsonRpcResultEntity> DataProperty(string datasetPath,string dataName)
|
||
{
|
||
JsonRpcResultEntity result = new JsonRpcResultEntity();
|
||
await QueuedTask.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
using Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(datasetPath)));
|
||
FeatureClass featureClass = gdb.OpenDataset<FeatureClass>(dataName);
|
||
FeatureClassDefinition featureClassDefinition = featureClass.GetDefinition();
|
||
SpatialReference spatialReference = featureClassDefinition.GetSpatialReference();
|
||
GeometryType geometryType = featureClassDefinition.GetShapeType();
|
||
result = new JsonRpcSuccessEntity()
|
||
{
|
||
Id = 1,
|
||
Result = JsonConvert.SerializeObject(new Dictionary<string, object>()
|
||
{
|
||
{"spatialReference", spatialReference.Name+"(WKID:"+spatialReference.Wkid+")"},
|
||
{"dataName", dataName},
|
||
{"geometryType", geometryType.ToString()},
|
||
{"hasZValue", featureClassDefinition.HasZ()},
|
||
{"hasMValue", featureClassDefinition.HasM()},
|
||
{"fields",featureClassDefinition.GetFields()}
|
||
})
|
||
};
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result = new JsonRpcErrorEntity()
|
||
{
|
||
Error = new Error()
|
||
{
|
||
Message = ex.Message
|
||
},
|
||
Id = 1
|
||
};
|
||
return result;
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
|
||
[McpServerTool, Description("列出gdb数据库中的所有数据的名称")]
|
||
public static async Task<JsonRpcResultEntity> ListData(string gdbPath)
|
||
{
|
||
var datasets = new List<string>();
|
||
await QueuedTask.Run(() =>
|
||
{
|
||
using (Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(gdbPath))))
|
||
{
|
||
// 获取所有要素类(Feature Classes)
|
||
var featureClasses = gdb.GetDefinitions<FeatureClassDefinition>();
|
||
foreach (var fc in featureClasses)
|
||
datasets.Add($"要素类: {fc.GetName()}");
|
||
|
||
// 获取所有表格(Tables)
|
||
var tables = gdb.GetDefinitions<TableDefinition>();
|
||
foreach (var table in tables)
|
||
datasets.Add($"表格: {table.GetName()}");
|
||
|
||
// 获取所有要素数据集(Feature Datasets)
|
||
var featureDatasets = gdb.GetDefinitions<FeatureDatasetDefinition>();
|
||
foreach (var fd in featureDatasets)
|
||
datasets.Add($"要素数据集: {fd.GetName()}");
|
||
|
||
// 获取所有栅格数据集(Raster Datasets)
|
||
var rasterDatasets = gdb.GetDefinitions<RasterDatasetDefinition>();
|
||
foreach (var raster in rasterDatasets)
|
||
datasets.Add($"栅格数据: {raster.GetName()}");
|
||
}
|
||
});
|
||
JsonRpcResultEntity result = new JsonRpcSuccessEntity()
|
||
{
|
||
Id = 1,
|
||
Result = JsonConvert.SerializeObject(datasets)
|
||
};
|
||
return result;
|
||
}
|
||
|
||
[McpServerTool, Description("获取要素类的属性表内容,可以查看属性表中的至多前20条记录的内容")]
|
||
public static async Task<JsonRpcResultEntity> GetFeatureDatasetAttributeTable(string datasetPath, string dataName, string rowsLimit)
|
||
{
|
||
JsonRpcResultEntity result = new JsonRpcResultEntity();
|
||
await QueuedTask.Run(async () =>
|
||
{
|
||
try
|
||
{
|
||
using Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(datasetPath)));
|
||
FeatureClass featureClass = gdb.OpenDataset<FeatureClass>(dataName);
|
||
List<Dictionary<string, string>> attributeTable = await GetAttributeTableAsync(featureClass,Convert.ToInt32(rowsLimit));
|
||
result = new JsonRpcSuccessEntity()
|
||
{
|
||
Id = 1,
|
||
Result = JsonConvert.SerializeObject(attributeTable)
|
||
};
|
||
return result;
|
||
}catch (Exception ex)
|
||
{
|
||
result = new JsonRpcErrorEntity()
|
||
{
|
||
Error = new Error()
|
||
{
|
||
Message = ex.Message,
|
||
Code = "500"
|
||
}
|
||
};
|
||
return result;
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
|
||
private static async Task<List<Dictionary<string, string>>> GetAttributeTableAsync(FeatureClass featureClass,int limit = 5)
|
||
{
|
||
if (limit > 20)
|
||
limit = 20;
|
||
return await QueuedTask.Run(() =>
|
||
{
|
||
var result = new List<Dictionary<string, string>>();
|
||
|
||
using (var cursor = featureClass.Search())
|
||
{
|
||
int i = 0;
|
||
while (cursor.MoveNext())
|
||
{
|
||
i++;
|
||
if (i >= limit && limit != -1)
|
||
break;
|
||
var feature = cursor.Current as Feature;
|
||
if (feature == null)
|
||
continue;
|
||
|
||
var record = new Dictionary<string, string>();
|
||
|
||
foreach (var field in featureClass.GetDefinition().GetFields())
|
||
{
|
||
var value = feature[field.Name];
|
||
|
||
// 处理 DBNull 值
|
||
if (value is DBNull)
|
||
value = null;
|
||
|
||
record[field.Name] = value.ToString();
|
||
}
|
||
|
||
result.Add(record);
|
||
}
|
||
}
|
||
|
||
return result;
|
||
});
|
||
}
|
||
|
||
private static string GetMessagesString(IEnumerable<IGPMessage> messages)
|
||
{
|
||
StringBuilder messagesStr = new StringBuilder();
|
||
foreach (var gpMessage in messages)
|
||
{
|
||
messagesStr.AppendLine(gpMessage.Text);
|
||
}
|
||
return messagesStr.ToString();
|
||
}
|
||
} |