[Map 3D开发实战系列] Map Resource Explorer 之六--资源操作及数据绑定

简介:


目录

[Map 3D开发实战系列] Map Resource Explorer 背景介绍--Kick off

[Map 3D开发实战系列] Map Resource Explorer 之二-- 运行和调试

[Map 3D开发实战系列] Map Resource Explorer 之三-- 添加AutoCAD风格的Palette界面

[Map 3D开发实战系列] Map Resource Explorer 之四-- Map3D开发中的WPF

[Map 3D开发实战系列] Map Resource Explorer 之五--界面设计

 

这篇文章中将触及到Map 3D开发的核心操作--资源操作。我们将枚举文档中所包含的所有资源,并显示到TreeView中。

 

为了项目组织方便,我把这些和业务逻辑相关的类放在Model目录下。在Visual Studio中添加Model目录后,在Model目录下新建一个类命名为ResourceManager,所有和Map 3D资源操作相关的方法就放在这里类里面。在编写资源操作相关方法之前,我们先为这个ResourceManager类做一个Singleton模式:

        #region Singleton
private static ResourceManager _instance = null;

private ResourceManager()
{

}

public static ResourceManager Instance
{
get
{
if (_instance == null)
{
_instance = new ResourceManager();
}

return _instance;
}

}

#endregion

 

现在开始实现资源相关方法,在Map 3D中支持的资源类型为FeatureSource,LayerDefiniation和SymbolDefinition。要素源FeatureSource包含了连接到地理要素源相关的参数信息;图层定义LayerDefiniation包含了图层显示和样式化相关的参数;符号定义SymbolDefinition定义了显示在地图上的符号。同一个文档中可能会有多个 FeatureSource,多个图层LayerDefiniation和SymbolDefinition,所有我们可以考虑按照资源类型类组织资源在 TreeView中的显示。所以我首先要定义一下Map 3D中支持的资源类型,以Dictionary<string, string>方式返回,以便绑定到TreeView上,其中第一个参数是资源类型,第二个参数是描述信息:

        /// <summary>
        /// Get valid resource type in Map3D
        /// --------------------------------------
        /// FeatureSource Contains the required parameters for connecting to a geospatial feature source 
        /// LayerDefinition Contains the required parameters for displaying and styling a layer. Layers can be drawing layers, vector layers, or grid (raster) layers. 
        /// SymbolDefinition Defines a symbol to be displayed on a map. 
        /// </summary>
        /// <returns></returns>
        public Dictionary<string,string> GetResourceAllTypes()
{
Dictionary<string, string> resourceTypes = new Dictionary<string, string>();
resourceTypes.Add(MgResourceType.FeatureSource, "Contains the required parameters for connecting to a geospatial feature source.");
resourceTypes.Add(MgResourceType.LayerDefinition, "Contains the required parameters for displaying and styling a layer. Layers can be drawing layers, vector layers, or grid (raster) layers.");
resourceTypes.Add(MgResourceType.SymbolDefinition, "Defines a symbol to be displayed on a map.");
return resourceTypes;
}
 

下面我们把资源类型作为treeview的节点绑定到TreeView界面上。在我们的自定义WPF用户控件的后台代码ExplorerForm.xaml.cs中定义BindTreeView方法,调用ResourceManager中定义的GetResourceAllTypes方法获取所有Map 3D支持的资源类型字典。然后把这个字典绑定到treeview控件上,把资源类型作为TreeViewItem的Header显示,把描述信息作为ToolTip。

        public void ForceRefresh()
{
if (this.IsVisible)
{
BindTreeView(treeView1);
}

}


private void BindTreeView(TreeView tree)
{
tree.Items.Clear();

ResourceManager resourceMgr = ResourceManager.Instance;

Dictionary<string, string> resourceTypes = resourceMgr.GetResourceAllTypes();
foreach (var resType in resourceTypes)
{
TreeViewItem resourceTypeitem = new TreeViewItem();
resourceTypeitem.Header = resType.Key;
resourceTypeitem.ToolTip = resType.Value;
//Bind resource to resourceItemType Dictionary<string, string> resList = resourceMgr.GetResourcesByType(resType.Key);

tree.Items.Add(resourceTypeitem);
}
}
现在运行一下,我们的资源浏览器应该已经初见雏形了,如图:

