利用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,一经查实,立即删除!

相关文章

java 线程简介_java多线程介绍

java多线程介绍多线程的基本实现进程指运行中的程序&#xff0c;每个进程都会分配一个内存空间&#xff0c;一个进程中存在多个线程&#xff0c;启动一个JAVA虚拟机&#xff0c;就是打开个一个进程&#xff0c;一个进程有多个线程&#xff0c;当多个线程同时进行&#xff0c;就…

webpack入门——构建简易版vue-cli

用vue-cli1/2搭建一个vue项目时&#xff0c;可以看到有很多关于webpack配置的文件。我们不需要知道那些繁琐的配置文件有什么作用&#xff0c;只需在控制台输入npm run dev&#xff0c;项目自动启动&#xff0c;我们就可以愉快的写业务代码了。 虽然vue-cli帮我们做好了一切&am…

leetcode43. 字符串相乘

给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 示例 1: 输入: num1 “2”, num2 “3” 输出: “6” 代码 class Solution {public String multiply(String num1, String num2) {if(n…

作业二:个人博客作业内容:需求分析

作业二&#xff1a;个人博客作业内容&#xff1a;需求分析 怎样与用户有效沟通获取用户的真实需求&#xff1f;访谈&#xff0c;正式访谈系统分析员将提出一些事先准备好的具体问题&#xff1b;非正式访谈中&#xff0c;分析人员将提出一些用户可以自由回答的开放性问题&#…

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

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

react和react2_为什么React16是React开发人员的福气

react和react2by Harsh Makadia通过苛刻马卡迪亚 为什么React16是React开发人员的福气 (Why React16 is a blessing to React developers) Just like how people are excited about updating their mobile apps and OS, developers should also be excited to update their fr…

jzoj4598. 【NOIP2016模拟7.9】准备食物

一个th的题&#xff08;a gensokyo&#xff09; 难度系数在该知识点下为$2.1$ 区间xor我们很明显会想到trie树&#xff0c;将每一个区间$l~r$异或和拆成$sum[l-1]$ $sum[r]$两个数的异或 注意到二进制的性质&#xff0c;比当前低的位即使都取1加起来都没有这位选1答案高&#x…

java number转string_Java Number类, Character类,String类

字符串在Java编程中广泛使用&#xff0c;字符串就是一系列字符(由一个个的字符组成)。 在Java编程语言中&#xff0c;字符串被视为对象。Java平台提供String类来创建和操作字符串。1. 创建字符串创建字符串的最直接方法是 -String str "Hello world!";每当它在代码中…

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 文件和…

lambda 使用_如何使用Lambda和API网关构建API

lambda 使用Do you want to access your database, control your system, or execute some code from another website? An API can do all of this for you, and they’re surprisingly easy to set up.您是否要访问数据库&#xff0c;控制系统或从其他网站执行一些代码&…

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

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

leetcode162. 寻找峰值(二分法)

峰值元素是指其值大于左右相邻值的元素。 给定一个输入数组 nums&#xff0c;其中 nums[i] ≠ nums[i1]&#xff0c;找到峰值元素并返回其索引。 数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个峰值所在位置即可。 你可以假设 nums[-1] nums[n] -…

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

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

Mingw编译DLib

Mingw编译DLib 因为机器上安装了qt-opensource-windows-x86-mingw530-5.8.0&#xff0c;所以准备使用其自带的mingw530来编译DLib使用。 因为DLib使用CMake的构建脚本&#xff0c;所以还请先安装好CMake。 cmake的下载地址如下https://cmake.org/files/v3.7/cmake-3.7.2-win64-…

探索JavaScript的关闭功能

Discover Functional JavaScript was named one of the best new Functional Programming books by BookAuthority!“发现功能JavaScript”被BookAuthority评为最佳新功能编程书籍之一 &#xff01; A closure is an inner function that has access to the outer scope, even…

QueryList 配置curl参数 的文档位置 QueryList抓取https 终于找到了

需要设置ssl证书&#xff0c;或者不验证证书&#xff0c;例&#xff1a;$ql QueryList::get(https://...,[],[verify > false]);设置这个 verify > false , 所以curl的其他参数就在这里配置即可 文档在 https://guzzle-cn.readthedocs.io/zh_CN/latest/request-optio…

leetcode981. 基于时间的键值存储(treemap)

创建一个基于时间的键值存储类 TimeMap&#xff0c;它支持下面两个操作&#xff1a; set(string key, string value, int timestamp) 存储键 key、值 value&#xff0c;以及给定的时间戳 timestamp。 2. get(string key, int timestamp) 返回先前调用 set(key, value, times…

物联网笔记

转载于: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