1.引言
在ArcGIS API中有一種圖層叫做GraphicsLayer
,GraphicsLayer
是一種客戶端圖層,GraphicsLayer
中的圖形我們稱作Graphic
,它對應着esri/graphic
,一個Graphic
對象由四部分組成:geometry
,symbol
,attribute
,infoTemplate
組成,Graphic
對象在我們開發中用到的非常多。例如:利用Graphic
實現圖形的高亮顯示等等。
2.需求
在我們開發當中,關於Graphic
的使用非常多,我們可以利用Graphic
實現各種各樣的功能。接下來我們根據一些需求來完成相應的功能。
2.1.根據具體坐標生成Graphic
- 在我們的實際開發當中可能會存在這樣的需求:根據坐標以及形狀生成相應的圖形然后在地圖顯示出來
在上面說過一個Graphic
由四部分組成,在需求中我們已經知道坐標形狀,即已經知道了geometry
,因此我們可以直接根據坐標生成相應的geometry
,從而創建Graphic
,然后添加到地圖中來。
2.1.1代碼實現
- 我們首先創建一個html頁面,引入相應的文件將地圖加載進來
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Graphic</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> <style> .MapClass{ width:100%; height:500px; border:1px solid #000; } </style> <script> require(["esri/map","esri/layers/ArcGISDynamicMapServiceLayer", "dojo/domReady!"],function(Map,ArcGISDynamicMapServiceLayer){ var map = new Map("mapDiv"); var layer = new ArcGISDynamicMapServiceLayer ("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"); map.addLayer(layer); }) </script> </head> <body> <div id="mapDiv" class="MapClass"></div> </body> </html>
- 創建四個按鈕,將四類不同的
Graphic
添加到GraphicsLayer
中
<button>添加點</button> <button>添加線</button> <button>添加面</button> <button>添加圓</button>
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
-
引入相應的模塊,其中包括:
dojo/on
(用於綁定事件的模塊)esri/symbols/SimpleMarkerSymbol
(點符號類)esri/symbols/SimpleLineSymbol
(線符號類)esri/symbols/SimpleFillSymbol
(面符號類)esri/geometry/Point
(點類)esri/geometry/Polyline
(折線類)esri/geometry/Polygon
(面類)esri/geometry/Circle
(圓類)dojo/query
(dojo的選擇器,用於選擇DOM元素)esri/graphic
(圖形類)esri/layers/GraphicsLayer
(客戶端圖層類) -
為相應的按鈕添加綁定事件
//創建客戶端圖層 var graphicsLayer=new GraphicsLayer(); //將客戶端圖層添加到地圖中 map.addLayer(graphicsLayer); //通過query查詢到button對象 var btns=query("button"); on(btns,"click",function(event){ //獲得按鈕的文本 var text=this.innerHTML; //定義線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new Color([255, 0, 0]), 3); //定義點符號l var pSymbol=new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,10, lineSymbol, new Color([255, 0, 0])); //定義面符號 var fill=SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol, new Color([255, 0, 0])); //聲明一個類型和圖形 var geometry; var graphic; //根據文本定義相應的geometry switch(text) { case "添加點": geometry=new Point({ "x":510706, "y":3986100, "spatialReference":map.spatialReference }); graphic=new Graphic(geometry,pSymbol); break; case "添加線": //點的坐標對 var paths=[]; paths[0]=[ [510326,3985702], [510994, 3985676], [511078, 3985903], [510433, 3985928] ]; geometry=new Polyline({ "paths":paths, "spatialReference":map.spatialReference }) graphic=new Graphic(geometry,lineSymbol); break; case "添加面": //點的坐標對 var ring=[]; ring[0]=[ [510275, 3986100], [510508, 3986162], [510596, 3986032], [510271, 3985847], [510275, 3986100] ]; geometry=new Polygon({ "rings":ring, "spatialReference":map.spatialReference }); graphic=new Graphic(geometry,fill); break; case "添加圓": //圓心 var p=new Point({ "x":510706, "y":3986100, "spatialReference":map.spatialReference }); //半徑 var r=20; geometry=new Circle(p,{ "radius":r }); graphic=new Graphic(geometry,fill); break; } //將圖形添加到圖層中 graphicsLayer.add(graphic);
- 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
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
2.1.2全部代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Graphic</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> <style> .MapClass{ width:100%; height:500px; border:1px solid #000; } </style> <script> require(["esri/map","esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/GraphicsLayer", "dojo/on","dojo/query","dojo/colors", "esri/graphic","esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/geometry/Point", "esri/geometry/Polyline","esri/geometry/Polygon", "esri/geometry/Circle", "dojo/domReady!"], function(Map,ArcGISDynamicMapServiceLayer, GraphicsLayer,on,query,Color,Graphic, SimpleMarkerSymbol,SimpleLineSymbol, SimpleFillSymbol,Point,Polyline,Polygon,Circle){ var map = new Map("mapDiv"); var layer = new ArcGISDynamicMapServiceLayer ("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"); map.addLayer(layer); //創建客戶端圖層 var graphicsLayer=new GraphicsLayer(); //將客戶端圖層添加到地圖中 map.addLayer(graphicsLayer); //通過query查詢到button對象 var btns=query("button"); on(btns,"click",function(event){ //獲得按鈕的文本 var text=this.innerHTML; //定義線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new Color([255, 0, 0]), 3); //定義點符號l var pSymbol=new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,10, lineSymbol, new Color([255, 0, 0])); //定義面符號 var fill=SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol, new Color([255, 0, 0])); //聲明一個類型和圖形 var geometry; var graphic; //根據文本定義相應的geometry switch(text) { case "添加點": geometry=new Point({ "x":510706, "y":3986100, "spatialReference":map.spatialReference }); graphic=new Graphic(geometry,pSymbol); break; case "添加線": //點的坐標對 var paths=[]; paths[0]=[ [510326,3985702], [510994, 3985676], [511078, 3985903], [510433, 3985928] ]; geometry=new Polyline({ "paths":paths, "spatialReference":map.spatialReference }) graphic=new Graphic(geometry,lineSymbol); break; case "添加面": //點的坐標對 var ring=[]; ring[0]=[ [510275, 3986100], [510508, 3986162], [510596, 3986032], [510271, 3985847], [510275, 3986100] ]; geometry=new Polygon({ "rings":ring, "spatialReference":map.spatialReference }); graphic=new Graphic(geometry,fill); break; case "添加圓": //圓心 var p=new Point({ "x":510706, "y":3986100, "spatialReference":map.spatialReference }); //半徑 var r=20; geometry=new Circle(p,{ "radius":r }); graphic=new Graphic(geometry,fill); break; } //將圖形添加到圖層中 graphicsLayer.add(graphic); }) }) </script> </head> <body> <div id="mapDiv" class="MapClass"></div> <button>添加點</button> <button>添加線</button> <button>添加面</button> <button>添加圓</button> </body> </html>
2.1.3代碼解釋
- 我們利用
dojo/query
查詢到所有的button
對象,利用dojo/on
模塊給所有的button
對象綁定事件。 - 在此例子中,有一個缺點:便是將點的坐標寫死了,因此我們可以將點的坐標存放在一個json文件中,從而讀取文件生成相應的點坐標
2.2.GraphicsLayer的屬性查詢
在前面我們提到過,Graphic
是可以存在屬性的,在實際開發當中,有時我們需要將相應的屬性查詢出來,在此時我提供一個簡單的方法,便是根據 GraphicsLayer的點擊事件來查詢Graphic
的屬性。
2.2.1代碼實現
- 首先我們添加一系列帶有屬性的
Graphic
(此處我們只用點圖形便可以)
//創建客戶端圖層 var graphicsLayer=new GraphicsLayer(); //將客戶端圖層添加到地圖中 map.addLayer(graphicsLayer); //添加點圖形的函數 function addGraphic() { //定義線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new Color([255, 0, 0]), 3); //定義點符號l var pSymbol=new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,10, lineSymbol, new Color([255, 0, 0])); //聲明形狀 var geometry; //聲明和圖形 var graphic; //添加第一個點圖形 geometry=new Point({ "x":510706, "y":3986100, "spatialReference":map.spatialReference, attributes:{ "h":100 } }); graphic=new Graphic(geometry,pSymbol); graphicsLayer.add(graphic); //添加第二個點圖形 geometry=new Point({ "x":510326, "y":3985702, "spatialReference":map.spatialReference, attributes:{ "h":200 } }); graphic=new Graphic(geometry,pSymbol); graphicsLayer.add(graphic); //添加第三個點圖形 geometry=new Point({ "x":510275, "y":3986100, "spatialReference":map.spatialReference, attributes:{ "h":300 } }); graphic=new Graphic(geometry,pSymbol); graphicsLayer.add(graphic); } //調用添加點圖形的函數 addGraphic();
- 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
- 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
- 給
GraphicsLayer
綁定相應的事件
//綁定事件 on(graphicsLayer,"click",function(event){ var graphic=event.graphic; alert(graphic.attributes["h"]); })
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
2.2.2全部代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Graphic</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> <style> .MapClass{ width:100%; height:500px; border:1px solid #000; } </style> <script> require(["esri/map","esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/GraphicsLayer", "dojo/on","dojo/query","dojo/colors", "esri/graphic","esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/geometry/Point", "dojo/domReady!"], function(Map,ArcGISDynamicMapServiceLayer, GraphicsLayer,on,query,Color,Graphic, SimpleMarkerSymbol,SimpleLineSymbol,Point){ var map = new Map("mapDiv"); var layer = new ArcGISDynamicMapServiceLayer ("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"); map.addLayer(layer); //創建客戶端圖層 var graphicsLayer=new GraphicsLayer(); //將客戶端圖層添加到地圖中 map.addLayer(graphicsLayer); //添加點圖形的函數 function addGraphic() { //定義線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new Color([255, 0, 0]), 3); //定義點符號l var pSymbol=new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,10, lineSymbol, new Color([255, 0, 0])); //聲明形狀 var geometry; //聲明和圖形 var graphic; //添加第一個點圖形 geometry=new Point({ "x":510706, "y":3986100, "spatialReference":map.spatialReference, }); graphic=new Graphic(geometry,pSymbol,{"h":100}); graphicsLayer.add(graphic); //添加第二個點圖形 geometry=new Point({ "x":510326, "y":3985702, "spatialReference":map.spatialReference }); graphic=new Graphic(geometry,pSymbol,{"h":200}); graphicsLayer.add(graphic); //添加第三個點圖形 geometry=new Point({ "x":510275, "y":3986100, "spatialReference":map.spatialReference }); graphic=new Graphic(geometry,pSymbol,{"h":300}); graphicsLayer.add(graphic); } //調用添加點圖形的函數 addGraphic(); //綁定事件 on(graphicsLayer,"click",function(event){ var graphic=event.graphic; alert(graphic.attributes["h"]); }) }) </script> </head> <body> <div id="mapDiv" class="MapClass"></div> </body> </html>
2.2.3代碼解釋
- 需要注意的是
graphicsLayer
的事件機制是針對於graphic
圖形的,也就是當圖形graphic
被點擊時被觸發,此時回調函數也會將哪個圖形被點擊傳給我們,從而得到圖形的屬性 - 有的同學不太喜歡新建一個
graphicsLayer
,而是使用map.graphics.add()
方法添加一個圖形graphic
,其實原理是一樣的,因為map
本身有一個默認的graphicsLayer
即:map.graphics
返回的便是一個graphicsLayer
對象 - 在此代碼當中我們只是將獲得到的屬性信息
alert
了一下,在真實需求當中我們可能會利用相應的屬性信息做很多的事情。
2.3.實現用戶交互畫圖(Draw工具)
在部分項目中,有這么一個需求:讓用戶在地圖上自己繪制一個圖形,然后將圖形添加到地圖當中,要實現這個功能我們需要借助esri
提供給我們的工具條實現:esri/toolbars/draw
,利用該工具條我們可以得到用戶交互畫出來的geometry
,從而根據geometry
生成相應的graphic
,使用該工具的一般步驟為:
- 創建繪圖對象
- 激活繪圖工具
- 得到圖形Geometry
- 創建Graphic
- 添加到地圖
2.3.1代碼實現
- 創建5個
button
(和第一個例子一樣) - 創建繪圖對象
var toolbar = new Draw(map, { showTooltips: true });
- 1
- 1
- 給每一個
button
綁定相應的事件(激活繪圖工具)
query("button").on("click",function(event){ var value=this.innerHTML; switch(value){ case "繪制點":{ //激活繪圖工具(畫點) toolbar.activate(Draw.POINT, { showTooltips:true }) break; } case "繪制折線":{ //激活繪圖工具(畫折線) toolbar.activate(Draw.POLYLINE, { showTooltips:true }) break; } case "繪制面":{ //激活繪圖工具(繪制面) toolbar.activate(Draw.POLYGON, { showTooltips:true }) break; } case "徒手線":{ //激活繪圖工具(徒手線) toolbar.activate(Draw.FREEHAND_POLYLINE, { showTooltips:true }) break; } case "徒手面":{ //激活繪圖工具(徒手面) toolbar.activate(Draw.FREEHAND_POLYGON, { showTooltips:true }) break; } } });
- 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
- 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
- 給繪圖工具綁定繪圖完成事件
on(toolbar,"draw-complete", function (result) { //獲得幾何形狀 var geometry=result.geometry; //獲得形狀的類型 var type=geometry.type; //聲明圖形對象 var graphic; //通過幾何形狀的類型,創建不同的圖形 switch (type) { case "point": graphic= new Graphic(geometry, marker); break; case "polyline": graphic= new Graphic(geometry, lineSymbol); break; case "polygon": graphic= new Graphic(geometry, fill); break; } map.graphics.add(graphic); //關掉繪圖工具 toolbar.deactivate(); });
2.3.2全部代碼
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>WebGIS</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> <style type="text/css"> .MapClass{ width:100%; height:500px; border:1px solid #000; } </style> <script type="text/javascript"> require(["esri/map","dojo/dom","dojo/on", "esri/layers/ArcGISDynamicMapServiceLayer", "dojo/query","esri/toolbars/draw", "esri/symbols/SimpleLineSymbol","esri/graphic","esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleFillSymbol","dojo/domReady!"], function (Map,dom,on, ArcGISDynamicMapServiceLayer,query, Draw, SimpleLineSymbol,Graphic,SimpleMarkerSymbol,SimpleFillSymbol) { var map = new esri.Map("MyMapDiv"); var layer = new ArcGISDynamicMapServiceLayer ("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"); map.addLayer(layer) var toolbar = new Draw(map, { showTooltips: true }); var lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 3); var marker= new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,10, lineSymbol, new dojo.Color([255, 0, 0])); var fill= new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol, new dojo.Color([255, 0, 0])); on(toolbar,"draw-complete", function (result) { var geometry=result.geometry; var type=geometry.type; var graphic; switch (type) { case "point": graphic= new Graphic(geometry, marker); break; case "polyline": graphic= new Graphic(geometry, lineSymbol); break; case "polygon": graphic= new Graphic(geometry, fill); break; } map.graphics.add(graphic); toolbar.deactivate(); }); query("button").on("click",function(event){ var value=this.innerHTML; switch(value){ case "繪制點":{ toolbar.activate(Draw.POINT, { showTooltips:true }) break; } case "繪制折線":{ toolbar.activate(Draw.POLYLINE, { showTooltips:true }) break; } case "繪制面":{ toolbar.activate(Draw.POLYGON, { showTooltips:true }) break; } case "徒手線":{ toolbar.activate(Draw.FREEHAND_POLYLINE, { showTooltips:true }) break; } case "徒手面":{ toolbar.activate(Draw.FREEHAND_POLYGON, { showTooltips:true }) break; } } }); }); </script> </head> <body> <div id="MyMapDiv" class="MapClass"></div> <button>繪制點</button> <button>繪制折線</button> <button>繪制面</button> <button>徒手線</button> <button>徒手面</button> </body> </html>
2.3.3代碼解釋
- 在使用繪圖工具時,最主要的不同為:在激活繪圖工具時的賦予的參數的不同。
graphic
只是客戶端圖形,並不改變服務本身,如果想要改變服務本身的數據,需要使用要素服務,用到esri/toolbars/Edit
工具。
3.總結
通過上面幾個需求得知,在生成graphic
時,最主要是有用這個圖形的幾何信息,幾何信息可以通過多方面獲得,例如:
- 通過具體的坐標生成
geometry
(實現) - 通過draw工具動態獲得
geometry
(實現) - 我們還可以通過map的點擊事件獲得點的
geometry
(可以嘗試自己實現)。
一旦擁有了圖形的幾何信息,我們就可以直接創建graphic
,從而添加到地圖中來。