选中FeatureLayer元素并高亮显示
Posted wangmengdx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了选中FeatureLayer元素并高亮显示相关的知识,希望对你有一定的参考价值。
点击FeatureLayer要素会弹出popup弹出框以显示要素的相关内容。这个例子实现点击要素,选中并高亮显示。例子使用ArcGIS API for javascript 4.8。
一、代码框架
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <!-- 移动端优化 --> 5 <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> 6 <title>在地图中显示FeatureLayer</title> 7 8 <!-- JS API 引入 --> 9 <link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css"> 10 <script src="https://js.arcgis.com/4.8/"></script> 11 12 <!-- 设置样式 --> 13 <style> 14 html,body,#viewDiv{ 15 margin:0; 16 padding:0; 17 height:100%; 18 width:100%; 19 } 20 </style> 21 22 <!-- JS API 调用代码 --> 23 <script> 24 25 </script> 26 </head> 27 28 <body> 29 <div id="viewDiv"></div> 30 </body> 31 </html>
二、添加FeatureLayer要素图层并进行render、popupTemplate的设置
1 <!-- JS API 调用代码 --> 2 <script> 3 require([ 4 "esri/Map", 5 "esri/views/MapView", 6 "esri/layers/TileLayer", 7 "esri/layers/FeatureLayer", 8 9 "esri/widgets/Legend", 10 11 "dojo/domReady!"],function(Map,MapView,TileLayer,FeatureLayer,Legend){ 12 var mapTileLayer=new TileLayer({ 13 url:"https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer" 14 }); 15 var map=new Map({ 16 layers:[mapTileLayer] 17 }); 18 19 var view=new MapView({ 20 container:"viewDiv", 21 map:map, 22 center:[118.79647, 32.05838], //南京城区 23 zoom:10 24 }); 25 26 //创建FeatureLayer 27 var featureLayer=new FeatureLayer({ 28 url:"https://localhost:6443/arcgis/rest/services/test/南京景点测试/FeatureServer", 29 renderer:{ //符号渲染器 30 type:"unique-value", 31 field:"类别", 32 uniqueValueInfos:[{ 33 value:"历史古迹", 34 symbol:{ 35 type:"simple-marker", 36 color:[115,0,0,0.8], //棕色 37 size:8 38 }, 39 label:"历史古迹" 40 },{ 41 value:"铭记缅怀", 42 symbol:{ 43 type:"simple-marker", 44 color:[36,36,36,0.8], //黑色(一点灰) 45 size:8 46 }, 47 label:"铭记缅怀" 48 },{ 49 value:"科教知识", 50 symbol:{ 51 type:"simple-marker", 52 color:[230,0,0,0.8], //红色 53 size:8 54 }, 55 label:"科教知识" 56 },{ 57 value:"生活玩乐", 58 symbol:{ 59 type:"simple-marker", 60 color:[230,0,169,0.8], //紫色 61 size:8 62 }, 63 label:"生活玩乐" 64 },{ 65 value:"纵情山水", 66 symbol:{ 67 type:"simple-marker", 68 color:[0,169,230,0.8], //蓝色 69 size:8 70 }, 71 label:"纵情山水" 72 },{ 73 value:"公园百态", 74 symbol:{ 75 type:"simple-marker", 76 color:[76,230,0,0.8], //绿色 77 size:8 78 }, 79 label:"公园百态" 80 }] 81 }, //符号渲染器结束 82 popupTemplate:{ //设置popup弹出框 83 title:"<strong>{景点名}</strong>", //HTML元素在title和下面的content中都是可用的 84 content:[{ //以文本方式显示字段值,type可以是:text、fields、media、attachment 85 type:"text", //花括号中写上FeatureLayer的字段名字即可显示出当前要素的这个字段的值 86 text:"地址:{地址}<br>"+"开放时间:{开放时}<br>"+"票价:{票价}<br>"+ 87 "<hr>"+ 88 "所属风景区:{所属风}<br>"+"星级:{星级}<br>"+"类别:{类别}<br>"+"网址:{网址}" 89 }] 90 } //popupTemplate结束 91 }); 92 map.layers.add(featureLayer); 93 94 //添加图例控件 95 var legend=new Legend({ //景点图例 96 view:view, 97 layerInfos:[{ 98 layer:featureLayer, 99 title:"南京景点", 100 style:"classic" //有两个值,classic和card,但是card没反应? 101 }] 102 }); 103 view.ui.add(legend,"bottom-left"); 104 }); 105 </script>
创建了FeatureLayer要素图层并添加到了Map对象上,进行了render、popupTemplate相关内容的设置,添加了图例,关于上面代码的详细内容,请查看:在地图中调用显示FeatureLayer并进行render、popupTemplate、添加图例等相关内容的设置。现在点击地图上的FeatureLayer元素是没有高亮显示的。
三、编写高亮显示的代码(写在<script></script>中添加图例代码的后面)
为视图view添加一个click事件,当点击view时将触发后面的匿名函数,函数有一个click事件返回的参数event,event中包含点击的相关信息。执行函数,弹出提示框,输出“click!”。
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 alert("click!"); 4 });
下面alert输出这个参数event。
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 alert(event); 4 });
弹出的是object Object,看不出什么内容。
改成console.log()控制台打印输出。
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 console.log(event); 4 });
分别用鼠标左键、中键、右键点击view,在Console控制台中输出相关内容。其中,左键、中键、右键输出的button属性值分别是0、1、2。(这里包括下文中,用Chrome和FireFox控制台显示的内容不完全一样,Chrome显示的内容更有用些。例子使用Chrome。)
展开一个记录,查看详细内容。可以看到点击处的经度、纬度以及在屏幕上的坐标等信息。
在view.on()中,为view添加hitTest测试,传入event,返回response并调用匿名函数,执行console.log(response),在控制台打印输出response对象。
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 view.hitTest(event).then(function(response){ 4 console.log(response); 5 }); 6 });
在view上点击,分别点击空白处和FeatureLayer要素。上面一条记录中,results的数组length长度是0,表示没有点击到FeatureLayer要素;而下方记录中,results数组长度为1,且可以查看results[0]的详细内容,表示点击到了FeatureLayer要素。
我们展开查看results[0]的详细内容。可以看到,其中包含了很多有用的信息,包括results[0].graphic.attributes中FeatureLayer相关字段值、results[0].graphic.geometry中经纬度的信息等。要留意这些信息并注意层级关系,编写代码时会用到。(这些内容在FireFox浏览器中是看不到的..)
在view.hitTest里进行是否点击到FeatureLayer要素的判断。判断条件有两个:①response.results.length是否大于0(即是否等于1) ②response.results[0].graphic是否存在。根据刚才Console控制台输出的信息,可以看到这样判断的依据。
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 view.hitTest(event).then(function(response){ 4 if(response.results.length>0&&response.results[0].graphic){ 5 console.log("点击到了FeatureLayer的要素!"); 6 } 7 else{ 8 console.log("没有点击FeatureLayer要素.."); 9 } 10 }); 11 });
在view中我们分别点击空白处和FeatureLayer要素。
在判断完确实点击到FeatureLayer要素后,将这个要素的id值传给selectFeature()函数(稍后定义),在这个函数内进行高亮显示的编写。传入的要素id值是一长串,可以和下面这张图对照着看,注意看层级关系。也可以按照注释掉的部分写,那样可能更清楚点。如果在控制台中查看到FeatureLayer并不包含objectid这个字段(我不知道这种情况会不会发生),可以这样写,起到的效果是一样的:selectFeature(response.results[0].graphic.attributes[featureLayer.objectIdField])。其中,featureLayer是FeatureLayer要素图层的名字,是自己起的,而objectIdField是FeatureLayer的一个属性名字。
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 view.hitTest(event).then(function(response){ 4 if(response.results.length>0&&response.results[0].graphic){ 5 //var feature=response.results[0].graphic; 6 //selectFeature(feature.attributes["objectid"]); 7 selectFeature(response.results[0].graphic.attributes["objectid"]); 8 } 9 }); 10 });
下面进行selectFeature()的编写。
selectionSymbol就是高亮显示的符号。
1 function selectFeature(objectid){ 2 var selectionSymbol={ 3 type:"simple-marker", 4 color:"#FFFF00", 5 size:10, 6 outline:{ 7 color:"#E69800", 8 width:2 9 } 10 }; 11 };
为FeatureLayer创建一个查询(query),并将查询条件(query.where)设置成FeatureLayer中要素的id值等于传入的那个id值(即在view中点击到的那个要素的id值)。
1 function selectFeature(objectid){ 2 var selectionSymbol={ 3 type:"simple-marker", 4 color:"#FFFF00", 5 size:10, 6 outline:{ 7 color:"#E69800", 8 width:2 9 } 10 }; 11 12 var query=featureLayer.createQuery(); 13 query.where=featureLayer.objectIdField+"="+objectid; 14 };
执行FeatureLayer的queryFeatures查询,传入刚才定义的query对象(里面包含查询条件)。查询成功后执行匿名函数(带有参数results),打印输出results对象的相关信息。
1 function selectFeature(objectid){ 2 var selectionSymbol={ 3 type:"simple-marker", 4 color:"#FFFF00", 5 size:10, 6 outline:{ 7 color:"#E69800", 8 width:2 9 } 10 }; 11 12 var query=featureLayer.createQuery(); 13 query.where=featureLayer.objectIdField+"="+objectid; 14 15 featureLayer.queryFeatures(query).then(function(results){ 16 console.log(results); 17 }); 18 };
在chrome中可以看到,results对象也包含了一些内容,但和之前view.hitTest那边的response对象的内容是不同的。不过也包含attributes、geometry等一些重要的内容。
在queryFeatures().then()的匿名函数中,进行是否点击到要素的判断后,将results.features[0]赋给lightFeature变量,lightFeature对象现在就包含点击到的那个要素的相关信息(attributes、geometry、经纬度信息等),将之前定义的符号赋值给lightFeature的symbol属性。最后view.graphics.add(lightFeature)将lightFeature以graphics的形式按照lightFeature中包含的经纬度信息绘制到view上。
1 function selectFeature(objectid){ 2 var selectionSymbol={ 3 type:"simple-marker", 4 color:"#FFFF00", 5 size:10, 6 outline:{ 7 color:"#E69800", 8 width:2 9 } 10 }; 11 12 var query=featureLayer.createQuery(); 13 query.where=featureLayer.objectIdField+"="+objectid; 14 15 featureLayer.queryFeatures(query).then(function(results){ 16 if(results.features.length>0){ 17 var lightFeature=results.features[0]; 18 lightFeature.symbol=selectionSymbol; 19 view.graphics.add(lightFeature); 20 } 21 }); 22 };
查看高亮显示的结果:
可以看到,点击到的要素已经被高亮显示出来,但是如果点击多个要素,之前高亮显示的要素并没有去除,下面在view.on()中的开头添加一行代码以解决这个问题。当每次点击到view,不管有没有点击到FeatureLayer的要素,都会执行去除view上所有graphics的操作。
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 view.graphics.removeAll(); //去除view中所有graphics 4 5 view.hitTest(event).then(function(response){ 6 if(response.results.length>0&&response.results[0].graphic){ 7 //var feature=response.results[0].graphic; 8 //selectFeature(feature.attributes["objectid"]); 9 selectFeature(response.results[0].graphic.attributes["objectid"]); 10 } 11 }); 12 });
最终高亮显示的代码:
1 //选中要素,高亮显示 2 view.on("click",function(event){ 3 view.graphics.removeAll(); //去除view中所有graphics 4 5 view.hitTest(event).then(function(response){ 6 if(response.results.length>0&&response.results[0].graphic){ 7 //var feature=response.results[0].graphic; 8 //selectFeature(feature.attributes["objectid"]); 9 selectFeature(response.results[0].graphic.attributes["objectid"]); 10 } 11 }); 12 }); 13 function selectFeature(objectid){ 14 var selectionSymbol={ 15 type:"simple-marker", 16 color:"#FFFF00", 17 size:10, 18 outline:{ 19 color:"#E69800", 20 width:2 21 } 22 }; 23 24 var query=featureLayer.createQuery(); 25 query.where=featureLayer.objectIdField+"="+objectid; 26 27 featureLayer.queryFeatures(query).then(function(results){ 28 if(results.features.length>0){ 29 var lightFeature=results.features[0]; 30 lightFeature.symbol=selectionSymbol; 31 view.graphics.add(lightFeature); 32 } 33 }); 34 };
全部代码:
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <!-- 移动端优化 --> 5 <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> 6 <title>在地图中显示FeatureLayer</title> 7 8 <!-- JS API 引入 --> 9 <link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css"> 10 <script src="https://js.arcgis.com/4.8/"></script> 11 12 <!-- 设置样式 --> 13 <style> 14 html,body,#viewDiv{ 15 margin:0; 16 padding:0; 17 height:100%; 18 width:100%; 19 } 20 </style> 21 22 <!-- JS API 调用代码 --> 23 <script> 24 require([ 25 "esri/Map", 26 "esri/views/MapView", 27 "esri/layers/TileLayer", 28 "esri/layers/FeatureLayer", 29 30 "esri/widgets/Legend", 31 32 "dojo/domReady!"],function(Map,MapView,TileLayer,FeatureLayer,Legend){ 33 var mapTileLayer=new TileLayer({ 34 url:"https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer" 35 }); 36 var map=new Map({ 37 layers:[mapTileLayer] 38 }); 39 40 var view=new MapView({ 41 container:"viewDiv", 42 map:map, 43 center:[118.79647, 32.05838], //南京城区 44 zoom:10 45 }); 46 47 //创建FeatureLayer 48 var featureLayer=new FeatureLayer({ 49 url:"https://localhost:6443/arcgis/rest/services/test/南京景点测试/FeatureServer", 50 renderer:{ //符号渲染器 51 type:"unique-value", 52 field:"类别", 53 uniqueValueInfos:[{ 54 value:"历史古迹", 55 symbol:{ 56 type:"simple-marker", 57 color:[115,0,0,0.8], //棕色 58 size:8 59 }, 60 label:"历史古迹" 61 },{ 62 value:"铭记缅怀", 63 symbol:{ 64 type:"simple-marker", 65 color:[36,36,36,0.8], //黑色(一点灰) 66 size:8 67 }, 68 label:"铭记缅怀" 69 },{ 70 value:"科教知识", 71 symbol:{ 72 type:"simple-marker", 73 color:[230,0,0,0.8], //红色 74 size:8 75 }, 76 label:"科教知识" 77 },{ 78 value:"生活玩乐", 79 symbol:{ 80 type:"simple-marker", 81 color:[230,0,169,0.8], //紫色 82 size:8 83 }, 84 label:"生活玩乐" 85 },{ 86 value:"纵情山水", 87 symbol:{ 88 type:"simple-marker", 89 color:[0,169,230,0.8], //蓝色 90 size:8 91 }, 92 label:"纵情山水" 93 },{ 94 value:"公园百态", 95 symbol:{ 96 type:"simple-marker", 97 color:[76,230,0,0.8], //绿色 98 size:8 99 }, 100 label:"公园百态" 101 }] 102 }, //符号渲染器结束 103 popupTemplate:{ //设置popup弹出框 104 title:"<strong>{景点名}</strong>", //HTML元素在title和下面的content中都是可用的 105 content:[{ //以文本方式显示字段值,type可以是:text、fields、media、attachment 106 type:"text", //花括号中写上FeatureLayer的字段名字即可显示出当前要素的这个字段的值 107 text:"地址:{地址}<br>"+"开放时间:{开放时}<br>"+"票价:{票价}<br>"+ 108 "<hr>"+ 109 "所属风景区:{所属风}<br>"+"星级:{星级}<br>"+"类别:{类别}<br>"+"网址:{网址}" 110 }] 111 } //popupTemplate结束 112 }); 113 map.layers.add(featureLayer); 114 115 //添加图例控件 116 var legend=new Legend({ //景点图例 117 view:view, 118 layerInfos:[{ 119 layer:featureLayer, 120 title:"南京景点", 121 style:"classic" //有两个值,classic和card,但是card没反应? 122 }] 123 }); 124 view.ui.add(legend,"bottom-left"); 125 126 //选中要素,高亮显示 127 view.on("click",function(event){ 128 view.graphics.removeAll(); //去除view中所有graphics 129 130 view.hitTest(event).then(function(response){ 131 if(response.results.length>0&&response.results[0].graphic){ 132 //var feature=response.results[0].graphic; 133 //selectFeature(feature.attributes["objectid"]); 134 selectFeature(response.results[0].graphic.attributes["objectid"]); 135 } 136 }); 137 }); 138 function selectFeature(objectid){ 139 var selectionSymbol={ 140 type:"simple-marker", 141 color:"#FFFF00", 142 size:10, 143 outline:{ 144 color:"#E69800", 145 width:2 146 } 147 }; 148 149 var query=featureLayer.createQuery(); 150 query.where=featureLayer.objectIdField+"="+objectid; 151 152 featureLayer.queryFeatures(query).then(function(results){ 153 if(results.features.length>0){ 154 var lightFeature=results.features[0]; 155 lightFeature.symbol=selectionSymbol; 156 view.graphics.add(lightFeature); 157 } 158 }); 159 }; 160 }); 161 </script> 162 </head> 163 164 <body> 165 <div id="viewDiv"></div> 166 </body> 167 </html>
例子使用的链接分享:https://pan.baidu.com/s/1fnyu0OjWx9FUvUs1BGvz3g
因为这个例子中ArcGIS Server发布的是本地服务,所以在别的电脑上无法访问例子中FeatureLayer的url,可以自己发布一个服务再进行尝试。
以上是关于选中FeatureLayer元素并高亮显示的主要内容,如果未能解决你的问题,请参考以下文章
Emacs如何在当前verilog文件中根据选中的文本快速查找并高亮显示