image

 

好了,现在来按照资源类型来枚举文档library中包含的所有资源。Map 3D采用Geospatial Platform API中的资源服务来枚举所有的资源。我们首先要创建资源服务,在Map 3D中创建资源服务于MapGuide中略有不同。在MapGuide中,资源服务是有SiteConnection.CreateService方法创建出来的,而在Map 3D中是通过AcMapServiceFactory的静态方法GetService来创建的:

        public MgResourceService ResourceService
{
get
{
if (_resourceService == null)
{
_resourceService = AcMapServiceFactory.GetService(MgServiceType.ResourceService) as MgResourceService;
}
return _resourceService;
}
}
 

现在有了资源服务,就可以通过MgResourceService::EnumerateResources方法来枚举所有资源了,下面是摘自帮助文档中关于EnumerateResources方法的描述。传入要枚举的资源ID,如果要枚举资源库中所有的资源resourceID可以是Library://. 也可以指定资源类型来枚特定类型的资源。函数的返回值是一个MgByteReader对象,里面包含了XML表示的资源列表。

 

.NET Syntax

MgByteReader EnumerateResources(MgResourceIdentifier resource, int depth, string type);

Parameters:

resource
(MgResourceIdentifier) Resource identifier specifying the resource to enumerate. This can be a document or a folder. 
If it is a folder, you must include the trailing slash in the identifier.

depth
(int) Recursion depth, relative to the specified resource.

  • If the resource is a document, depth must be set to 0.
  • If the resource is a folder:
    • If the depth is equal to 0, only information about the specified folder is returned.
    • If the depth is greater than 0, information about the folder and its descendants up to the specified depth are returned.
  • If the depth is -1, information about the folder and all its descendants is returned.

type
(String/string) Type of the resource to be enumerated. (Case sensitive.) See MgResourceType for valid types. 
Or, this can be set to null, in which case information about all resource types is returned.

Returns:
Returns an  MgByteReader object containing a description of the resources in XML format using the  ResourceList schema.

下面是运行过程中MgResourceService::EnumerateResources方法返回的XMl的一个例子,我们可以通过DOM来解析XML,找到我们的需要的资源ID。

