利用Arcgis for javascript API绘制GeoJSON并同时弹出多个Popup

1.引言

  由于Arcgis for javascript API不可以绘制Geojson,并且提供的Popup一般只可以弹出一个,在很多专题图制作中,会遇到不少的麻烦。因此本文结合了两个现有的Arcgis for javascript API扩充库,对其进行改造达到绘制Geojson并同时弹出多个Popup的目的。

目前已有的两个扩充库github地址(可供单独使用):

1.绘制Geojson的扩充库:https://github.com/Esri/geojson-layer-js

2.多个Popup显示的扩充库:https://github.com/nickcam/PopupExtended

  本文实现的效果图:

 

                  图1 上海5个地点的部分预报属性                                 图2 上海某三条航线的部分预报属性

2. 各类依赖库引入及前端HTML

  首先需要先载入需要用的常用js、Arcgis及两个扩充库的js及部分css(下载地址见其github):

<!DOCTYPE html>
<html>
<head><title>Add GeoJSON and Display Multiple Popup</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=7,IE=9"><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"><!-- ArcGIS API for JavaScript CSS--><link rel="stylesheet" href="http://js.arcgis.com/3.13/esri/css/esri.css"><link rel="stylesheet" href="http://js.arcgis.com/3.13/dijit/themes/claro/claro.css"><!-- Web Framework CSS - Bootstrap (getbootstrap.com) and Bootstrap-map-js (github.com/esri/bootstrap-map-js) --><link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"><link rel="stylesheet" href="./css/bootstrap.min.css"><!-- PopExtendCss --><link href="./vendor/ncam/PopupExtended.css" rel="stylesheet" /><!-- PopupExtended references --><script>var dojoConfig = {parseOnLoad: false,async: true,tlmSiblingOfDojo: false,packages: [{name: "ncam",location: location.pathname.replace(/\/[^/]+$/, '') + "ncam"
            }]};</script><!-- ArcGIS API for JavaScript library references --><script src="//js.arcgis.com/3.10"></script><!-- Terraformer reference --><script src="./vendor/terraformer/terraformer.min.js"></script>    <script src="./vendor/terraformer-arcgis-parser/terraformer-arcgis-parser.min.js"></script><!-- other reference --><script src="./vendor/jquery.js"></script>
</head>
<body></body>
</html>

  加入底图所需要的div与图层切换的Button:

<body><div id="mapDiv"></div><button type="line" id="shanghaiPoint" class="btn btn-default buttonRight" style="top:20px;right:20px">上海区各点</button><button type="point" id="threeLine" class="btn btn-default buttonRight" style="top:70px;right:20px">三条航线</button>
</body>

3.置入Popupextended并扩充geojsonlayer.js  

  然后从geojsonlayer.js源码入手,开始将PopupExtended扩展其中,让我们新构建的geojsonlayer直接可拥有多个Popup。在geojsonlayer.js的constructor中很容易可以找出infotemplate的set方法:

            // Default popupif (options.infoTemplate !== false) {this.setInfoTemplate(options.infoTemplate || new InfoTemplate("GeoJSON Data", "${*}"));}

  很明显,geojsonlayer初始化时通过options传入参数进行判断并构造,所以实现本文目的的大致思路是将这里的setInfoTemplate替换成可以扩展的PopupExtended:

