ArcGIS Maritime Server 开发教程Maritime Service 开发技巧

Posted 李远祥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArcGIS Maritime Server 开发教程Maritime Service 开发技巧相关的知识,希望对你有一定的参考价值。

ArcGIS Maritime Server 开发教程(六)Maritime Service 开发技巧

本章导读:GIS 开发人员基于 Maritime Service 开发海图应用时总会遇到与海图数据相关的问题,而对于数据的了解不足,往往给开发带来不少的困难。本章通过 ArcGIS 的几个工具进行辅助,让开发人员很好的从 GIS 向海图过渡,降低海图应用开发的门槛。 By 李远祥

巧妙使用 ArcGIS S-57 Viewer

S-57 Viewer 是 ArcGIS Desktop 的一个免费插件,通过扩展 ArcMap 的功能,让 ArcMap 能够直接读取 S-57 数据。S-57 Viewer 可以在 ArcGIS 的官方网站中下载。S-57 Viewer官方下载地址点击,目前最新版本为 2.2.0.9 。

单独将 S-57 Viewer 这个免费的插件拿出作为浏览 .000 数据的话,笔者认为它比不过免费的 CARIS Easy View 产品。但从 GIS 开发者的角度来看,它是一个协助 GIS 人员向海图技术过渡的利器。因为它能够从 GIS 的角度来解析数据。更有甚者,它是 Maritime Server 出现之间已经存在的东西, Maritime Server 的海图引擎都是从它的渲染引擎中演化过来的。

为什么说 S-57 Viewer 是 GIS 开发者的利器?从上面的图片可以看出,S-57 Viewer 对.000数据的对象进行了分组,并且将同组的对象归为了同一个图层,并且标准命名了。其图层和要素类(看起来像要素类,实际上还是松散的对象)的名称都是按照 S-57 物标的标准命名,只是在不同的类型后面加上了下划线,标明点线面类型,例如 _A 为面要素,_P为点要素。

所以,S-57 Viewer 对于开发者来说,它提供的海图显示并不是重点,对数据的解析才是最重要的,它为 GIS 开发者打开了 .000 数据的盒子,让他们能够以 GIS 人员的角度看清楚里面的结构内容。

以水深点为例,通过 S-57 Viewer 进行解析,可以看到其属性表里面的属性情况。

从这个对数据的解析来看,ArcGIS 软件对 S-57 数据的解析更像对 CAD 数据的解析,将同一组的对象解析为一个图层,将对象的一些说明写入到属性中,而并非图层要素的属性字段。这些都是解析性出来的结构,并不是真实逻辑结构。

在《ArcGIS Maritime Server 开发教程(四)Maritime Service 开发实践》提及到的 FindTask 和 IdentifyTask 的例子中提及到查询出来的结果,如何判别是哪一类型的对象,主要是通过 graphic 的 attributes 来确定的,而非图层名称。attributes 里面的其中一个属性是 objectType ,它对应的是解析出来的图层下划线前半部分名称,如 SOUNDG_P, objectType 输出则为 SOUNDG 。但从 SOUNDG_P 的属性表中根本就找不到 objectType 的字段。 所以,这个属性表里面的属性与 Maritime Service 的对象的属性是不一样的。objectType 是标识物标类型的唯一属性,它是与 S-57 物标对象命名是一致的。 在开发过程中,这个属性字段使用频率非常高。

对之前的 IdentifyTask 代码进行改造,点选查询水深点,并将查询的水深点的所有属性输出来。其代码片段如下

var soundg = "";
//获取物标所有的属性,其中objectType(固定标识) 为物标的唯一标识
var featureAttributes = gra.attributes;
for (var attr in featureAttributes) 
    if (attr == "objectType") 
        var oType = featureAttributes[attr];
        if (oType == "SOUNDG") 
            //输出所有的属性
            for (var attr in featureAttributes) 
                soundg = soundg + attr + ":" + featureAttributes[attr] + "   ";
            
            alert(soundg);
            //对点线面图形设置符号
            if (gra.geometry.type == "point") 
                gra.symbol = pointSym;
             else if (gra.geometry.type == "polyline") 
                gra.symbol = lineSym;
             else if (gra.geometry.type == "polygon") 
                gra.symbol = polySym;
            
            map.graphics.add(gra);
            //跳转到地图位置
            jumptoMap(gra);
        
    

最终的测试效果如下图所示,弹出框内容为水深点所有的字段名称及属性值。如下图所示

