ArcGIS Pro中的映射功能通过ArcGIS.Desktop.Mapping提供。ArcGIS.Desktop.Mapping命名空间为编写映射提供类和成员。这包括创建地图、在ArcGIS Online中打开网络地图、向地图添加图层等内容、创建和编辑符号、为图层指定渲染器,以及支持地图注释和动态标记。ArcGIS.Desktop.Mapping命名空间还提供了在ArcGIS Pro项目中管理样式和样式项的能力。
Map类是ArcGIS Pro中用于组织地理数据的主要对象。它是图层和独立表格的容器。Map对象具有在地图中的所有图层上操作的特性,例如空间参照、地图比例等,以及操作地图图层和独立表格的方法。Map对象的典型任务包括添加新图层、设置基础地图、更改空间参考、获取当前选定的要素和元素以及管理时空书签。
在应用程序中,现有地图在“目录”窗格中显示为单个项目项或打开的视图。地图视图与单个地图关联。一张地图可以有多个视图。对于项目,一次只能有一个视图处于活动状态。活动视图可以是地图视图,也可以不是地图视图。
由于应用程序的异步特性,无法使用其构造函数创建Map对象;事实上,Map类没有公共构造函数。使用MapFactory.Instance.CreateMap方法创建新创建的映射并将其添加到当前项目中。
// create a new map with an ArcGIS Online basemap
QueuedTask.Run(( )=>
{
Map map = MapFactory.Instance.CreateMap(
"World Map", ArcGIS.Core.CIM.MapType.Map, ArcGIS.Core.CIM.MapViewingMode.Map, Basemap.Streets);
...
}
在MapFactory.Instance.CreateMap()结束时,地图已创建并添加到“目录”窗口中的“地图”文件夹集合中,但地图尚未打开。要打开地图,请使用FrameworkApplication.Panes.CreateMapPaneAsync(map)创建MapView以承载地图。地图视图窗格将打开并显示其关联的地图。TOC将填充地图内容。
// create and open a new map
Map world_map = await QueuedTask.Run(() =>
{
// create a new map with an ArcGIS Online basemap
Map map = MapFactory.Instance.CreateMap(
"World Map", ArcGIS.Core.CIM.MapType.Map, ArcGIS.Core.CIM.MapViewingMode.Map, Basemap.Streets);
return map;
});
//should be called on the UI
await ProApp.Panes.CreateMapPaneAsync(world_map);
应在UI线程上调用CreateMapPaneAsync。
要检索存储在项目中的地图(并将其打开),请使用project.Current.GetItems(),其中“T”是MapProjectItem类型。使用LINQ将返回的集合筛选为您正在查找的地图项。接下来,调用mapProjectItem.GetMap()来检索地图并加载它。一旦检索到映射,就可以将其传递给FrameworkApplication.Panes.CreateMapPaneAsync以打开地图。
// open an existing map
var mapProjectItems = Project.Current.GetItems();
var mapProjectItem = mapProjectItems.FirstOrDefault(mpi => mpi.Name.Equals("World Map"));
await QueuedTask.Run(async () =>
{
Map map = mapProjectItem.GetMap();
await ProApp.Panes.CreateMapPaneAsync(map);
});
一旦地图打开并且地图视图是活动视图,插件就可以通过MapView使用应用程序上下文。Active静态属性获取当前活动地图视图的句柄(如果没有活动地图视图,则为null)和MapView.Active.Map以访问地图:
// access the currently active map
Map map = MapView.Active.Map;
// set or change the basemap layer of the active map
QueuedTask.Run(() =>
{
Map map = MapView.Active.Map;
map.SetBasemapLayers(Basemap.Gray);
});
底图是一个不可编辑的图层,它在地图中提供背景或参考信息。它通常被设计为为其他层提供视觉参考,以帮助确定地图用户的方向。ArcGIS Online中的航空图像、地形和街道是可以添加到地图中的基础地图图层的示例。此外,您可以通过创建basemap类型的地图并将其创作为常规地图,为项目创建自定义basemap图层。地图将显示在功能区的基础地图图层库中,以及具有不同图标的“目录”窗格中。
// create custom basemap in your current project
Map map = await QueuedTask.Run(() =>
{
Map basemap = MapFactory.Instance.CreateLocalBasemap("My basemap");
// create and add layer to the basemap using LayerFactory.Instance
string url = @"c:\temp\roads.shp";
Uri uri = new Uri(url);
Layer lyr = LayerFactory.Instance.CreateLayer(uri, basemap);
return basemap;
});
ArcGIS Pro支持与ArcGIS Online或您的组织门户无缝集成。您可以在项目中添加并打开现有web地图,将现有门户层项目添加到地图,或将项目中的地图发布为web地图,以便在组织内或与更广泛的受众共享。
Map实现了ArcGIS.Desktop.Core.IMetadataInfo提供对其元数据*的读写访问。地图元数据与地图一起保存在.aprx中。从地图中检索的元数据将采用xml格式,并将根据当前使用的元数据样式进行样式设置。外接程序负责确保在编辑元数据时满足与当前元数据样式相关联的规则。
//Supports access and update of metadata
public interface IMetadataInfo
{
// Returns true if the metadata can be edited otherwise false
bool GetCanEditMetadata();
// Returns the xml formatted metadata
string GetMetadata();
// Set the metadata xml. The requirements of the current style
//should be met
void SetMetadata(string metadataXml);
}
在本例中,如果地图元数据是可编辑的,则检索并“设置”地图元数据,而不进行任何更改。要使地图元数据可编辑,至少必须具有项目访问权限。
var map = MapView.Active.Map; //Assume null check...
QueuedTask.Run(() => {
//read the map metadata and set it back if the metadata
//is editable
var map_xml = map.GetMetadata();
if (map.GetCanEditMetadata())
map.SetMetadata(map_xml);
});
元数据访问也可从ArcGIS.Desktop.Maping.MapProjectItem获得
Pro中包含支持同步的功能服务内容的地图可以“脱机”。脱机内容是指即使在没有网络连接的情况下也可以在地图中访问的内容。使地图脱机需要生成要素服务内容的本地副本(或副本),并可选地将任何相关光栅和/或矢量平铺缓存内容导出到本地计算机。
一旦在本地计算机上,就可以编辑离线功能服务内容并与服务同步。通过API进行的同步目前仅限于双向同步,这意味着客户端上的任何挂起的更改(自上次同步以来保存的编辑)都会推送到服务,而服务上的任何未决更改(与其他子副本的父副本同步的任何编辑和/或更改)都会在API中的单个同步调用中拉送到客户端。API生成的基础副本是双向副本。当编辑完成或要丢弃客户端副本时,可以在服务上注销副本。API中用于创建、同步和删除副本以及导出平铺缓存内容的相关操作通过ArcGIS.Desktop.Maping.Offline命名空间中的GenerateOfflineMap和相关类公开。
有关等效Pro UI功能的文档,请参阅离线地图。ArcGIS Server文档中的脱机地图和分支版本数据的附加工作也可能会有所帮助。地图脱机时创建的本地副本的属性也可以通过Pro UI副本管理功能查看。
使地图内容脱机包括:
API提供了三种方法来确定地图是否有可脱机的内容:
导出平铺缓存的质量/细节通过传递到“导出”的ExportTileCacheParams上设置的MaximumUserDefinedScale属性来控制。将MaximumUserDefinedScale与给定光栅或矢量平铺服务的相应详细级别LOD进行比较,以确定将导出哪个LOD(在指定范围内)。选定的LOD将是包含指定比例的最大(最粗)LOD。要获取与光栅和/或矢量平铺缓存内容的可用LOD相关的可用比例列表,加载项可以分别调用GetExportRasterTileCacheScales(映射,范围)和GetExportVectorTileCaacheScales(贴图,范围)。MaximumUserDefinedScale应从列表中的一个刻度中选择。给定列表中的第一个比例表示可用的最详细的LOD,列表中的最后一个比例表示最粗略或最不详细的可用LOD。
但是,LOD随着MaximumUserDefinedScale值的减少而增加,平铺的数量(覆盖要导出的区域)也会增加。如果导出的磁贴的组合大小超过1或2 GB(如果网络速度差,则小于1或2),则导出可能需要几分钟。应相应设置MaximumUserDefinedScale和导出范围参数。注:用于确定比例尺列表的范围应与用于导出的范围相同。
GenerateReplicaParams和ExportTileCacheParams类都包含DestinationFolder属性,该属性用于确定副本和/或导出的磁贴包将复制到的输出位置。如果该属性为空,则目标文件夹默认为为当前项目指定的当前脱机地图位置。通常,这是当前项目文件夹。指定不存在的文件夹将引发ArgumentException。
下面的代码示例演示了如何使地图内容脱机:
var extent = MapView.Active.Extent;
var map = MapView.Active.Map;
await QueuedTask.Run(() =>
{
//Check map for sync-enabled content
var canGenReplicas = GenerateOfflineMap.Instance.GetCanGenerateReplicas(map);
if (canGenReplicas)
{
//Calling GenerateReplicas on a map with no sync-enabled content throws
//an InvalidOperationException.
GenerateOfflineMap.Instance.GenerateReplicas(map, new GenerateReplicaParams()
{
//The area to be exported
Extent = extent,//clip extent - must be in the same SR as the map
//Note: DestinationFolder is _not_ set in this case. Therefore it will default
//to the current offline maps location set in the project properties UI. If
//none is set, it defaults to the current project folder
});
}
//Check for raster tile cache content
var canExport = GenerateOfflineMap.Instance.GetCanExportRasterTileCache(map);
if (canExport)
{
//Get a list of available scales. Calling this method on a map with no raster
//tile cache content returns an empty list
var scales = GenerateOfflineMap.Instance.GetExportRasterTileCacheScales(map, extent);
var max_scale = scales[scales.Count() - 1];//pick a scale - in this case the coarsest
//so the fastest but least detail
//Export the raster tile caches in the map. Calling ExportRasterTileCache on a map
//with no raster tile cache content will throw an InvalidOperationException
GenerateOfflineMap.Instance.ExportRasterTileCache(map, new ExportTileCacheParams()
{
Extent = extent,//clip extent - must be in the same SR as the map
MaximumUserDefinedScale = max_scale, //Controls the exported LOD
//(and, hence, download performance)
DestinationFolder = @"C:/Data/Exports" //target folder - must exist
});
}
//Check for vector tile cache content
canExport = GenerateOfflineMap.Instance.GetCanExportVectorTileCache(map);
if (canExport)
{
//Get a list of available scales. Calling this method on a map with no vector
//tile cache content returns an empty list
var scales = GenerateOfflineMap.Instance.GetExportVectorTileCacheScales(map, extent);
var max_scale = scales[scales.Count() - 1];//pick a scale - in this case the coarsest
//Export the vector tile caches in the map. Calling ExportVectorTileCache on a map
//with no vector tile cache content will throw an InvalidOperationException
GenerateOfflineMap.Instance.ExportVectorTileCache(map, new ExportTileCacheParams()
{
Extent = extent,//clip extent - must be in the same SR as the map
MaximumUserDefinedScale = max_scale,
DestinationFolder = @"C:/Data/Exports"
});
}
});
地图内容脱机后,本地副本内容可以与功能服务上的父副本同步。由于通过GenerateReplicas创建的本地副本是双向副本,因此可以多次同步子(本地)副本和父(服务)副本之间的数据更改。在同步调用期间,仅应用自上次同步以来所做的更改。注意:客户端上任何未保存的编辑都不会同步。
同步将所有(保存的)挂起的更改从子级推送到父级,并将所有挂起的修改从父级推送到子级。从父级中提取的更改不会参与编辑会话。它们直接写入子副本,并且不可执行。因此,加载项应在执行同步之前保存或放弃所有挂起的编辑。
加载项可以通过GenerateOfflineMap.Instance.GetCanSynchronizeReplicas(map)检查地图中是否有任何本地可同步内容,并使用GenerateOfflineMap.Instance.SynchronizeReplicass(map)执行双向同步。
var map = MapView.Active.Map;
//Save or discard any edits first!
await Project.Current.DiscardEditsAsync();
//await Project.Current.SaveEditsAsync();
await QueuedTask.Run(() => {
var canSync = GenerateOfflineMap.Instance.GetCanSynchronizeReplicas(map);
if (canSync) {
//Do a bi-directional sync. If the local replicas were unregistered, this is
//a no-op
GenerateOfflineMap.Instance.SynchronizeReplicas(map);
}
});
GetCanSynchronizeReplicas仅检测是否有任何地图内容源于本地副本。它不会检测到挂起的更改。它不会确定是否由于某种原因在服务器上注销了本地副本。对以前未注册的副本内容调用SynchronizeReplicas会导致no-op。
要从映射中删除本地副本(以及项目中相应的数据库项),加载项调用GenerateOfflineMap.Instance.RemoveReplicas(map)。Remove replicas会注销服务上源于地图中的内容的任何本地副本,并从项目中删除相应的数据库项。针对本地复制副本内容的层将重新来源,以指向相关的功能服务内容。加载项可以调用GenerateOfflineMap.Instance.GetCanRemoveReplicas(map)以确定映射中是否存在可删除的可同步内容。
在执行RemoveReplicas时,本地副本中保存的任何挂起的更改将不会与父副本同步。要同步任何挂起的更改,加载项应保存(或放弃)任何未保存的编辑,并首先调用SynchronizeReplicas。
var map = MapView.Active.Map;
//Save any outstanding edits and call sync to
//sync pending changes _before_ calling RemoveReplicas
//if addins want local changes sync'd with the parent _first_.
await Project.Current.SaveEditsAsync();
await QueuedTask.Run(() => {
var canRemove = GenerateOfflineMap.Instance.GetCanRemoveReplicas(map);
if (canRemove) {
//Sync first as needed...at the discretion of the addin
//GenerateOfflineMap.Instance.SynchronizeReplicas(map);
//unregister on the service and remove associated database items from
//the project. Re-source relevant local feature layers to point back
//to the service content.
GenerateOfflineMap.Instance.RemoveReplicas(map);
}
});
GetCanRemoveReplicas不会检测映射中存在的本地同步副本是否已注销。对以前未注册的副本内容调用RemoveReplicas会导致no-op。
MapMember是一个抽象类,表示映射中包含的项。它包含图层和独立表共享的常用方法和特性。Layer和StandaloneTable类继承自MapMember类。要获取地图中可用图层和独立表格的列表,请使用Map.Layers 和Map.StandaloneTables属性。
要查找现有MapMember(如图层或独立表),请分别从地图中使用FindLayer或FindStandaloneTable方法。这些方法允许您按唯一的层或表URI进行搜索。还有一个“FindLayers”和“FindStandaloneTables”方法可以按名称查找图层或独立表。由于地图支持图层和独立表的嵌套分组,因此使用GetLayersAsFlattenedList和GetStandaloneTablesAsFlatenedList方法从地图中递归获取图层和独立表格。GroupLayer和CompositeLayer类提供了类似的方法来在该上下文中查找层和独立表。
这些函数不支持部分搜索,但可以通过使用.NET lambda表达式来实现。还可以使用OfType构造将返回列表限制为指定类型的层。下面是一些例子。
//find all layers from the active map that contain 'world' in their name
Map map = MapView.Active.Map;
IEnumerable layers = map.GetLayersAsFlattenedList().Where(l => l.Name.Contains("world"));
// find the layer with the specified Uri from the map
Layer layer = map.FindLayer(layerURI);
// find the standalone table with the specified name from the map
StandaloneTable table = map.FindStandaloneTables(tableName);
// find the first group layer in the map
GroupLayer groupLayer = map.GetLayersAsFlattenedList().OfType().FirstOrDefault();
// find the layers and standalone tables from the group Layer
var layers = groupLayer.Layers;
var tables = groupLayer.StandaloneTables;
// find all layers standalone tables from a group layer (recursively)
var layers = groupLayers.GetLayersAsFlattenedList();
var tables = groupLayer.GetStandaloneTablesAsFlattenedList();
要在TOC中高亮显示(选择)图层或表格,需要使用MapView类,而不是Map。
MapView mapView = MapView.Active;
IReadOnlyList selectedLayers = mapView.GetSelectedLayers();
IReadOnlyList selectedTables = mapView.GetSelectedStandaloneTables();
层和独立表实现ArcGIS.Desktop.Core.IMetadataInfo提供对其元数据的读写访问。
默认情况下,通过向地图引用添加数据源创建的新地图图层和表将使用与基础数据源关联的元数据。例如,将新要素图层添加到地图时,默认情况下,要素图层将使用要素类元数据。层和表元数据可以通过IMetadataSource接口在它们自己的(独立的)完整元数据和(依赖的)数据源元数据之间切换。从源访问的MapMember元数据是只读的,并且是MapMember.GetCanEditMetadata()将返回false。
MapMember元数据与map成员一起保存在.aprx中。元数据将采用xml格式,并将根据当前使用的元数据样式进行样式设置。外接程序负责确保在编辑元数据时满足与当前元数据样式相关联的规则。
//Supports access and update of metadata
public interface IMetadataInfo {
// Returns true if the metadata can be edited otherwise false
bool GetCanEditMetadata();
// Returns the xml formatted metadata
string GetMetadata();
//Set the metadata xml. The requirements of the current style
//should be met
void SetMetadata(string metadataXml);
}
//Indicates if metadata can be retrieved from a source other than itself
public interface IMetadataSource {
//Gets whether an underlying source is being used for metadata
bool GetUseSourceMetadata();
// Set to true to use the underlying source object's metadata
void SetUseSourceMetadata(bool useSource);
}
在此示例中,图层元数据设置为独立于其源。
//var layer = ...;
//Must be on the QueuedTask.Run()
//Is this layer using source metadata?
if (layer.GetUseSourceMetadata())
//Set the metadata to be independent of the underlying layer source
layer.SetUseSourceMetadata(false);
在此示例中,如果图层元数据是可编辑的,则检索并“设置”图层的元数据,而不进行任何更改。至少,要使层(和表)元数据可编辑,请使用mapMember.GetUseSourceMetadata()必须为false,并且项目访问权限必须为读/写。
//var layer = ...;
QueuedTask.Run(() => {
//read the layer metadata and set it back if the metadata
//is editable
var layer_xml = layer.GetMetadata();
if (layer.GetCanEditMetadata())
layer.SetMetadata(layer_xml);
});
_Sub_layers 不支持元数据。检查map.SupportsMetadata属性为true|false,具体取决于是否支持元数据。子层包括:AnnotationSubLayer、ServiceCompositeSubLayer、ServiceSubLayer和WMSSubLayer。尝试从子层访问元数据(SupportsMetadata为false)将引发NotSupportedException。
图层在地图上显示地理信息。层不存储实际地理数据;相反,它引用包含在形状文件、地理数据库、图像等中的数据,然后定义如何显示这些地理数据。最常见的情况是,图层引用数据库中的单个形状文件、表或视图。有时,图层的源是由两个或多个表组成的连接表。
某些图层不引用地理数据。例如,GroupLayer引用其他层,AnnotationLayer存储文本或图形元素。
每种类型的图层对象表示不同类型的数据。图层对象的示例包括:
//create a layer from a shapefile
string uriShp = @"\\Machine\SharedFolder\Census.shp";
Layer lyr = LayerFactory.Instance.CreateLayer(new Uri(uriShp), map);
//create a layer from a feature class off an sde
string uriSde = @"c:\MyDataConnections\MySDE.sde\Census";
Layer lyr = LayerFactory.Instance.CreateLayer(new Uri(uriSde), map);
//create a layer using a URL
string url = @"http://sampleserver6.arcgisonline.com/arcgis/rest/services/NapervilleShelters/FeatureServer/0";
Layer lyr = LayerFactory.Instance.CreateLayer(new Uri(url), map);
// create a layer and add it to a groupLayer
string urlLyrx = @"\\Machine\SharedFolder\Census.lyrx";
Layer lyr = LayerFactory.Instance.CreateLayer(new Uri(urlLyrx), grpLayer);
但是,创建图层时可能需要更多的控制,以便在将图层添加到地图之前设置某些属性。例如,您可能希望将图层添加到地图中,但默认情况下该图层不可见
LayerCreationParams类是为此目的创建的,可以与LayerFactory.Instance.CreateLayer(LayerCreationParams, ILayerContainerEdit)一起使用。
有许多类型的LayerCreationParam,每种类型都具有特定于该层类型的属性。例如,FeatureLayerCreationParams允许您在添加层之前设置DefinitionQuery和Renderer。
下面是此特定CreateLayer调用的一些示例。请注意,在调用中使用的Template与LayerCreationParams类的特定后代的使用相匹配。
// create a layer from a uri
// set the name and visibility
var uri = new Uri(@"c:\MyDataConnections\MySDE.sde\LANDUSE_polygon");
var createParams = new LayerCreationParams(uri)
{
Name = "Landuse",
IsVisible = false,
};
Layer layer = LayerFactory.Instance.CreateLayer(createParams, MapView.Active.Map);
// create a layer from a feature class
// use the FeatureLayerCreationParams since I want to
// set name, visibility and definition query
var featureCreateParams = new FeatureLayerCreationParams(featureClass)
{
Name = "Cities",
IsVisible = false,
DefinitionQuery = new DefinitionQuery("My Query", "ObjectID > 3"),
};
// use the FeatureLayer template to match the FeatureLayerCreationParams
FeatureLayer featurelayer =
LayerFactory.Instance.CreateLayer(featureCreateParams, MapView.Active.Map);
// create a group layer - use GroupLayerCreationParams
// set the name and scale
var groupCreateParams = new GroupLayerCreationParams()
{
Name="GroupLayer",
MinimumScale = 1000,
MaximumScale = 1000000,
};
// use GroupLayer to match GroupLayerCreationParams
GroupLayer grouplayer =
LayerFactory.Instance.CreateLayer(groupCreateParams, MapView.Active.Map);
// create a graphics layer
// set the name
var graphicscreateParams = new GraphicsLayerCreationParams()
{
Name = "My Graphics Layer",
};
GraphicsLayer graphicsLayer =
LayerFactory.Instance.CreateLayer(graphicscreateParams, MapView.Active.Map);
注意,您也可以使用Layerfactory.Instance.CreateGroupLayer创建组层。
地图注释可以添加到地图中。地图注释作为图层样板包的集合提供。可以使用LayerCreationParams将这些地图注释中的每一个作为“项目”对象添加到地图中。
//Gets the collection of layer template packages installed with Pro for use with maps
var items = MapView.Active.Map.LayerTemplatePackages;
//Iterate through the collection of items to add each Map Note to the active map
foreach (var item in items)
{
//Create a parameter item for the map note
var layer_params = new LayerCreationParams(item);
layer_params.IsVisible = false;
await QueuedTask.Run(() => {
//Create a feature layer for the map note
var layer = LayerFactory.Instance.CreateLayer(layer_params, MapView.Active.Map);
});
}
FeatureLayer是基于矢量地理数据的图层,通常是地理数据库、形状文件要素类或地图或要素服务的子图层。它允许您绘制和/或编辑基础特征。DefinitionQuery可用于绘制所有特征的子集。您还可以定义RendererDefinition以使用所需符号而不是默认符号显示数据。
如上所示,使用LayerFactory.Instance.CreateLayer方法创建要素图层。下面是一些代码片段。
//create a feature layer to ONLY cities in California
FeatureLayer flyr = LayerFactory.Instance.CreateLayer(new Uri(strUri), map) as FeatureLayer;
flyr.SetDefinitionQuery("state_name = 'California'");
// or use the FeatureLayerCreationParams
var featureCreateParams = new FeatureLayerCreationParams(new Uri(strUri))
{
Name = "States",
DefinitionQuery = new DefinitionQuery("California State", "state_name = 'California'"),
};
// use the FeatureLayer template to match the FeatureLayerCreationParams
FeatureLayer featurelayer =
LayerFactory.Instance.CreateLayer(featureCreateParams, MapView.Active.Map);
//create a feature layer with a graduated color renderer on a numeric field
var featureCreateParams = new FeatureLayerCreationParams(new Uri(strUri))
{
Name = "Population Density",
RendererDefinition = new GraduatedColorsRendererDefinition("POP10_SQMI"),
};
// use the FeatureLayer template to match the FeatureLayerCreationParams
FeatureLayer featurelayer =
LayerFactory.Instance.CreateLayer(featureCreateParams, MapView.Active.Map);
//create a feature layer with a graduated color renderer and a definition query
RendererDefinition rd = new GraduatedColorsRendererDefinition("POP10_SQMI");
var createParams = new FeatureLayerCreationParams(uri)
{
Name = "Population Density",
RendererDefinition = rd,
DefinitionQuery = new DefinitionQuery("Population greater than 1000", "POP > 1000"),
};
FeatureLayer flyr = LayerFactory.Instance.CreateLayer(createParams, myMap);
渲染器是存储要素图层符号化并基于存储的符号化规则绘制此数据的对象。要在ArcGIS Pro中创建渲染器,建议您创建一个RendererDefinition,调用CreateRenderer方法,该方法返回一个CIMRender对象。如果需要,可以在将其指定给要素层之前通过调用SetRenderer方法对其进行修改。例如,如果要通过调用GetRenderer方法修改渲染器中使用的符号,则可以获取指定给要素层的当前渲染器。
//assign a graduated color renderer with 6 breaks and exclusion clause
GraduatedColorsRendererDefinition gcDef = new GraduatedColorsRendererDefinition()
{
ClassificationField = "CROP_ACR07",
ClassificationMethod = ArcGIS.Core.CIM.ClassificationMethod.NaturalBreaks,
BreakCount = 6,
ExclusionClause = "CROP_ACR07 = -99",
ExclusionSymbol = aExclusionSymbol,
ColorRamp = aColorRamp,
SymbolTemplate = aSymbolTemplate,
};
CIMRenderer gcRenderer = aFeatureLayer.CreateRenderer(gcDef);
aFeatureLayer.SetRenderer(gcRenderer);
地图创作片段中有更多渲染器示例
图层的标签特性存储在FeatureLayer上可用的LabelClasses集合中。要更新或读取现有LabelClass的属性,请从集合中获取所需的LabelClass。
LabelClass提供对常用更新的标签类属性的访问。
通过调用GetMaplexLabelPlacementProperties()或GetStandardLabelPlagementProperties(),可以访问地图当前使用的标签引擎的完整标签放置属性,这两个函数分别返回CIMMaplexLabel placement属性和CIMStandardLabelplacementProproperties。要更新这些属性,请根据所使用的标签引擎调用SetMaplexLabelPlacementProperties()或SetStandardLabelPlagementProperties()。
调用地图上的GetLabelEngine以确定当前正在使用的标签引擎。地图级标签属性可以通过Map方法GetGeneralPlacementProperties()访问,并通过SetGeneralPlacesProperties()更新。
RasterLayer表示磁盘或地理数据库中的图像或像素数据。
// Create a RasterLayer from an image on disk.
string url = @"C:\Images\Italy.tif";
RasterLayer rasterLayer = LayerFactory.Instance.CreateLayer(new Uri(url), map) as RasterLayer;
使用RasterLayerCreationParams类并定义ColorizerDefinition,以使用所需的着色器而不是默认的着色器创建光栅或图像服务层。
// Create a new stretch colorizer definition using default constructor.
StretchColorizerDefinition stretchColorizerDef = new StretchColorizerDefinition();
await QueuedTask.Run(() =>
{
var rasterCreationParams = new RasterLayerCreationParams(new Uri(url));
rasterCreationParams.Name = layerName;
rasterCreationParams.MapMemberIndex = 0;
rasterCreationParams.ColorizerDefinition = stretchColorizerDef;
// Create a raster layer using the colorizer definition created above.
// Note: You can create a raster layer from a url, project item, or data connection.
RasterLayer rasterLayerfromURL = LayerFactory.Instance.CreateLayer(rasterCreationParams, map);
});
MosaicLayer是表示马赛克数据集的组层。马赛克数据集是一组无缝拼接在一起的图像,使它们看起来像一幅图像。镶嵌层组层可包含多达四个不同的子层:
// Get the Image sublayer of the mosaic layer.
ImageMosaicSubLayer mosaicImageSublayer = mosaiclayer.GetImageLayer();
// Get the Footprint sublayer of the mosaic layer.
FeatureMosaicSubLayer mosaicFootprintSubLayer = mosaiclayer.GetFootprintLayer();
// Get the Boundary sublayer of the mosaic layer.
FeatureMosaicSubLayer mosaicBoundarySubLayer = mosaiclayer.GetBoundaryLayer();
// Get the Seamline sublayer of the mosaic layer.
FeatureMosaicSubLayer mosaicSeamlineSubLayer = mosaiclayer.GetSeamlineLayer();
LayerFactory.Instance.CreateLayer()允许您传入RasterColorizerDefinition,以使用所需的着色器而不是默认的着色器创建马赛克层。
// Create a new colorizer definition using default constructor.
StretchColorizerDefinition stretchColorizerDef = new StretchColorizerDefinition();
await QueuedTask.Run(() =>
{
// Note: You can create a mosaic layer from a url, project item, or data connection.
var mosaicCreationParams = new MosaicLayerCreationParams(new Uri(url));
mosaicCreationParams.Name = layerName;
mosaicCreationParams.MapMemberIndex = 0;
mosaicCreationParams.ColorizerDefinition = stretchColorizerDef;
// Create a mosaic layer using the colorizer definition created above.
MosaicLayer newMosaicLayer = LayerFactory.Instance.CreateLayer(mosaicCreationParams, map);
});
ImageServiceLayer表示来自图像服务或马赛克数据集的像素数据。图像服务层允许用户更改图像拼接在一起的顺序(称为马赛克方法)以及图像重叠部分的显示方式(称为镶嵌算子)。图像服务层还允许用户控制正在传输的图像的压缩。
// Get the mosaic rule of the image service.
CIMMosaicRule mosaicRule = isLayer.GetMosaicRule();
// Set the mosaic method to be Center.
mosaicRule.MosaicMethod = RasterMosaicMethod.Center;
// Update the image service with the changed mosaic rule.
isLayer.SetMosaicRule(mosaicRule);
使用LayerFactory.Instance.CreateLayer()方法与RasterLayerCreationParams一起指定ColorizerDefinition,以使用所需的着色器而不是默认的着色器创建光栅或图像服务层。
// Create a new colorizer definition using default constructor.
StretchColorizerDefinition stretchColorizerDef = new StretchColorizerDefinition();
await QueuedTask.Run(() =>
{
var rasterCreationParams = new RasterLayerCreationParams(new Uri(url));
rasterCreationParams.Name = "my image layer";
rasterCreationParams.MapMemberIndex = 0;
rasterCreationParams.ColorizerDefinition = stretchColorizerDef;
// Create an image service layer using the colorizer definition created above.
ImageServiceLayer imageServiceLayer =
LayerFactory.Instance.CreateLayer(rasterCreationParams, map) as ImageServiceLayer;
});
光栅、马赛克和图像服务层是基于颜色器中存储的属性绘制的。要修改颜色器,请使用光栅和图像服务层上的GetColorizer方法获取CIMRasterColorizer对象,进行相应修改,然后使用SetColorizer方法应用更改。
要在ArcGIS Pro中创建着色器,建议您创建一个RasterColorizerDefinition,调用CreateColorizer方法返回CIMRasterColorize,然后使用SetColorizer方法将其分配给图层。
// Get the colorizer from the raster layer.
CIMRasterColorizer rasterColorizer = rasterLayer.GetColorizer();
// Update raster colorizer properties.
rasterColorizer.Brightness = 10;
rasterColorizer.Contrast = -5;
rasterColorizer.ResamplingType = RasterResamplingType.NearestNeighbor;
// Update the raster layer with the changed colorizer.
rasterLayer.SetColorizer(rasterColorizer);
从3.0开始,高程曲面和源由ElevationSurfaceLayer类表示。ElevationSurfaceLayer派生自CompositeLayer,可以包含零个、一个或多个子高程源层(例如光栅、三角网等)。例如,以下TOC显示了3个高程曲面图层。第一个是地面高程面层(“地面”),它包含2个高程源层。第二个高程曲面图层(“Surface1”)包含一个高程源图层,第三个高程曲面层(“surface 2”)包含0个高程源层。
您可以使用map.GetElevationSurfaceLayers检索地图中的高程面层。请注意,map.layers或map.GetLayersAsFlattenedList方法不会检索高程面层;必须使用Map.GetElevationSurfaceLayers。还有一个额外的方法Map.GetGroundElevationSubfaceLayer来检索指定为地面的高程面层。地图中始终只有一个地面高程曲面层。通过访问ElevationSurfaceLayer类的“图层”特性可以检索各个高程源图层。
// retrieve the elevation surface layers in the map including the Ground
var surfaceLayers = map.GetElevationSurfaceLayers();
// retrieve the single ground elevation surface layer in the map
var groundSurfaceLayer = map.GetGroundElevationSurfaceLayer();
// determine the number of elevation sources in the ground elevation surface layer
int numberGroundSources = groundSurfaceLayer.Layers.Count;
// get the first elevation source layer from the ground elevation surface layer
var groundSourceLayer = groundSurfaceLayer.Layers.FirstOrDefault();
您可以使用Map找到特定的高程曲面层。FindElevationSurfaceLayer(LayerUri)或地图。使用LINQ查询获取ElevationSurfaceLayers
var surfaceLayers = map.GetElevationSurfaceLayers();
var surfaceLayer = surfaceLayers.FirstOrDefault(l => l.Name == "Surface2");
var surfaceLayer = map.FindElevationSurfaceLayer(layerUri);
与所有其他图层类型一样,有一个ElevationLayerCreationParams类可与LayerFactory.Instance.CreateLayer方法一起使用,以将高程曲面图层添加到地图中。指定ElevationSurfaceLayer类型作为模板参数。将使用ElevationMode.CustomSurface的ElevationModel创建曲面层。
var map = MapView.Active.Map;
await QueuedTask.Run(() =>
{
string uri = "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer";
var createParams = new ElevationLayerCreationParams(new Uri(uri));
createParams.Name = "My custom elevation surface";
// adds a new elevation surface layer to the map with the specified elevation source
var eleSurfaceLayer = LayerFactory.Instance.CreateLayer(createParams, map);
});
要将高程源添加到现有高程曲面图层,请使用相同的CreateLayer方法,但将图层类型指定为样板,将高程曲面图层指定为容器而不是地图。
var surfaceLayers = map.GetElevationSurfaceLayers();
var surfaceLayer = surfaceLayers.FirstOrDefault(l => l.Name == "Surface2");
// surfaceLayer could also be the ground layer
// var surfaceLayer = map.GetGroundElevationSurfaceLayer();
await QueuedTask.Run(() =>
{
string uri = "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer";
var createParams = new ElevationLayerCreationParams(new Uri(uri));
createParams.Name = "Terrain 3D";
var eleSourceLayer = LayerFactory.Instance.CreateLayer(createParams, surfaceLayer);
});
要向地图添加新的地面高程曲面图层,请使用MapFactory.Instance.CreateScene方法。
//Or create a new scene from scratch with a ground elevation source
var scene = MapFactory.Instance.CreateScene("My scene", groundSourceUri, MapViewingMode.SceneGlobal);
使用RemoveLayer、RemoveLays或ClearElevationSurfaceLayers方法从地图中删除高程曲面图层。不能使用这些调用删除地面高程曲面图层。
map.RemoveLayer(surfaceLayer);//Cannot remove ground
map.RemoveLayers(map.GetElevationSurfaceLayers()); //Ground will not be removed
map.ClearElevationSurfaceLayers(); //Ground will not be removed
通过使用ElevationSurfaceLayer对象中的RemoveLayer和RemoveLays方法,从立面曲面图层中删除各个立面源图层。
await QueuedTask.Run(() =>
{
eleSurfaceLayer.RemoveLayer(eleSurfaceLayer.Layers.FirstOrDefault());
});
表格或“独立”表格用于以表格格式显示属性信息。用最简单的术语来说,表由行和列组成,所有行都有相同的列。此外,表格不包含形状列。使用表格视图(包括与要素图层关联的属性)可视化表格数据。可以同时打开多个表,无论是源于独立表还是源于层。可以通过UI自定义表视图,以修改列、筛选字段、排序记录、选择记录和编辑数据。
通过StandaloneTableFactory,可以以与层类似的方式(使用LayerFactory)将独立表添加到地图或场景:
//container can be a map or group layer
var container = MapView.Active.Map;
//var container = MapView.Active.Map.GetLayersAsFlattenedList()
// .OfType().First();
QueuedTask.Run(() =>
{
// use a local path
var table = StandaloneTableFactory.Instance.CreateStandaloneTable(
new Uri(@"C:\Temp\Data\SDK.gdb\EarthquakeDamage_Table", UriKind.Absolute),container);
//use a URI to a feature service table endpoint
var table2 = StandaloneTableFactory.Instance.CreateStandaloneTable(
new Uri(@"https://bexdog.esri.com/server/rest/services/FeatureServer" + "/2", UriKind.Absolute),
container);
//Use an item and StandaloneTableCreationParams
// StandaloneTableCreationParams allows you to set name, position, DefinitionQuery
var item = ItemFactory.Instance.Create(@"C:\Temp\Data\SDK.gdb\ParcelOwners");
var tableCreationParams = new StandaloneTableCreationParams(item);
tableCreationParams.Name = "Parcel Owners";
tableCreationParams.MapMemberPosition = MapMemberPosition.AddToTop;
var table3 = StandaloneTableFactory.Instance.CreateStandaloneTable(tableCreationParams, container);
});
一旦添加到映射中,就可以从各自的容器中检索表。可以使用FrameworkApplication.Panes.OpenTablePane(…)打开表视图。请注意,必须从UI线程调用OpenTablePane:
var container = MapView.Active.Map;
//the map standalone table collection
var table = container.GetStandaloneTablesAsFlattenedList()
.FirstOrDefault(tbl => tbl.Name == "EarthquakeDamage");
//or from a group layer
var grp_layer = MapView.Active.Map.FindLayers("GroupLayer1").First() as GroupLayer;
var table2 = grp_layer.FindStandaloneTables("EarthquakeDamage").First();
//or grp_layer.GetStandaloneTablesAsFlattenedList()
//show the table in a table view
//use FrameworkApplication.Current.Dispatcher.BeginInvoke if not on the UI thread
FrameworkApplication.Panes.OpenTablePane(table2);
可以在各自的容器(映射或组层)上使用MoveStandaloneTable方法将表移动到其容器内,或移动到另一个容器,其中“位置”被指定为从零开始的索引(在目标容器内),表应移动到该索引。位置0是容器的顶部,位置n-1或任何无效索引(如-1)将是底部。要在组层容器之间移动表,或从映射到组层,请使用MoveStandaloneTable(Standalone表,CompositeLayerWithTables targetLayer,int位置)重载,将目标容器指定为targetLaser参数。
将表格从组图层移动到地图是一种特殊情况。不能在MoveStandaloneTable()重载中将映射指定为目标容器,只有组层可以。相反,只需使用map.MoveStandaloneTable(table,index)方法指定要移动的表和要将其移动到的索引(在映射表容器中)。因为在这种情况下,指定的表包含在组层中,但MoveStandaloneTable正在映射上调用,所以映射被假定为目标容器。
//get the current map
var map = MapView.Active.Map;//assumes non-null
//get the first group layer that has at least one table
var grp_layer = MapView.Active.Map.GetLayersAsFlattenedList()
.OfType().First(g => g.StandaloneTables.Count > 0);//we assume there is one
var grp_layer2 = ....;//get another group layer from the map
QueuedTask.Run(() =>
{
//move the first table in the group layer to the bottom of the container
grp_layer.MoveStandaloneTable(grp_layer.StandaloneTables.First(), -1);
//move the last table in the map standalone tables to a group
//layer and place it at position 3. If 3 is invalid, the table
//will be placed at the bottom of the target container
//assumes the map has at least one standalone table...
var table = map.StandaloneTables.Last();
map.MoveStandaloneTable(table, grp_layer, 3);//move it to the group layer
//move a table from one group layer to another
grp_layer.MoveStandaloneTable(table, grp_layer2, 0);//move it to group layer "2"
//move a table from a group layer to the map standalone tables
//collection - assumes a table called 'Earthquakes' exists -
//special case - call MoveStandaloneTable() on the map...
var table2 = grp_layer.FindStandaloneTables("Earthquakes").First();
//move to the map container
map.MoveStandaloneTable(table2, 0);//will be placed at the top
});
可以通过RemoveStandaloneTable(…)从各自的容器中删除表,或者要删除多个,可以通过remove Standalone Tables(…)。
QueuedTask.Run(()=>
{
//get the tables from the map container
var tables = map.GetStandaloneTablesAsFlattenedList();
//delete the first...
if (tables.Count() > 0)
{
map.RemoveStandaloneTable(tables.First());
//or delete all of them
map.RemoveStandaloneTables(tables);
}
//delete a table from a group layer
//assumes it has at least one table...
grp_layer.RemoveStandaloneTable(grp_layer.StandaloneTables.First());
...
参考