if (options.infoTemplate !== false) {//① create a PopupTemplatevar template = new PopupTemplate({title: "{name}",fieldInfos: [{ fieldName: "Id", label: "Id", visible: true },{ fieldName: "publishdate", label: "观测日期", visible: true },{ fieldName: "waveheight", label: "浪高", visible: true },{ fieldName: "wavedirection", label: "浪向", visible: true },{ fieldName: "windspeed", label: "风速", visible: true },{ fieldName: "winddirection", label: "风向", visible: true },{ fieldName: "comfort", label: "等级", visible: true }],extended: { actions: [{ text: " IconText", className: "iconText", title: "Custom action with an icon and Text", click: function (feature) { alert("Icon Text clicked on " + "id: " + feature.attributes.id + " " + feature.attributes.name); } },{ text: "", className: "iconOnly", title: "Custom action only using an icon", click: function (feature) { alert("Icon action clicked on " + "id: " + feature.attributes.id + " " + feature.attributes.name); } }                          ],//uses a pretty bad custom theme defined in PopupExtended.css.scaleSelected: 1.6}});//② create a extend for basemapvar extendedPopup = new PopupExtended({extended: {themeClass: "light",draggable: true,defaultWidth: 250,actions: [{text: "其他", className: "defaultAction", title: "Default action added in extendedPopup properties.",click: function (feature) { alert("clicked feature - " + feature.attributes); }}],hideOnOffClick: false,multiple: true,},highlight: false,//titleInBody: false,}, dojo.create("div"));//③set the map to use the exteneded popup
                extendedPopup.setMap(options.baseMap);options.baseMap.infoWindow = extendedPopup;this.setInfoTemplate(options.infoTemplate || template);}

  由上段代码可见,引入Popup给GeoJSON共分为三步:①实例化一个你需要的PopupTemplate(这里起名为template),可指定你需要展示的主题、数据项及扩展的一些交互action;②实例化一个PopupExtended并设置一些默认的Popup属性;③将实例化的PopupExtended——extendedPopup的Map设置为baseMap,并将baseMap的infowindow设置为extendedPopup,最后将geojsonlayer的infoTemplate设置为新构建的template。这样便可以实现对置入底图的geojsonlayer进行多个infoTemplate展示需求了。源代码见github:展示效果如图3:

 

图3 对geojsonlayer扩充Popupextended后的显示效果

  如若只需增加多个Popup至geojsonlayer的话,以上部分足以实现了。

4.增加新的Attributes及调整Popup的样式  

  由于设计上的需求,笔者需要从其他地址获取观测点的部分观测值,并且笔者的老师觉得应该加一些icon给属性,美化展示效果,所以需要重新构造两部分:①获取并为graphics增加新的attributes;②重构geojsonlayer的infoTemplate的content。

4.1 获取并为graphics增加新的attributes:

  通过在button上利用fetch及Promise.all来同时获取6个点或3条航线的数据,并传入至初始化geojsonlayer的函数内;