输出结果与 S-57 Viewer 的属性表对比,还是有一些差异的。如 OBJL、GRUP 等字段根本不存在。可以看出, S-57 Viewer 除了将对象的属性解析出来之外,还对其结构划分追加了一些内容。这部分内容可以给制作桌面工具例如 .000 转 GDB 的小工具提供了比较好的依据。

Maritime Service 中的图层

Maritime Service 在严格意义上是没有图层的概念的,但通过 Maritime Service 的 rest 页面,可以看到其分组显示。

如果在 Maritime Service 的服务地址添加索引号的话,是不能像传统图层那样跳转到有效的动态图层的,而是直接报“无效的URL”,并显示 400 的错误。如下图所示

如果单纯的将 Maritime Service 作为底图显示,那么这个图层分组没有什么太大的必要。但如果比较关注海图数据本身的应用,这样的分组是可以用作图层显示控制的。

S-57 数据的物标对象有上百种类型,如果想 S-57 Viewer 解析那样,将每一种都解析成一个图层,那么上百个图层对于图层控制来说没有多大的意义。Esri 根据自己对海图的理解,将 .000 数据归类为 8 个图层组,每个图层组实现对一组关联物标的控制。

对于传统的动态图层来说,通过图层索引的方式是可以加载的。但 Maritime Service 却不能通过类似的以下的 URL 方式来加载,如:

var enc84 = new DynamicLayer("http://localhost:6080/arcgis/rest/services/SampleWorldCities/MapServer/exts/MaritimeChartService/MapServer/4")

Maritime Service 必须完整加载服务之后,通过 setVisibleLayers 方法进行控制显示。例如要显示第3和第5个图层组的内容,可以参考以下代码:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>加载海图图层组服务</title>
  <link rel="stylesheet" href="http://localhost/arcgis_js_api/3.19/esri/css/esri.css">
  <style>
    html,
    body,
    #map 
      height: 100%;
      margin: 0;
      padding: 0;
    
  </style>
  <script src="http://localhost/arcgis_js_api/3.19/init.js"></script>
  <script>
    var map;
    require(["esri/map",
      "esri/layers/ArcGISDynamicMapServiceLayer",
      "esri/geometry/Extent",
      "dojo/domReady!"], function (Map, DynamicLayer,Extent) 
        var initexten = new Extent( "xmin": 113.42, "ymin": 22.15, "xmax": 113.58, "ymax": 22.26, "spatialReference":  "wkid": 4326  );
        map = new Map("map",  extent: initexten );
        //加载 WGS 84 服务
        var basemap = new DynamicLayer("http://localhost:6080/arcgis/rest/services/SampleWorldCities/MapServer");
        map.addLayer(basemap);
        //加载海图服务
        var enc84 = new DynamicLayer("http://localhost:6080/arcgis/rest/services/SampleWorldCities/MapServer/exts/MaritimeChartService/MapServer");
        //选择要显示的图层组
        enc84.setVisibleLayers([2,4]);
        map.addLayer(enc84);
      );
  </script>
</head>
<body>
  <div id="map"></div>
</body>
</html>

其显示效果如下

如果需要实现图层显示控制,只能通过 setVisibleLayers 方法来完成。

总结

本章是针对 GIS 开发人员向海图应用开发的过渡,利用 S-57 Viewer 对海图数据的解析,来了解 S-57 数据的结构以及在 GIS 中数据的组织方式。毕竟海图数据不是以图层的形式进行组织,因此在开发过程中“海图图层”与 GIS 图层有着比较大的区别。通过一些基本的测试,基本上可以了解到 S-57 数据与传统图层的异同,并通过 javascript API 进行有效的操作。

更多的GIS主流和非主流技术,可以持续关注CSDN的GIS制图乐园,以及微信公众号【GIS制图乐园】。BY 李远祥

以上是关于ArcGIS Maritime Server 开发教程Maritime Service 开发技巧的主要内容,如果未能解决你的问题,请参考以下文章

ArcGIS Maritime Server 开发教程Maritime Server 正确的开发模式

ArcGIS Maritime Server 开发教程Maritime Server 正确的开发模式

ArcGIS Maritime Server 开发教程Maritime Server 正确的开发模式

ArcGIS Maritime Server 开发教程Maritime Service 开发技巧

ArcGIS Maritime Server 开发教程Maritime Service 开发技巧

ArcGIS Maritime Server 开发教程Maritime Service 开发实践