ArcObjectsSDKNet

创建日期:2024-06-21
更新日期:2025-01-20

重要:ArcGIS开发需要安装ArcGIS Engine DevelopKit 10和ArcObjects SDK for the Microsoft .NET Framework。不需要安装ArcGIS Desktop和ArcGIS Server,可以直接连接服务器上的ArcSDE。

不需要安装,.NET项目运行后,会自动加载到C:\Windows\assembly目录下。使用下列名称可以将该目录下面的dll文件拷贝出来。

xcopy C:\Windows\assembly\GAC_32 d:\dll /e /c
xcopy C:\Windows\assembly\GAC_MSIL d:\dll /e /c

开发示例

AddInEditorExtension

此示例演示如何使用加载项创建自定义编辑器扩展。

AddInExtensionPersist

在 ArcGIS Desktop 应用程序中的保存和打开事件期间,扩展参与文档持久性。 此示例展示了如何通过使用插件实现扩展来将数据保存在文档中。

AddInTimeSeriesGraph

时间序列图工具根据不同的时间值从点要素图层构建折线图。 该层包含一组七个量具的多个测量值。 每个测量都有自己的流量值、日期和时间,以及与之关联的量具 ID 属性。

当您使用时间序列图工具单击特征点(计量站)时,该工具会识别该点并查找计量 ID。 从此量具 ID 的所有测量值都用于基于图形模板制作图形。 如果现有打开的图形窗口,该工具会在此窗口中创建图形系列。 如果没有打开的图形窗口,该工具会在新的图形窗口中创建图形系列。

AlgorithmicColorRamp

此示例演示了一种用于生成用户指定的 AlgorithmicColorRamp 的工具,该工具用于为要素图层上的 ClassBreaksRenderer 上的符号着色。

AngleAngleConstructor

此示例演示如何创建形状构造函数。 角度-角度形状构造函数根据两个点位置和两个角度的输入向编辑草图添加点。 基于这些输入构建一个角交点。 如果未计算新点,则会出现一个消息对话框来指示这一点。

AnimationLayerEffects

此示例展示了如何在 ArcGIS Desktop 中创建自定义动画并为 ArcMap 实现图层效果动画类型。 它允许您通过图层亮度和对比度进行动画处理。 此动画仅适用于支持对比度和亮度作为图层属性的栅格图层。 如示例代码所示,要在 ArcMap、ArcScene 或 ArcGlobe 中创建自定义动画类型,请实现新的关键帧类和新的动画类型类。 在 ESRI Map Animation Types 组件类别(或 ArcScene 的 ESRI 3D 动画类型和 Globe 或 ArcGlobe 的 ESRI 3D 动画类型)中注册动画类型类。

AnimationMoveGraphicAlongPath

此示例实现了 ArcMap 动画的沿路径移动对象功能。 它允许您沿选定的线要素或选定的线图形移动点图形元素或文本元素。 实现了一种新的动画类型(地图图形动画类型)及其对应的关键帧(地图图形关键帧),以支持沿路径移动图形。 它还实现了用于创建移动对象沿路径动画的 ArcMap 命令。 此示例的目的是展示如何在 ArcMap 中创建自定义动画类型以及如何实施 ArcMap 命令来导入动画轨迹。 要创建自定义动画类型,请实现一个新的关键帧类和一个新的动画类型类。

ApplyOffsetToATimeAwareLayer

此示例演示如何将偏移量应用于时间感知层。

ARControlAttributeQuery

此示例说明如何在已加载到 ReaderControl 的已发布地图文件 (PMF) 中查询图层的字段属性值。

ARControlDocumentProperties

此示例演示如何使用 IARControl.ShowARWindow 方法在使用“浏览”对话框选择要加载到控件中的文档时显示 FileProperties 模式窗口。 通过右键单击内容列表 (TOC) 中的地图或图层以显示上下文菜单并选择属性来显示 DataFrame 和图层属性模式窗口。 IARControl.TOCVisible 属性用于切换 TOC 的可见性,如果加载的文档是在有权限发布的情况下进行的。

当 TOC 不可见时,无法手动显示 DataFrame 和 Layer 属性。 相反,IARPageLayout.ARMap 属性用于迭代每个地图并获取其 Description、DistanceUnits、Name 和 SpatialReferenceName 属性。 IARMap.ARLayer 属性用于迭代地图中的每个图层并获取其描述、名称、MaximumScale 和 MinimumScale 属性。 这些属性连接成一个字符串,显示在 RichTextBox 中。

分析功能

1、Find Common Ancestors: 公共祖先追踪分析

添加两个标记,找到共同祖先。(从源开始公共的所有元素)

2、Find Connected: 网络连接要素分析

添加一个标记,找到所有连接的要素。

3、Find Loops: 网络环路分析

添加一个标记,找到所有环路。