-----------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<ResourceList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ResourceList-1.0.0.xsd">
  <ResourceDocument>
    <ResourceId>Library://erase.FeatureSource</ResourceId>
    <Depth>1</Depth>
    <Owner></Owner>
    <CreatedDate>2011-02-07T06:27:24.062153Z</CreatedDate>
    <ModifiedDate>2011-02-07T06:27:24.062153Z</ModifiedDate>
    <ResourceDocumentHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema"                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                    xsi:noNamespaceSchemaLocation="ResourceDocumentHeader-1.0.0.xsd">
      <General>
        <IconName></IconName>
      </General>
      <Security xsi:noNamespaceSchemaLocation="ResourceSecurity-1.0.0.xsd">
        <Inherited>true</Inherited>
        <Groups>
          <Group>
            <Name>Everyone</Name>
            <Permissions>r,w</Permissions>
          </Group>
        </Groups>
      </Security>
    </ResourceDocumentHeader>
  </ResourceDocument>
  <ResourceDocument>
    <ResourceId>Library://intersect2.FeatureSource</ResourceId>
    <Depth>1</Depth>
    <Owner></Owner>
    <CreatedDate>2011-02-07T06:27:16.857741Z</CreatedDate>
    <ModifiedDate>2011-02-07T06:27:16.857741Z</ModifiedDate>
    <ResourceDocumentHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema"                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                    xsi:noNamespaceSchemaLocation="ResourceDocumentHeader-1.0.0.xsd">
      <General>
        <IconName></IconName>
      </General>
      <Security xsi:noNamespaceSchemaLocation="ResourceSecurity-1.0.0.xsd">
        <Inherited>true</Inherited>
        <Groups>
          <Group>
            <Name>Everyone</Name>
            <Permissions>r,w</Permissions>
          </Group>
        </Groups>
      </Security>
    </ResourceDocumentHeader>
  </ResourceDocument>
  <ResourceDocument>
    <ResourceId>Library://realtor_neighborhoods.FeatureSource</ResourceId>
    <Depth>1</Depth>
    <Owner></Owner>
    <CreatedDate>2011-02-07T06:26:52.00632Z</CreatedDate>
    <ModifiedDate>2011-02-07T06:26:52.00632Z</ModifiedDate>
    <ResourceDocumentHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema"                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                    xsi:noNamespaceSchemaLocation="ResourceDocumentHeader-1.0.0.xsd">
      <General>
        <IconName></IconName>
      </General>
      <Security xsi:noNamespaceSchemaLocation="ResourceSecurity-1.0.0.xsd">
        <Inherited>true</Inherited>
        <Groups>
          <Group>
            <Name>Everyone</Name>
            <Permissions>r,w</Permissions>
          </Group>
        </Groups>
      </Security>
    </ResourceDocumentHeader>
  </ResourceDocument>
  <ResourceDocument>
    <ResourceId>Library://sfzipcodes.FeatureSource</ResourceId>
    <Depth>1</Depth>
    <Owner></Owner>
    <CreatedDate>2011-02-07T06:26:53.154385Z</CreatedDate>
    <ModifiedDate>2011-02-07T06:26:53.154385Z</ModifiedDate>
    <ResourceDocumentHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema"                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                    xsi:noNamespaceSchemaLocation="ResourceDocumentHeader-1.0.0.xsd">
      <General>
        <IconName></IconName>
      </General>
      <Security xsi:noNamespaceSchemaLocation="ResourceSecurity-1.0.0.xsd">
        <Inherited>true</Inherited>
        <Groups>
          <Group>
            <Name>Everyone</Name>
            <Permissions>r,w</Permissions>
          </Group>
        </Groups>
      </Security>
    </ResourceDocumentHeader>
  </ResourceDocument>
</ResourceList>

 

我们在ResourceManager类中添加下面的方法来枚举资源库中的指定类型的资源,通过XML解析后存入一个Dictionary中返回,字典的第一个参数是资源名字用来显示,第二个参数是resourceID,用来进行后续存取资源内容时使用。

        public Dictionary<string, string> GetResourcesByType(string resourceType)
{
//TODO: if (!IsValidMap3DResourceType(resourceType))
{
throw new ApplicationException("unspported resource type by Map3D");
}

Dictionary<string, string> resources = new Dictionary<string, string>();

MgResourceIdentifier rootResId = new MgResourceIdentifier(@"Library://");
MgByteReader reader = ResourceService.EnumerateResources(rootResId, -1, resourceType.ToString());

//Convert to string String resStr = reader.ToString(); //Load into XML document so we can parse and get the names of the maps XmlDocument doc = new XmlDocument();
doc.LoadXml(resStr);

//let's extract the map names and list them XmlNodeList resIdNodeList; XmlElement root = doc.DocumentElement; resIdNodeList = root.SelectNodes("//ResourceId");
int resCount = resIdNodeList.Count;
for (int i = 0; i < resCount; i++)
{
XmlNode resIdNode = resIdNodeList.Item(i);
String resId = resIdNode.InnerText;
int index1 = resId.LastIndexOf('/') + 1;
int index2 = resId.IndexOf(resourceType) - 2;
int length = index2 - index1 + 1;
string resName = resId.Substring(index1, length);
resources.Add(resName, resId);

}


return resources;
}

 

