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

版权声明:欢迎分享地理价值,但请注明出处,http://blog.csdn.net/liyuanxiang1984 https://blog.csdn.net/liyuanxiang1984/article/details/79974153

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 界面

单独将 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 分组显示

如果在 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 李远祥

阅读更多

扫码向博主提问

李远祥

博客专家

非学,无以致疑;非问,无以广识
去开通我的Chat快问
换一批

没有更多推荐了,返回首页