Arcgis api for javascript學習筆記(4.5版本) - 點擊多邊形(Polygon)並高亮顯示

在現在的 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章