好了,然后我们把枚举到的资源也作为treeviewitem绑定到treeview控件上。修改上面的BingTreeView方法如下:

 

        private void BindTreeView(TreeView tree)
{
tree.Items.Clear();

ResourceManager resourceMgr = ResourceManager.Instance;

Dictionary<string, string> resourceTypes = resourceMgr.GetResourceAllTypes();
foreach (var resType in resourceTypes)
{
TreeViewItem resourceTypeitem = new TreeViewItem();
resourceTypeitem.Header = resType.Key;
resourceTypeitem.ToolTip = resType.Value;
//Bind resource to resourceItemType Dictionary<string, string> resList = resourceMgr.GetResourcesByType(resType.Key);

foreach (var item in resList)
{
TreeViewItem resItem = new TreeViewItem();
resItem.Header = item.Key;
resItem.ToolTip = item.Value;
resItem.Tag = "IsResource";

resourceTypeitem.Items.Add(resItem);
}
tree.Items.Add(resourceTypeitem); } }
 

好了,编译一下如果没什么问题的话我们的工作已经完成一半了,通过netload命令加载程序集并调出ResourceExplorer界面后,你应该能看到类似下面的界面:

image

 

好了,先到这儿吧,下来我们该准备后续的关于资源内容方面的操作了。请继续关注。

 

Cheers,

峻祁连

作者: 峻祁连
邮箱:junqilian@163.com 
出处: http://junqilian.cnblogs.com 
转载请保留此信息。



本文转自峻祁连. Moving to Cloud/Mobile博客园博客,原文链接:http://www.cnblogs.com/junqilian/archive/2011/02/08/1949656.html ,如需转载请自行联系原作者
相关文章
|
7月前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
110 3
|
定位技术
百度地图开发:map.setViewport让标注显示在最佳视野内
百度地图开发:map.setViewport让标注显示在最佳视野内
349 0
|
机器学习/深度学习 定位技术 容器
百度地图高级开发:map.getDistance计算多点之间的距离并输入矩阵
百度地图高级开发:map.getDistance计算多点之间的距离并输入矩阵
295 0
|
2月前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
79 2
SpringMVC入门到实战------5、域对象共享数据 Request、Session、Application、Model、ModelAndView、Map、ModelMap的详细使用及代码实例
这篇文章详细解释了在IntelliJ IDEA中如何使用Mute Breakpoints功能来快速跳过程序中的后续断点,并展示了如何一键清空所有设置的断点。
SpringMVC入门到实战------5、域对象共享数据 Request、Session、Application、Model、ModelAndView、Map、ModelMap的详细使用及代码实例
|
4月前
|
Java Serverless Go
Golang 开发函数计算问题之在 Golang 中避免 "concurrent map writes" 异常如何解决
Golang 开发函数计算问题之在 Golang 中避免 "concurrent map writes" 异常如何解决
|
5月前
|
JavaScript 定位技术
vue-baidu-map 绘制行政区划的轮廓,添加行政区划名称(含给覆盖物添加点击事件)——vue 百度地图开发
vue-baidu-map 绘制行政区划的轮廓,添加行政区划名称(含给覆盖物添加点击事件)——vue 百度地图开发
286 1
|
5月前
|
JavaScript 定位技术
vue 百度地图开发【教程】1. 绘制百度地图(不使用 vue-baidu-map,解决 BMap is undefined)
vue 百度地图开发【教程】1. 绘制百度地图(不使用 vue-baidu-map,解决 BMap is undefined)
442 0
|
6月前
|
存储 Java 数据处理
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【6月更文挑战第18天】在Java中,HashMap基于哈希表提供快速的键值对操作,适合无序数据;而TreeMap利用红黑树保证排序,适用于有序场景。示例展示了HashMap如何存储并查找用户信息,以及TreeMap如何按员工编号排序存储员工名。两者在不同需求下优化了数据处理。
162 0
|
7月前
|
JavaScript
webpack-devtool选项 --生成source-map便于开发调试(二)
webpack-devtool选项 --生成source-map便于开发调试(二)
235 0