$("#shanghaiPoint").click(function(){// if first init geojsonlayerif(firstPointInit){var requestBZ = 'http://wx.dhybzx.org:18080/forecast/shanghai_sea_env/80';var requestWGQ = 'http://wx.dhybzx.org:18080/forecast/shanghai_sea_env/81';var requestHS = 'http://wx.dhybzx.org:18080/forecast/shanghai_sea_env/82';var requestLCG = 'http://wx.dhybzx.org:18080/forecast/shanghai_sea_env/83';var requestJHG = 'http://wx.dhybzx.org:18080/forecast/shanghai_sea_env/84';var requestJSW = 'http://wx.dhybzx.org:18080/forecast/shanghai_sea_env/85';var urls = [requestBZ, requestWGQ,requestHS,requestLCG,requestJHG,requestJSW]Promise.all(urls.map(url =>fetch(url).then(resp => resp.json()))).then(results => {var tempJson = {"堡镇":results[0][0],"外高桥":results[1][0],"横沙":results[2][0],"芦潮港":results[3][0],"金汇港":results[4][0],"金山卫":results[5][0]}addGeoJsonToMap("./data/six_point.json",tempJson)});}else{//geojsonlayer has been initialaddGeoJsonToMap("./data/six_point.json")}})

  这里的Promise.all采用了ES2015的箭头函数,兼容性问题需要自己考虑,也可以手动改成ES5支持的。将额外的attributes组装成tempJson后传入至初始化方法addGeoJsonToMap内。

4.2 重构geojsonlayer的infoTemplate的content:

  在geojsonlayer.js内继续做一部分修改,注释掉实例化template中的fieldInfos属性及值,并且为geojsonlayer的infoTemplate设置新的content,代码如下:

               var template = new PopupTemplate({title: "{name}",// fieldInfos: [//     { fieldName: "Id", label: "Id", visible: true },//     { fieldName: "publishdate", label: "观测日期", visible: true },//     { fieldName: "waveheight", label: "浪高", visible: true },//     { fieldName: "wavedirection", label: "浪向", visible: true },//     { fieldName: "windspeed", label: "风速", visible: true },//     { fieldName: "winddirection", label: "风向", visible: true },//     { fieldName: "comfort", label: "等级", visible: true }// ],
                        extended: { actions: [{ text: " IconText", className: "iconText", title: "Custom action with an icon and Text", click: function (feature) { alert("Icon Text clicked on " + "id: " + feature.attributes.id + " " + feature.attributes.name); } },{ text: "", className: "iconOnly", title: "Custom action only using an icon", click: function (feature) { alert("Icon action clicked on " + "id: " + feature.attributes.id + " " + feature.attributes.name); } }                          ],//uses a pretty bad custom theme defined in PopupExtended.css.scaleSelected: 1.6}});//create a extend for basemapvar extendedPopup = new PopupExtended({extended: {themeClass: "light",draggable: true,defaultWidth: 250,actions: [{text: "其他", className: "defaultAction", title: "Default action added in extendedPopup properties.",click: function (feature) { alert("clicked feature - " + feature.attributes); }}],hideOnOffClick: false,multiple: true,},highlight: false,//titleInBody: false,}, dojo.create("div"));//set the map to use the exteneded popup
                extendedPopup.setMap(options.baseMap);options.baseMap.infoWindow = extendedPopup;this.setInfoTemplate(options.infoTemplate || template);this.infoTemplate.setContent("<b class='popupTitle'>${name}</b>" +"<div class='hzLine'></div>"+"<div class='popupContent'>"+"<i class='glyphicon glyphicon-calendar'></i><b>日期: </b> ${publishdate}<br/>"+"<i class='glyphicon glyphicon-resize-vertical'></i><b>浪高: </b> ${waveheight}<br/>" +"<i class='glyphicon glyphicon-random'></i><b>浪向: </b> ${wavedirection}<br/>"+"<i class='glyphicon glyphicon-share'></i><b>风速: </b> ${windspeed}<br/>" +"<i class='glyphicon glyphicon-transfer'></i><b>风向: </b> ${winddirection}<br/>"+"<i class='glyphicon glyphicon-export'></i><b>等级: </b> ${comfort}<br/>"+"</div>");

  额外的属性和新的infoTemplate样式构造完成,但存在一个问题,即额外的attributes必须要在geojsonlayer绘制好后再进行设置并展示,arcgis提供了layer的layer-add及layer-add-result事件,但是无法监控到graphics是否已经增入至geojsonlayer内,所以必须要再做一些改进,使额外的属性能够在graphics绘制完毕后再添加进去。具体方法分为两步:1)初始化geojsonlayer时,将showAllPopup方法传入其构造函数内;2)在grahics添加至layer后,调用showAllPopup方法,显示所有的Popup。前端代码如下:

//add GeoJSON to baseMap , constuct show&hide popup method and add other attribute to graphicsfunction addGeoJsonToMap(url,otherJson){require(["esri/map","./src/geojsonlayer.js","esri/geometry/Point", "esri/SpatialReference","dojo/on","dojo/dom","dojo/domReady!"],function (Map, GeoJsonLayer, Point, SpatialReference,on, dom) {var hasThisLayer=false;otherJson=otherJson?otherJson:"";hideAllPopup()//judge layer has been initmap.getLayersVisibleAtScale().forEach(function(item){if(item._url==url&&item.dataType=="geojson"){console.log(item)item.show();console.log("dd")showAllPopup(item);hasThisLayer=true;// map.setExtent(item.extent)}else if(item._url!=url&&item.dataType=="geojson"){item.hide();}})if(!hasThisLayer){addGeoJsonLayer(url);                                  }//show all popupsfunction showAllPopup(layer){......}//hide all popupsfunction hideAllPopup(){.......}//add other attribute to grpahics for popupfunction addAttrToGrpahics(item,type){.......}// Add the layerfunction addGeoJsonLayer(url) {// Create the layervar geoJsonLayer = new GeoJsonLayer({baseMap:map,url: url,onLayerLoaded:function(layer){showAllPopup(layer);}              });// Add to mapgeoJsonLayer.dataType="geojson"; map.addLayer(geoJsonLayer);}});}

并且在geojsonlayer.js的constructor内加入:

this._onLayerLoaded = options.onLayerLoaded;

在最后的_addGraphics方法中onLoad方法后,加入:

if (this._onLayerLoaded) this._onLayerLoaded(this);

利用show/hide方法,控制popup显示及隐藏。

//open all popup
layer.graphics.forEach(function(item){if(firstPointInit&&otherJson[item.attributes.name]){addAttrToGrpahics(item,layer.graphics[0].geometry.type)}var loc = map.toScreen(item.geometry);map.infoWindow.setFeatures([item]);map.infoWindow.show(loc);
})
//hide all popup
var tempLength = map.infoWindow.openPopups.length;
for(var i=0;i<tempLength;i++){map.infoWindow.openPopups[0].hide()
}

5. 结论  

  至此,本文已经完成了在Arcgis for javascript API中实现Geojson的绘制,并同时展示其多个Popup的需求。最终的展示效果如图1、2。源代码见笔者的github:https://github.com/EasonXu818/Add-GeoJSON-Multiple-Popups。

 

转载于:https://www.cnblogs.com/easonxu/p/6588529.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/393444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HBase数据备份及恢复(导入导出)的常用方法

一、说明 随着HBase在重要的商业系统中应用的大量增加&#xff0c;许多企业需要通过对它们的HBase集群建立健壮的备份和故障恢复机制来保证它们的企业&#xff08;数据&#xff09;资产。备份Hbase时的难点是其待备份的数据集可能非常巨大&#xff0c;因此备份方案必须有很高的…

Android商城开发系列(二)——App启动欢迎页面制作

商城APP一般都会在应用启动时有一个欢迎界面&#xff0c;下面我们来实现一个最简单的欢迎页开发&#xff1a;就是打开商城App&#xff0c;先出现欢迎界面&#xff0c;停留几秒钟&#xff0c;自动进入应用程序的主界面。 首先先定义WelcomeActivity布局&#xff0c;布局非常简单…

DELL安装不了mysql_Windows 版本 Mysql 8.x 安装

1、官网下载安装包百度网盘链接&#xff1a;https://pan.baidu.com/s/1cFRbQM5720xrzMxbgjPeyA提取码&#xff1a;xlz72、解压安装包并新建一个文件夹作为安装目录(mysqlInstall)3、配置 Mysql 环境变量4、在解压好的目录下新建一个 my.ini 文件(注意&#xff1a;my.ini 文件和…

Hyper-V Server联机调整虚拟硬盘大小

1. 技术概述&#xff1a; 从 Windows Server 2012 R2开始&#xff0c;管理员可以在运行虚拟机的同时&#xff0c;使用 Hyper-V 来扩展或压缩虚拟硬盘的大小。存储管理员可以通过对运行中的虚拟硬盘执行维护操作来避免代价不菲的停机。不再需要关闭虚拟机&#xff0c;这可以避免…

python网络爬虫(5)BeautifulSoup的使用示范

创建并显示原始内容 其中的lxml第三方解释器加快解析速度 import bs4 from bs4 import BeautifulSoup html_str """ <html><head><title>The Dormouses story</title></head> <body> <p class"title"><…

物联网笔记

转载于:https://www.cnblogs.com/16-C-kai/p/6596682.html

关于大学生玩网络游戏的调查问卷

1.创建问卷&#xff0c;输入调查名称 2编辑问卷 3检查问卷&#xff0c;是否有误 4.提交并发布问卷 5分享问卷 6.问卷分析 转载于:https://www.cnblogs.com/dzw1996/p/7786754.html

第六次 实验

转载于:https://www.cnblogs.com/P201821440005/p/10967987.html

du命令、df命令用法

一、du命令 [plain] view plaincopy print?[rootwc1 mysql]# du --help Usage: du [OPTION]... [FILE]... or: du [OPTION]... --files0-fromF Summarize disk usage of each FILE, recursively for directories. Mandatory arguments to long options are mandatory…

SQL Server 2008 - Cannot set a credential for principal 'sa'.

很久没有用到SQL Server了&#xff0c;今天有幸在帮同事解决一个SQL Server数据连接的问题时突然发现我无法修改我的sa用户的密码了。过程是这样的&#xff1a;一开始我本地的数据库实例是Windows认证方式&#xff0c;我想将它改成Windows和数据库混合认证方式后用sa账户登录&a…

Java小知识-----Map 按Key排序和按Value排序

Map排序的方式有很多种&#xff0c;这里记录下自己总结的两种比较常用的方式&#xff1a;按键排序(sort by key)&#xff0c; 按值排序(sort by value)。 1、按键排序 jdk内置的java.util包下的TreeMap<K,V>既可满足此类需求&#xff0c;向其构造方法 TreeMap(Comparator…

Microsoft Deployment Toolkit 2010 新功能实战之一

续Microsoft Deployment Toolkit 2010 Beta 2先睹为快&#xff01;下面将通过使用Microsoft Deployment Toolkit 2010来部署Windows 7来介绍它的新功能的具体操作。有些概念的理解和操作方法参见MDT2008部署之一概览。 一、实验环境操作全部在VMware Workstation的虚拟操作环境…

Netbackup detected IBM drives as unusable

今天在远程给客户安装NBU的时候&#xff0c;遇到了下面这个问题&#xff0c;下面的内容来至于SYMANTEC。 1&#xff0c;更新mapping文件 在原来也遇到过类型的故障&#xff0c;通过更新mapping文件后&#xff0c;故障解决&#xff0c;这次没有那么幸运了。 2&#xff0c;lsscsi…

opencv python运动人体检测

采用非极大值抑制&#xff0c;将重叠的框合并成一个。 # import the necessary packages from imutils.object_detection import non_max_suppression import numpy as np import imutils import cv2# initialize the HOG descriptor/person detector hog cv2.HOGDescriptor()…

php mysql 注入一句话木马_渗透技术--SQL注入写一句话木马原理

讲一下SQL注入中写一句话拿webshell的原理&#xff0c;主要使用的是 SELECT ... INTO OUTFILE 这个语句&#xff0c;下面是一个语句的例子:SELECT * INTO OUTFILE C:\log1.txt这样就可以把查询到的数据写入到C盘的log1.txt这个文件里面。利用这个原理我们可以把PHP的一句话木马…

java 多线程阻塞队列 与 阻塞方法与和非阻塞方法

Queue是什么队列&#xff0c;是一种数据结构。除了优先级队列和LIFO队列外&#xff0c;队列都是以FIFO&#xff08;先进先出&#xff09;的方式对各个元素进行排序的。无论使用哪种排序方式&#xff0c;队列的头都是调用remove()或poll()移除元素的。在FIFO队列中&#xff0c;所…

批量移动AD用户到指定OU

作为域管理员&#xff0c;在日常工作中使用ADUC&#xff08;AD用户和计算机&#xff09;工具在图形界面中进行账号管理操作可谓是家常便饭了。然而一个个增加、移动、删除用户&#xff0c;这样操作有时真的够烦&#xff0c;当管理大批量的账户时&#xff0c;重复操作浪费的时间…

oracle常用操作指令

登录oracle用户: sqlplus 用户名/密码 创建用户&#xff1a;create user 要创建的用户名 identified by 当前用户名; 授权&#xff1a;grant resource,connect to 要授权的用户名; 删除用户&#xff1a;drop user 用户名 创建表&#xff1a; create table student( id n…

JAVA基础_修饰符

引言&#xff1a;Java的修饰符根据修饰的对象不同&#xff0c;分为类修饰符、方法修饰符、变量修饰符&#xff0c;其中每种修饰符又分为访问控制修饰符和非访问控制修饰符。访问控制存在的原因&#xff1a;a、让客户端程序员无法触及他们不应该触及的部分 b、允许库设计者可以改…

iOS https双向配置

只需要服务器验证手机端的童鞋可以点开以下链接【ios 单向配置https】 http://www.cnblogs.com/OC888/p/6560602.html 兜兜转转弄了一个星期&#xff0c;网上的大多数demo都下来过一遍了&#xff0c;各种偏方都试了&#xff0c;终于配置好了双向配置&#xff0c;网上大多数标题…