利用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.pswp.cn/news/393444.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/393444.shtml
英文地址,請注明出處:http://en.pswp.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