4、Find Disconnected: 网络中断要素分析

添加一个标记,找到所有不相连的要素。

5、Find Path Upstream: 网络上溯路径分析

添加一个标记,找到源到标记的所有要素。

6、Find Path: 网络路径分析

添加两个标记,找到两个标记连通路径的所有要素,并返回总成本。

7、Trace Downstream: 网络下溯追踪

添加一个标记,找到标记到汇的所有要素。

8、Find Upstream Accumulation: 网络上溯累计追踪

添加一个标记,找到源到标记所有元素,并返回总成本。

9、Trace Upstream: 网络上溯追踪

添加一个标记,找到源到标记的所有要素。

开发指南

1、检查授权。

ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);

 var licenses = new Dictionary<esriLicenseProductCode, string>
 {
     // 注意下面两行顺序不能颠倒,否则报错:
     // System.Runtime.InteropServices.COMException:“No edit session is in progress”
     { esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB, "ArcEngine GDB" },
     { esriLicenseProductCode.esriLicenseProductCodeEngine, "ArcEngine" }
 };

 foreach (var license in licenses)
 {
     var productCode = license.Key;
     var licenseName = license.Value;
     var aoi = new AoInitializeClass();

     if (aoi.IsProductCodeAvailable(productCode) == esriLicenseStatus.esriLicenseAvailable)
     {
         Console.WriteLine($"{licenseName}许可可用");
         if (aoi.Initialize(productCode) == esriLicenseStatus.esriLicenseCheckedOut)
         {
             Console.WriteLine($"{licenseName}许可已签出");
         }
     }
     else
     {
         Console.WriteLine($"{licenseName}许可不可用");
     }
 }

2、打开工作空间枚举所有数据集。

 IPropertySet property = new PropertySetClass();
 property.SetProperty("SERVER", "192.168.23.111");
 property.SetProperty("INSTANCE", "5151");
 property.SetProperty("USER", "sde");
 property.SetProperty("PASSWORD", "hylab");
 property.SetProperty("DATABASE", "sde");
 property.SetProperty("VERSION", "sde.DEFAULT");

 IWorkspaceFactory2 factory = new SdeWorkspaceFactoryClass();
 IWorkspace workspace = factory.Open(property, 0);

 if (workspace != null)
 {
     Console.WriteLine("打开工作空间成功");
     var datasets = workspace.Datasets[esriDatasetType.esriDTFeatureDataset];

     IDataset dataset;
     while ((dataset = datasets.Next()) != null)
     {
         Console.WriteLine($"数据集:${dataset.Name}");
     }
 }
 else
 {
     Console.WriteLine("打开工作空间失败");
 }

3、打开数据集并获取所有图层。

 IWorkspace workspace = OpenWorkspace();

 IFeatureDataset dataset = (workspace as IFeatureWorkspace).OpenFeatureDataset("SDE.LTRQ");

 IFeatureClassContainer container = dataset as IFeatureClassContainer;

 for (int i = 0; i < container.ClassCount; i++)
 {
     IFeatureClass cls = container.Class[i];
     IDataset ds = cls as IDataset;
     if (ds != null && !string.IsNullOrEmpty(ds.Name))
     {
         IFeatureLayer layer = new FeatureLayerClass
         {
             Name = (cls as IDataset).Name,
             FeatureClass = cls
         };

         Console.WriteLine($"图层:{layer.Name}");
     }
 }

4、根据OBJECTID查询要素并显示要素属性。

 IQueryFilter filter = new QueryFilterClass();
 filter.WhereClause = "OBJECTID=672"; // 支持 =, <>, >, <, >=, <=, IN, LIKE, UPPER, LOWER, and, or, 跟查Oracle一样

 IFeatureCursor cursor = layer.Search(filter, false);
 IFeature feature;

 while ((feature = cursor.NextFeature()) != null)
 {
     for (int i = 0; i < feature.Fields.FieldCount; i++)
     {
         IField field = feature.Fields.Field[i];
         object value = feature.Value[i];
         Console.WriteLine($"{field.Name},{field.AliasName},{value}");
     }
 }

 Marshal.ReleaseComObject(cursor);

5、获取几何网络,显示边数和节点数,枚举简单边类和简单节点类。

INetworkCollection networks = layer.FeatureClass.FeatureDataset as INetworkCollection;

for (int i = 0; i < networks.GeometricNetworkCount; i++)
{
    IGeometricNetwork gn = networks.get_GeometricNetwork(i);
    IFeatureClassContainer container = gn as IFeatureClassContainer;

    if (container.ClassByID[layer.FeatureClass.ObjectClassID] != null)
    {
        Console.WriteLine($"边数:{gn.Network.EdgeCount} 节点数:{gn.Network.JunctionCount}");

        // 枚举边
        IEnumFeatureClass list = gn.ClassesByType[esriFeatureType.esriFTSimpleEdge];
        IFeatureClass cls;

        while ((cls = list.Next()) != null)
        {
            Console.WriteLine($"简单边类:{cls.AliasName}");
        }

        // 枚举节点
        list = gn.ClassesByType[esriFeatureType.esriFTSimpleJunction];

        while ((cls = list.Next()) != null)
        {
            Console.WriteLine($"简单节点类:{cls.AliasName}");
        }
    }
}

