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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

點擊運行,運行之後如圖所示:

這裏寫圖片描述

注:

  • 在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]);
                    })
                })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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="查詢">
  • 1
  • 2
  • 1
  • 2
  • 將文本框中的教學樓名稱獲取,並創建屬性查詢對象
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)
                    })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 將查詢到的樓層信息(幾何信息)獲取,利用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);
                        }
                    }                                                           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 查看結果
    屬性查詢前:

這裏寫圖片描述

屬性查詢後:

這裏寫圖片描述

完整代碼:

<!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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

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);
  • 1
  • 1
  • 獲得點擊的地圖座標(點座標),並創建空間查詢參數對象
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)

                    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 將教學樓與點相交的樓層查詢出來,然後利用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);
                        }
                    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 查看結果
    鼠標點擊前:

這裏寫圖片描述
鼠標點擊後:

這裏寫圖片描述

  • 完整代碼
<!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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

3.3.2代碼解釋

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

3.4補充

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

  • 直接通過事件句柄解除(dojo新版本)
//綁定事件
var handle=map.on("click",mapClick);
//解除事件
handle.remove();
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
  • 通過老版本的方法解除

//綁定事件 

var handle=map.on("click",mapClick); 

//解除事件 

dojo.disconnect(handle)
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4



(function () { ('pre.prettyprint code').each(function () {
var lines = (this).text().split(\n).length;var numbering = $('
    ').addClass('pre-numbering').hide();
    (this).addClass(hasnumbering).parent().append( numbering);
    for (i = 1; i <= lines; i++) {
    numbering.append( ('
  • ').text(i));
    };
    $numbering.fadeIn(1700);
    });
    });

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