在現在的 arcgis_js_v45_api 版本中並沒有直接提供點擊Polygon對象高亮顯示。需要實現如下幾個步驟:
1.點擊地圖時,獲取Polygon的Graphic對象;
2.對獲取到的Graphic對象進行高亮顯示和移出高亮顯示;
1. 點擊地圖時,獲取當前點擊的Polygon的Graphic對象
在4.x版本中可以通過 view.on("click", function (event) { }); 結合 view.hitTest(event).then(function (response) { }); 來獲取點擊的Graphic對象。但是這種實現方式只能在以下兩種情況下才能獲取到。
Ⅰ. 在二維地圖(MapView)中,無論是Point還是Polygon,都可以獲取到他們對應的Graphic對象;
Ⅱ. 在三維地圖(SceneView)中,只能獲取到 Point 的Graphic對象,而 Polygon 的Graphic對象沒有辦法獲取到;
所以個人的實現思路:獲取當前鼠標點擊的位置,循環多邊形,判斷點是否在該多邊形內。考慮到多邊形rings比較多,所以先在判斷點是否在多邊形的外界矩形內部。
2. Graphic對象高亮顯示與移除
方案1:在官方文檔中有提供高亮顯示的功能,https://developers.arcgis.com/javascript/latest/api-reference/esri-views-layers-FeatureLayerView.html#highlight;
方案2:新增一個同樣位置的Graphic對象,初始化時設置高亮的symbol。經過本人測試,直接修改 Graphic 對象的 symbol 屬性,是無法達到預期的效果。因爲儘管修改 symbol 屬性,Graphic 在地圖中的樣式並不會發生改變;
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> <title>Intro to SceneView - Create a 3D map</title> <style type="text/css"> html, body, #viewDiv { height: 100%; width: 100%; } </style> <!--<script type="text/javascript">--> <!--dojoConfig = {--> <!--async: true, //dojo核心示範異步加載--> <!--baseUrl: "http://localhost:8001/arcgis_js_v45_api/dojo",--> <!--packages: [{--> <!--name: "extends",--> <!--location: location.pathname.replace(/\/[^/]+$/, "")--> <!--}],--> <!--waitSeconds: 5, //加載模塊的請求響應時間--> <!--cacheBust: false, //是否清空模塊緩存(原理就是在請求模塊的URL加上當前時間戳)--> <!--locale: location.search.match(/locale=([\w\-]+)/) ? RegExp.$1 : "en-us"--> <!--};--> <!--</script>--> <!--<script type="text/javascript" src="jquery-1.8.0.min.js"></script>--> <!--<link rel="stylesheet" href="http://127.0.0.1:8001/arcgis_js_v45_api/esri/css/main.css">--> <!--<script type="text/javascript" src="http://127.0.0.1:8001/arcgis_js_v45_api/init.js"></script>--> <script type="text/javascript" src="jquery-1.8.0.min.js"></script> <link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css"> <script src="https://js.arcgis.com/4.5/"></script> <script> require([ "esri/config", "esri/Map", "esri/views/SceneView", "esri/Graphic", "extends/GraphicLayerEx", "dojo/domReady!" ], function (esriConfig, Map, SceneView, Graphic, GraphicLayerEx) { esriConfig.request.proxyUrl = "http://127.0.0.1:8002/proxy.ashx"; esriConfig.request.corsDetection = true; var map = new Map({ "basemap": "hybrid", "ground": "world-elevation" }); var view = new SceneView({ "map": map, "container": "viewDiv" }); var polygonLayer = new GraphicLayerEx(); map.layers.add(polygonLayer); view.then(function () { jQuery.getJSON("data.json", function (data) { for(var i = 0; i < data.length; i++){ var item = data[i]; console.info(item); var polygonGraphic = new Graphic({ "geometry": { "type": "polygon", "rings": item }, "symbol": { "width": 2, "type": "simple-line", "color": [255, 255, 255] } }); polygonLayer.graphics.add(polygonGraphic); } }); var highlightPolygon; view.on("click", function (event) { if(highlightPolygon){ highlightPolygon.remove(); } console.info(event) view.hitTest(event).then(function (response) { var g_move = polygonLayer.getInsidePolygon({ y: response.results[0].mapPoint.latitude, x: response.results[0].mapPoint.longitude }); if (g_move) { view.whenLayerView(polygonLayer).then(function (lyrView) { highlightPolygon = lyrView.highlight(g_move); }); } }); }); }); }); </script> </head> <body> <div id="viewDiv"></div> </body> </html>
GraphicLayerEx.js (GraphicLayer擴展,獲取點坐落所在多邊形polygon)
define([ "esri/core/declare", "esri/layers/GraphicsLayer" ], function (declare, GraphicsLayer) { return declare([GraphicsLayer], { /** * @description 獲取點坐落所在多邊形polygon * @param {Object} pt 待判斷的點,格式:{ x: X座標, y: Y座標 } * @return {Object} 多邊形graphic對象 */ "getInsidePolygon": function (pt) { for (var k = 0; k < this.graphics.length; k++) { var g = this.graphics.items[k]; if (g.geometry.type !== "polygon") { continue; } var rings = g.geometry.rings[0]; var gExtent = g.geometry.extent; if( pt.x > gExtent.xmin && pt.x < gExtent.xmax && pt.y > gExtent.ymin && pt.y < gExtent.ymax){ //如果在多邊形外界矩形,再詳細判斷是否在多邊形內部 var flag = false; for (var i = 0, l = rings.length, j = l - 1; i < l; j = i, i++) { var sx = rings[i][0], sy = rings[i][1], tx = rings[j][0], ty = rings[j][1]; // 點與多邊形頂點重合 if ((sx === pt.x && sy === pt.y) || (tx === pt.x && ty === pt.y)) { return g; } // 判斷線段兩端點是否在射線兩側 if ((sy < pt.y && ty >= pt.y) || (sy >= pt.y && ty < pt.y)) { // 線段上與射線 Y 座標相同的點的 X 座標 var x = sx + (pt.y - sy) * (tx - sx) / (ty - sy); // 點在多邊形的邊上 if (x === pt.x) { return g; } // 射線穿過多邊形的邊界 if (x > pt.x) { flag = !flag; } } } //射線穿過多邊形邊界的次數爲奇數時點在多邊形內 if(flag){ return g; } } } return null; } }); });
data.json(模擬數據)
[ [ [81.99385,41.423614], [84.311909,41.062564], [82.214617,38.363399], [81.99385,41.423614] ], [ [82.251412,35.166954], [88.138547,35.348045], [85.489336,31.239761], [82.251412,35.166954] ], [ [90.934936,38.218397], [92.958639,33.05534], [98.220266,35.918797], [90.934936,38.218397] ], [ [98.514622,32.620448], [101.016655,27.829668], [103.70266,32.277243], [98.514622,32.620448] ], [ [112.386184,32.744923], [117.095892,31.681338], [115.256162,26.579477], [112.386184,32.744923] ] ]
效果圖:
源碼下載地址: https://download.csdn.net/download/tracine0513/10339435