6、根据位置查询几何网络中的边。

IPoint point = new PointClass
{
    X = 19246.370,
    Y = 83994.007
};

// 1、创建地图
IMap map = new MapClass();
map.AddLayer(layer); // IFeatureLayer

// 2、查询离点最近的边
IPointToEID eid = new PointToEIDClass
{
    SourceMap = map,
    GeometricNetwork = network,
    SnapTolerance = 5 // 查找范围,5个地图单位
};

int nearestEdgeEID;
IPoint location;
double percent;

eid.GetNearestEdge(point, out nearestEdgeEID, out location, out percent);

if (location != null)
{
    Console.WriteLine($"最近边EID:{nearestEdgeEID}");
    Console.WriteLine($"位置:{location.X}, {location.Y}");
    Console.WriteLine($"比例:{percent}");
}
else
{
    Console.WriteLine("未找到离点最近的边");
}

7、根据几何网络中的边获取要素类和OBJECTID。

int userClassID, userID, userSubID;

INetElements elements = (INetElements)network.Network;
elements.QueryIDs(nearestEdgeEID, esriElementType.esriETEdge, out userClassID, out userID, out userSubID);

if (userClassID > 0)
{
    IFeatureClassContainer container = dataset as IFeatureClassContainer;
    IFeatureClass cls = container.ClassByID[userClassID];
    Console.WriteLine($"ClassID: {userClassID} AliasName: {cls.AliasName} OBJECTID: {userID}");
}

8、从一个边开始遍历连通的要素。

// 1、启用编辑
IWorkspaceEdit2 edit = workspace as IWorkspaceEdit2;

if (!edit.IsBeingEdited())
{
    edit.StartEditing(true);
}

if (!edit.IsInEditOperation)
{
    edit.StartEditOperation();
}

IVersionedObject versioned = layer.FeatureClass as IVersionedObject;

if (versioned == null || !versioned.IsRegisteredAsVersioned)
{
    Console.WriteLine($"不支持开启无版本编辑:{layer.Name}");
    return;
}

// 2、创建流向跟踪解决方案
ITraceFlowSolverGEN solver = new TraceFlowSolverClass
{
    TraceIndeterminateFlow = true // true:搜索所有流向,false:只搜索确定流向
};

((INetSolver)solver).SourceNetwork = network.Network;

// 3、设置起始边
IEdgeFlag flag = new EdgeFlagClass();
((INetFlag)flag).UserClassID = layer.FeatureClass.FeatureClassID;
((INetFlag)flag).UserID = feature.OID;

((INetFlag)flag).UserSubID = 0;

IEdgeFlag[] flags = new EdgeFlagClass[1];

flags[0] = flag;

solver.PutEdgeOrigins(ref flags);

// 4、建立流动网络
if (!network.ValidFlowDirection)
{
    network.EstablishFlowDirection();
}

// 5、查找连通要素
IEnumNetEID junctionEIDs, edgeEIDs;
solver.FindFlowElements(
    esriFlowMethod.esriFMConnected,
    esriFlowElements.esriFEJunctionsAndEdges,
    out junctionEIDs,
    out edgeEIDs
   );

IEIDHelper helper = new EIDHelperClass
{
    GeometricNetwork = network,
    ReturnFeatures = true,
    ReturnGeometries = true
};

IEnumEIDInfo infos = helper.CreateEnumEIDInfo(edgeEIDs);

IEIDInfo info = infos.Next();

while (info != null)
{
    Console.WriteLine($"OBJECTID: {info.Feature.OID}");
    info = infos.Next();
}

// 6、停止编辑
edit.StopEditOperation();
edit.StopEditing(true);

9、空间范围查询。

IEnvelope envelope = new EnvelopeClass();
envelope.PutCoords(32087.494, 68942.316, 32489.132, 69434.442);

ISpatialFilter filter = new SpatialFilterClass
{
    Geometry = envelope,
    GeometryField = layer.FeatureClass.ShapeFieldName,
    SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects
};

filter.SubFields = "*";

using (ComReleaser comReleaser = new ComReleaser())
{
    IFeatureCursor cursor = layer.FeatureClass.Search(filter, true);
    comReleaser.ManageLifetime(cursor);

    IFeature feature = null;

    while ((feature = cursor.NextFeature()) != null)
    {
        Console.WriteLine("OBJECTID: {0}", feature.OID);
    }
}