1. 程式人生 > >(三)ArcGIS API For Javascript之呼叫動態地圖服務

(三)ArcGIS API For Javascript之呼叫動態地圖服務

1.引言

      在本篇部落格中主要記錄一下在ArcGIS API如何呼叫自己釋出的動態地圖服務,利用動態地圖服務我們可以完成哪一些需求等等。

注:(如何利用ArcGIS Server釋出動態地圖服務請看部落格ArcGIS Server釋出動態地圖服務

2.呼叫動態地圖服務

    在ArcGIS API 中給我們提供了一個類叫做ArcGISDynamicMapServiceLayer利用這個類,我們可以獲得釋出的地圖服務。呼叫動態地圖服務一般只需要兩步:

  • 通過地圖服務的URL建立一個ArcGISDynamicMapServiceLayer物件
  • 將動態地圖服務的物件新增到地圖容器中

程式碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
    <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"/>
    <link rel="stylesheet"
type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />
<script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.17/3.17/init.js"></script> <script> require(["esri/map","esri/layers/ArcGISDynamicMapServiceLayer", "dojo/domReady!"
], function(Map,ArcGISDynamicMapServiceLayer){ var map = new Map("mapDiv"); //利用url建立一個動態地圖服務物件 var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer"); //將地圖服務物件新增到地圖容器中 map.addLayer(layer); })
</script> </head> <body class="tundra"> <div id="mapDiv" style="width:900px; height:600px; border:1px solid #000;"></div> </body> </html>

點選執行,執行之後如圖所示:

這裡寫圖片描述

注:

  • 在ArcGIS API中與ArcMap不同的是:一個服務圖層相當於一組圖層的集合(即多個圖層)。

3.需求

    在真實開發過程中,動態地圖服務可以幫助我們完成很多的功能需求,例如:

  • 根據需求隱藏服務中的某一個圖層(動態地圖服務可以實現,但是切片地圖服務就不能實現)
  • 通過屬性查詢地圖服務中的資訊
  • 通過空間查詢地圖服務中的資訊(包括點查詢,線查詢,面查詢等等)

3.1.根據需求隱藏服務中的某一個圖層

    我們釋出的地圖服務中有四個圖層

這裡寫圖片描述

在本需求中。我們主要是給頁面新增一個按鈕,然後將地圖服務中的road2隱藏
程式碼為:

 require(["esri/map","dojo/dom","dojo/on","esri/layers/ArcGISDynamicMapServiceLayer",
                    "dojo/domReady!"],
                function(Map,dom,on,ArcGISDynamicMapServiceLayer){
                    var map = new Map("mapDiv");
                    var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
                    map.addLayer(layer);
                    //給id為btn的按鈕繫結click事件
                    on(dom.byId("btn"),"click",function()
                    {
                        layer.setVisibleLayers([1,2,3]);
                    })
                })

3.1.1程式碼解釋:

  • 此程式碼功能的實現非常簡單,只利用了setVisibleLayers方法,告訴服務,我要顯示圖層編號為1,2,3的圖層。
  • require中載入了一個新的模組dojo/dom模組,此模組給我們提供了一個方法dom.byId(id),我們可以通過id獲得dom物件,類似於document.getElementById()方法。
  • require中載入了一個新的模組dojo/on模組,在dojo中on是用來繫結事件的,on(target,type,listener)的第一個引數是給哪一個物件繫結事件,第二個引數是事件的型別,第三個是引數是回撥函式。

3.2.通過屬性查詢地圖服務中的資訊

     在開發過程中,經常有這樣的需求:

  • 根據屬性查詢出我們想要的要素圖形,然後將該圖形高亮(在本事例中查詢教學樓的資訊,例如根據教學樓的名稱將該樓層成高亮)

教學樓圖層的屬性表資訊:

這裡寫圖片描述

     在實現這個功能的時候我們分幾步開始考慮:

  1. 在網頁上新建一個文字框
  2. 將文字框中的教學樓名稱獲取,並建立屬性查詢物件
  3. 將查詢到的樓層資訊(幾何資訊)獲取,利用graphics高亮顯示

3.2.1.程式碼實現

  • 建立一個文字框
Name:<input class="nm" type="text">
<input type="button" value="查詢">
  • 將文字框中的教學樓名稱獲取,並建立屬性查詢物件
query("#btn").on("click",function(){
                        //獲得教學樓的名稱
                        var name=query(".nm")[0].value;
                        //例項化查詢引數
                        var findParams = new esri.tasks.FindParameters();
                        findParams.returnGeometry = true;
                        findParams.layerIds = [3];
                        findParams.searchFields = ["name"];
                        findParams.searchText = name;
                        //例項化查詢物件
                        var FindTask = new esri.tasks.FindTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
                        //進行查詢
                        FindTask.execute(findParams,ShowFindResult)
                    })
  • 將查詢到的樓層資訊(幾何資訊)獲取,利用graphics高亮顯示
function showFindResult(queryResult)
                    {
                        if (queryResult.length == 0) {
                            alert("沒有該元素");
                            return;
                        }
                        for (var i = 0; i < queryResult.length; i++) {
                                //獲得該圖形的形狀
                                var graphic = queryResult[i].feature;
                                var geometry = graphic.geometry;
                                //定義高亮圖形的符號
                                //1.定義面的邊界線符號
                                var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
                                //2.定義面符號
                                var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
                                //建立客戶端圖形
                                var graphic = new Graphic(geometry, PolygonSymbol);
                                //將客戶端圖形新增到map中
                                map.graphics.add(graphic);
                        }
                    }                                                           
  • 檢視結果
    屬性查詢前:

這裡寫圖片描述

屬性查詢後:

這裡寫圖片描述

完整程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
    <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"/>
    <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />
    <script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.17/3.17/init.js"></script>
    <script>


        require(["esri/map","dojo/query","dojo/on",
            "esri/layers/ArcGISDynamicMapServiceLayer",
            "esri/tasks/FindTask",
            "esri/tasks/FindParameters",
            "esri/symbols/SimpleLineSymbol",
            "esri/symbols/SimpleFillSymbol",
            "esri/Color",
            "esri/graphic",
            "dojo/domReady!"],
                function(Map,query,on,ArcGISDynamicMapServiceLayer,FindTask,FindParameters,SimpleLineSymbol,SimpleFillSymbol,Color,Graphic){
                    var map = new Map("mapDiv");
                    var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
                    map.addLayer(layer);
                    query("#btn").on("click",function(){
                        //獲得教學樓的名稱
                        var name=query(".nm")[0].value;
                        //例項化查詢引數
                        var findParams = new FindParameters();
                        findParams.returnGeometry = true;
                        findParams.layerIds = [3];
                        findParams.searchFields = ["name"];
                        findParams.searchText = name;
                        //例項化查詢物件
                        var findTask = new FindTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
                        //進行查詢
                        findTask.execute(findParams,showFindResult)
                    });
                    function showFindResult(queryResult)
                    {
                        if (queryResult.length == 0) {
                            alert("沒有該元素");
                            return;
                        }
                        for (var i = 0; i < queryResult.length; i++) {
                                //獲得該圖形的形狀
                                var feature= queryResult[i].feature;
                                var geometry = feature.geometry;
                                //定義高亮圖形的符號
                                //1.定義面的邊界線符號
                                var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
                                //2.定義面符號
                                var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
                                //建立客戶端圖形
                                var graphic = new Graphic(geometry, PolygonSymbol);
                                //將客戶端圖形新增到map中
                                map.graphics.add(graphic);
                        }
                    }



                })
    </script>
</head>
<body class="tundra">
<div id="mapDiv" style="width:900px; height:580px; border:1px solid #000;"></div>
    Name:<input class="nm" type="text">
    <input id="btn" type="button" value="查詢">
</body>
</html>

3.2.2程式碼解釋

  • FindTask 是Esri提供的一個屬性查詢的類,他所對應的引數為:FindParametersFindTask只能用於屬性查詢,不能用於空間查詢
  • FindTask類中有一個方法叫做execute,execute的第一個引數是屬性查詢的引數,第二個引數是一個回撥函式(即是一個非同步函式),當伺服器返回資料時,此函式才會被觸發。
  • dojo/querydojo提供的一個DOM選擇器,他的功能非常強大,與JQuery中的$符一樣強大,可以根據id選擇query("#id"),也可以根據類名選擇query(".classname")query方法還有很多強大的地方,具體可以參考官方文件
  • query("#btn").on()是dojo提供給我們第二種繫結事件的方式。
  • graphicesri提供給我們使用的客戶端圖層,利用graphic,我們可以完成很多操作,graphic具體的使用,將在Draw工具時說明。

3.3通過空間查詢地圖服務中的資訊

    相信大家都遇到過這種問題,當我點選地圖時,將我點選的圖形進行高亮顯示,此時就用到了空間查詢。為了實現該功能我們可以分為以下幾步:

  1. 因為要點選地圖,所以首先我們給地圖繫結點選事件
  2. 獲得點選的地圖座標(點座標),並建立空間查詢引數物件
  3. 將教學樓與點相交的樓層查詢出來,然後利用graphic進行高亮顯示

注:此事例查詢是教學樓圖層

3.3.1程式碼實現

  • 給地圖繫結點選事件
map.on("click",mapClick);
  • 獲得點選的地圖座標(點座標),並建立空間查詢引數物件
function mapClick(e){
                        //獲得使用者點選的地圖座標
                        var point=e.mapPoint;
                        //例項化查詢引數
                        query=new Query();
                        query.geometry = point;
                        query.outFields = ["*"];
                        query.outSpatialReference = map.spatialReference;
                        query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
                        query.returnGeometry = true;
                        //例項化查詢物件
                        var queryTask = new QueryTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer/3");
                        //進行查詢
                        queryTask.execute(query,showFindResult)

                    }
  • 將教學樓與點相交的樓層查詢出來,然後利用graphic進行高亮顯示
function showFindResult(queryResult)
                    {
                        if (queryResult.features == 0) {
                            alert("沒有該元素");
                            return;
                        }
                        for (var i = 0; i < queryResult.features.length; i++) {
                            //獲得該圖形的形狀
                            var feature = queryResult.features[i];
                            var geometry = feature.geometry;
                            //定義高亮圖形的符號
                            //1.定義面的邊界線符號
                            var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
                            //2.定義面符號
                            var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
                            //建立客戶端圖形
                            var graphic = new Graphic(geometry, PolygonSymbol);
                            //將客戶端圖形新增到map中
                            map.graphics.add(graphic);
                        }
                    }
  • 檢視結果
    滑鼠點選前:

這裡寫圖片描述
滑鼠點選後:

這裡寫圖片描述

  • 完整程式碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
    <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"/>
    <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />
    <script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.17/3.17/init.js"></script>
    <script>
        require(["esri/map","dojo/query","dojo/on",
                    "esri/layers/ArcGISDynamicMapServiceLayer",
                    "esri/tasks/QueryTask",
                    "esri/tasks/query",
                    "esri/symbols/SimpleLineSymbol",
                    "esri/symbols/SimpleFillSymbol",
                    "esri/Color",
                    "esri/graphic",
                    "dojo/domReady!"],
                function(Map,query,on,ArcGISDynamicMapServiceLayer,QueryTask,Query,SimpleLineSymbol,SimpleFillSymbol,Color,Graphic){
                    var map = new Map("mapDiv");
                    var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
                    map.addLayer(layer);
                    map.on("click",mapClick);
                    function mapClick(e){
                        //獲得使用者點選的地圖座標
                        var point=e.mapPoint;
                        //例項化查詢引數
                        query=new Query();
                        query.geometry = point;
                        query.outFields = ["*"];
                        query.outSpatialReference = map.spatialReference;
                        query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
                        query.returnGeometry = true;
                        //例項化查詢物件
                        var queryTask = new QueryTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer/3");
                        //進行查詢
                        queryTask.execute(query,showFindResult)

                    }
                    function showFindResult(queryResult)
                    {
                        if (queryResult.features == 0) {
                            alert("沒有該元素");
                            return;
                        }
                        for (var i = 0; i < queryResult.features.length; i++) {
                            //獲得該圖形的形狀
                            var feature = queryResult.features[i];
                            var geometry = feature.geometry;
                            //定義高亮圖形的符號
                            //1.定義面的邊界線符號
                            var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
                            //2.定義面符號
                            var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
                            //建立客戶端圖形
                            var graphic = new Graphic(geometry, PolygonSymbol);
                            //將客戶端圖形新增到map中
                            map.graphics.add(graphic);
                        }
                    }
                })
    </script>
</head>
<body class="tundra">
<div id="mapDiv" style="width:900px; height:580px; border:1px solid #000;"></div>
</body>
</html>

3.3.2程式碼解釋

  • QueryTask是esri提供給我們的一個工具類,可用於屬性查詢,也可用於空間查詢,QueryTask只能作用於地圖服務的某一個圖層,而不能作用於一整個地圖服務(IdentifyTask類可作用於一整個地圖服務)
  • Query類是QueryTask引數類,用於設定空間查詢的引數。
  • QueryTask類中有一個方法叫做execute,execute的第一個引數是查詢的引數,第二個引數是一個回撥函式(即是一個非同步函式),當伺服器返回資料時,此函式才會被觸發

3.4補充

繫結事件之後,在某些情況下也解除事件的繫結,下面提供幾種方法解除事件繫結

  • 直接通過事件控制代碼解除(dojo新版本)
//繫結事件
var handle=map.on("click",mapClick);
//解除事件
handle.remove();
  • 通過老版本的方法解除
//繫結事件
var handle=map.on("click",mapClick);
//解除事件
dojo.disconnect(handle)