1、模塊定義javascript
1、定義只含值對,沒有任何依賴的模塊(moudle1.js)css
define({html
color: "black",java
size: "unisize"node
});css3
2、定義沒有任何依賴,可是須要一個準備活動的函數(moudle2.js)web
define(function () {sql
//在這裏能夠一些準備工做數據庫
return {編程
color: "black",
size: "unisize"
}
//return 是模塊的返回值
});
3、若是模塊存在依賴,假設模塊依賴須要用到dojo/dom模塊(moudle3.js)
//該模塊提供了一個方法,能夠改變dom元素的innerHTML
define(["dojo/dom"], function(dom) {
return {
change: function(id,text) {
dom.byId(id).innerHTML=text
}
}
}
);
4、將模塊定義爲函數(moudle4.js)
define(function() {
return function(text) {
//彈出一下text文本
alert(text);
}
}
);
2、定義模塊所處的位置
將每一個js文件看作一個模塊,經過dojoConfig去添加咱們本身的配置,告訴dojo框架自定義模塊所處的位置用的是packages屬性,以下
<script> var dojoConfig={ packages: [{ name: "js",//模塊的名字 location: location.pathname.replace(/\/[^/]*$/, '') + '/js'//模塊所處的路徑 }] } </script>
<link rel="stylesheet" type="text/css" href="arcgis_js_v317_api/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css" /> <link rel="stylesheet" type="text/css" href="arcgis_js_v317_api/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" /> <script type="text/javascript"> var dojoConfig={ baseUrl:"arcgis_js_v317_api/arcgis_js_api/library/3.17/3.17compact/dojo", packages: [{ name: "js", location: location.pathname.replace(/\/[^/]*$/, '') + '/js' }] } </script> <script type="text/javascript" src="arcgis_js_v317_api/arcgis_js_api/library/3.17/3.17compact/init.js"></script> <script type="text/javascript"> var map; require(["esri/map", "dojo/domReady!"], function (Map) { map = new Map("mapDiv", { basemap: "topo", center:[120,32], zoom:10 }); }); </script>
3、require中的調用
require(["js/moudle1","js/moudle2","js/moudle3","js/moudle4"], function(moudle1,moudle2,moudle3,moudle4) { alert(moudle1.color) alert(moudle2.color) moudle3.change("test1","文本改變了moudle3") moudle4("aaaa") });
4、dojo/dom
該模塊定義了Dojo Dom API,主要有如下幾種用法:
1、dom.byId();(至關於document.getElementById())
①最直接的用法:
require(["dojo/dom"], function(dom){
var node = dom.byId("someNode");
});
②它是domNode,能夠繼續操做屬性(也就是能夠直接後面"."xxx.xxx...)
dom.byId("someNode").innerHTML = "Hello World";
③若是引用dom.byId();像這樣:
var node = dom.byId("someNode");
var other = dom.byId(node);
console.log(node == other);//true
④require(["dojo/dom", "dojo/dom-style"], function(dom, domStyle){
domStyle.set(dom.byId("foo"), "opacity", 0.5);
//等同於(固然下面這種寫法更好)
domStyle.set("foo", "opacity", 0.5);
});
舉個例子:(dojo/on,dojo/_base/fx,dojo/domReady!咱們不難看出它們是什麼,後面繼續學習)
require(["dojo/dom", "dojo/on", "dojo/_base/fx", "dojo/domReady!"],
function(dom, on, baseFx){
var node = dom.byId("findMe");
on(dom.byId("buttonOne"), "click", function(){
baseFx.fadeOut({ node: node, duration: 300 }).play();
});
on(dom.byId("buttonTwo"), "click", function(){
baseFx.fadeIn({ node: node, duration: 300 }).play();
})
});
<button id="buttonOne">隱藏</button> <button id="buttonTwo">顯示</button>
<div id="findMe">Hi!</div>
2、isDescendant()
判斷該節點是不是另一個節點的子節點(後代節點)
require(["dojo/dom"], function(dom){
dom.isDescendant("child", "ancestor");
})
舉個例子:
require(["dojo/dom", "dojo/domReady!"], function(dom){
var output = "";
if (dom.isDescendant("child", "ancestor")){
output += "'child' is a descendant of 'ancestor'</br>";
}else{
output += "'child' is not a descendant of 'ancestor'</br>";
}
if (dom.isDescendant("loner", "ancestor")){
output += "'loner' is a descendant of 'ancestor'</br>";
}else{
output += "'loner' is not a descendant of 'ancestor'</br>";
}
dom.byId("output").innerHTML = output;
});
<div id="ancestor">
<div id="child">I'm a child!</div>
</div>
<div id="loner">I'm not a child!</div>
<div id="output"></div>
3、setSelectable()
啓用或禁用一個節點上的選擇
舉個例子:
require(["dojo/dom", "dojo/on", "dojo/domReady!"], function(dom, on){
on(dom.byId("button1"), "click", function(){
dom.setSelectable("model", true);
});
on(dom.byId("button2"), "click", function(){
dom.setSelectable("model", false);
});
});
<div id="model">Am I selectable?</div>
<button id="button1">setSelectable True</button>
<button id="button2">setSelectable False</button>
4、dojo/dom-attr該模塊定義了Dojo DOM attributes API,屬性有:
has(),get(),set(),remove(),getNodeProp() 對node屬性的增刪改查...
require(["dojo/dom-attr"], function(domAttr){
result = domAttr.has/get...("myNode", "someAttr");
})
5、dojo/dom-class
contains(),add(),remove(),replace(),toggle()對node className的增刪改查...
6、dojo/dom-construct
toDom()實例化一個HTML片斷返回相應的DOM
place()在已有的DOM樹添加或者更改HTML片斷
create()建立DOM簡化DOM操做
empty()刪除子元素
destroy()刪除DOM,包括自身
7、dojo/dom-form 該模塊定義了表單處理功能
fieldToObject()接收表單id返回它的值,跳過禁用表單控件和沒選擇的radio和checkbox,若是是select返回一個values的字符串數組
toObject()接收表單id返回{"name":"value","name":"value"...}對象,跳過禁用表單控件和沒選擇的radio和checkbox
toQuery()將輸入表單的數據轉換爲URL
toJson()將輸入表單的數據轉換爲JSON對象
8、dojo/dom-geometry 該模塊定義了dojo DOM幾何API,返回DOM節點的邊框,大小,位置以及座標等...
dojo/dom-geometry::position()
dojo/dom-geometry::getMarginBox()
dojo/dom-geometry::setMarginBox()
dojo/dom-geometry::getContentBox()
dojo/dom-geometry::setContentSize()
dojo/dom-geometry::getPadExtents()
dojo/dom-geometry::getBorderExtents()
dojo/dom-geometry::getPadBorderExtents()
dojo/dom-geometry::getMarginExtents()
dojo/dom-geometry::isBodyLtr()
dojo/dom-geometry::normalizeEvent()
dojo/dom-geometry::docScroll()
dojo/dom-geometry::fixIeBiDiScrollLeft()
dojo/dom-geometry::getMarginSize()
9、dojo/dom-prop 該模塊是獲取或設置DOM的各類類型屬性,dojo/dom-style獲取或設置DOM節點的Style
get(),set()
10、dojo/domReady! AMD加載插件,等到DOM加載完成後
dojo/query
1、該模塊提供了DOM查詢功能,輸出一個函數,能夠用來查詢DOM節點的CSS選擇器。
好比:require(["dojo/query!sizzle"], function(query){
query("div")...
(Sizzle是一個純javascript CSS選擇器引擎)
2、若是你想用CSS3僞類選擇器,能夠這樣:
require(["dojo/query!css3"], function(query){
query('#t > h3:nth-child(odd)')...
3、query(selector,context)第一個參數是CSS選擇器(String),第二個參數是可選的上下文來限制搜索範圍(String|DomNode)
好比:require(["dojo/query", "dojo/dom"], function(query, dom){
var nl = query(".someClass", "someId");
// or
var node = dom.byId("someId");
nl = query(".someClass", node);
});
4、dojo/query()返回的是一個NodeList類數組對象,(判斷是不是數組的最簡單也是最有效的方法:
function isArray(arr) {
return Object.prototype.toString.call(arr) ==="[object Array]";
})
NodeList能夠直接使用數組的方法,最多見的幾種方法:
①at(),返回一個新的NodeList,數字參數(能夠是多個)支持負數參數(原來的NodeList下標)指定新的NodeList下標0開始,好比:
require(["dojo/query"], function(query){
var nodelist = query("ul > li").at(0,-1);
console.log(nodelist);
});
<ul><li id="l1"></li>
<li id="l2"></li>
<li id="l3"></li>
<li id="l4"></li>
<li id="l5"></li></ul>
②concat()返回一個新的NodeList,和數組的拼接同樣,如:
require(["dojo/query"], function(query){
var nodelist = query("h1").concat(query("h2"));
console.log(nodelist);
});
③end()該方法沒有參數,用在超連接中,回到以前的NodeList,如:
require(["dojo/query", "dojo/NodeList-dom"], function(query){
query("a")
.filter(".disabled")
.style("color", "grey")
.end()
.style("fontSize", "50px");
});
④every()、some()該方法是數組的迭代方法;
其中every()若是NodeList中每一個node都返回true,它才返回true;
some()若是NodeList中每一個node都返回false,它才返回false,
every()、some()就像邏輯中的&、||好比:
require(["dojo/query"], function(query){
if(query(".someclass").every/some(function(node){
return node.innerHTML == "hello";
})){
// function is true for every node (every)
// function is true for at least one node (some)
}else{
// function is not true for every node
}
});
⑤forEach()遍歷每一個節點,如:
require(["dojo/query"], function(query){
query(".someclass").forEach(function(node){
// node will be each node in the list.
});
});
⑥indexOf()、lastIndexOf()查找指定參數首次(找到一個就不在繼續往下找了)出現的位置,找到返回下標,找不到返回-1;
indexOf()從左向右開始找,lastIndexOf()從右向左找 如:
require(["dojo/query", "dojo/dom"], function(query, dom){
var node = dom.byId("someId");
var idx = query(".someClass").indexOf/lastIndexOf(node);
// if idx >= 0 then node has a class of someClass
// if idx = -1 then node doesn't have class of someClass
});
⑦instantiate()類的實例化,將可選配置對象傳遞給構造函數,如:
require(["dojo/query", "dijit/form/Button"], function(query, Button){
// Converts all button nodes to dijit/form/Buttons
query("button").instantiate(Button, {
showLabel: true
});
});
⑧map()將NodeList中的全部node傳給回調函數,返回新的NodeList 如:
require(["dojo/query"], function(query){
var nodelist = query("h1").map(function(node){
return node.parentNode;
});
// nodelist contains all the parent nodes of every heading level 1 node
});
⑨on()給NodeList中全部/指定node綁定監聽事件,咱們到dojo/on中繼續學習 如:
require("dojo/query", function(query){
query("button").on("click", function(e){
console.log("click!");
});
// Every button will log "click!" to the console when clicked
});
require("dojo/query", function(query){
query("#mylist").on("li:click", function(e){
console.log("click!");
});
// Listens for onclick events on list items in the list with an ID of "myList"
});
require("dojo/query", function(query){
query("#mylist").on("li button:mouseover, li:click", function(e){
console.log("hello!");
});
});
⑩其它像slice(),splice(),push(),pop(), shift(),unshift()等等就不在細說了,都是數組的方法。
dojo/NodeList-data 該模塊經過簡單的data API擴展了NodeList,能夠將data數據綁定到單獨的node節點,從而能夠經過查詢該節點來獲取數據。
一般結合dojo/query一塊兒用:
require(["dojo/query", "dojo/NodeList-data"], function(query){
query("#aNode").data("someKey", "someValue");
});
擴展了兩個方法:data(),removeData()
①data()添加或獲取NodeList中的任何數據;傳兩個參數(data("key","value"))時,函數會把這些數據data設置在NodeList的每一個node中;
傳一個參數(data("key"))時,它會做爲一個getter返回一個數組arr(arr[0]指定key的值)。如:
require("dojo/query", "dojo/NodeList-data", function(query){
query("#foo").data("bar", "baz");
var values = query("#foo").data("bar");
if(values[0] == "baz"){
// do something
}
});
當data()做爲setter時,它返回的是實例化NodeList的操做,因此能夠繼續操做 如:
require("dojo/query", "dojo/NodeList-data", function(query){
query(".someClass")
.data("bar", "baz")
.data("qat", "qut");
});
data()也能夠接收一個對象,而後將數據混合到該節點:
require("dojo/query", "dojo/NodeList-data", function(query){
query("#foo").data({
a: "bar",
b: "baz",
c: [0, 1, 3]
});
var a = query("#foo").data("a")[0];
// a == "bar"
var b = query("#foo").data("b")[0];
// b == "baz"
var c = query("#foo").data("c")[0];
// c == [0, 1, 3]
});
當data()調用沒有參數時,它返回一個包含全部的數據值的數組:
require(["dojo/query", "dojo/NodeList-data"], function(query){
query("#foo").data("a", "bar")
.data("b", "baz")
.data("c", [0, 1, 3]);
var values = query("#foo").data()[0];
// values == { a: "bar", b: "baz", "c": [0, 1, 3] }
});
②removeData()刪除數據,指定參數key時,刪除指定key的屬性;沒有參數則刪除全部數據:
require(["dojo/query", "dojo/NodeList-data"], function(query){
query("#foo").removeData(); // add data removed
query("#foo").removeData("bar"); // only "bar" removed
});
當DOM改變時,有些節點不存在時能夠手動刪除不存在的節點的數據:
require(["dojo/_base/kernel", "dojo/NodeList-data"], function(kernel){
kernel._gcNodeData();
});
5、dojo.declare 定義類
dojo.declare(/*String*/ className,
/*Function | Function[]*/ superclass,
/*Object*/ props )
如清單 6 所示,咱們用 dojo.declare 定義了一個名爲 ClassX 的類,父類爲空,即無父類,類的每一個實例都有屬性 messageX,在調用 constructor 函數初始化新對象時賦值,併爲類的原型設置了 sayMessageX 方法。
dojo.declare( "ClassX", // 類的名字 null, // 父類 // 要加入新定義類的原型的全部屬性及方法 { messageX: null, constructor: function(msgX){ this.messageX = msgX; }, sayMessageX: function(){ alert("hi, this is " + this. messageX); } } );
定義類 ClassX 後,即可以使用了,由示例代碼可見,類 ClassX 的對象既是 ClassX 的實例也是 Object 的實例。
var objX = new ClassX("X");
objX. sayMessageX(); //output: "hi, this is X"
objX instanceof ClassX; //true
objX instanceof Object;//true
dojo.declare( "ClassZ", // 類的名字 [ClassX,ClassY] // 父類 // 要加入新定義類的原型的全部屬性及方法 { messageZ: null, constructor: function(msgX,msgY,msgZ){ this.messageZ = msgZ; this.setMessageY(msgY); }, sayMessageZ: function(){ alert("hi, this is " + this.messageZ); } } );
6、Dojo Widget 傳入參數處理機制
Dojo所開發的控件具備很強的內聚性和麪向對象性。dojo的dijit._widget是dojo提供的圖形界面組件庫
組件的生命週期指的是某一個組件從建立到銷燬的存續階段。理解在各個階段被調用的函數有助於自定義組件或繼承組件的功能擴展。
constructor():
構造函數,在使用new操做時被調用,發生在參數被混合進組件實例以前,主要用於狀態、屬性的初始化。
參數被混合進組件實例:
若是使用標籤化實現或編程實現來實例化一個組件類的時候,傳入參數,好比<button dojoType="dijit.form.Button" iconClass ="">或new dijit.form.Button({iconClass: ""}),該階段沒有關聯特殊的函數,但咱們可使用傳入的這些參數值。
postMixInProperties()自定義屬性:
使用自定義屬性,若是在你的widget裏面須要自定義屬性。該函數會在該組件對應DOM節點建立前被調用。能夠經過參數傳入一個包含各類屬性的javascript對象,這些屬性被混入到dijit組件中,能夠經過this調用。當混入完成以後,在建立dijit組件界面以前,還能夠加入本身的業務。
buildRendering()建立其外觀:
該方法用來建立dijit組件的用戶界面,即DOM節點,該方法完成時候,this.domNode指向的是剛建立的DOM節點。
postCreate()快速建立:
被自定義組件常用的一個函數。當DOM節點被建立完成以後,此方法被調用。須要注意的是,這個時候組件的DOM節點尚未被添加到當前頁面文檔樹。通常用來添加添加組件相關的邏輯。
startup()若是要建立一個孩子widget:
在創建了一個父組件後,還須要添加若干子組件(這裏的子組件不是表示繼承關係,而是表示包含關係),並但願所有加載後一塊兒展示時,就能夠調用該函數。
一個關於該函數的最佳實踐就是即便沒有子組件,也對一個組件新建實例調用該函數,
destroy():
dijit組件的銷燬過程比較複雜。組件實例的銷燬,佔用資源的釋放。包括該組件的DOM節點,相似C語言裏的析構函數。dijit._Widget提供了多個以destroy爲前綴的方法,如destroyRecursive()用於某組件以及其內部包含的子組件(這裏的子組件含義同startup處的說明)的銷燬。
調用順序爲constructor、postCreate、startup
1.dojo.require("dijit.layout.ContentPane"); 2.dojo.declare("Test", [ dijit.layout.ContentPane ], { 3. tagattr1: "", 4. 5. constructor: function(){ 6. console.log("=============constructor============="); 7. console.log("this.title: ", this.title); 8. console.log("this.tagattr1: ", this.tagattr1); 9. console.log("arguments[0].title: ", arguments[0].title); 10. console.log("arguments[0].tagattr1: ", arguments[0].tagattr1); 11. }, 12. 13. postCreate: function(){ 14. console.log("=============postCreate============="); 15. console.log("this.title: ", this.title); 16. console.log("this.tagattr1: ", this.tagattr1); 17. }, 18. 19. startup: function(){ 20. console.log("=============startup============="); 21. console.log("this.title: ", this.title); 22. console.log("this.tagattr1: ", this.tagattr1); 23. } 24.});
dijit._Widget是因此dijit組件的父類,dijit默認提供的組件和本身開發的組件都要繼承此類。dijit._Widget提供了對組件生命週期的管理。dijit組件生命週期管理在實現的時候使用了template method設計方式。dijit._Widget的create()方法定義了默認模版。開發人員也能夠覆蓋create()方法,提供一套不一樣的生命週期實現。dijit定義的生命週期實現:
圖中橢圓行的三個方法是dijit提供的擴展點,用戶能夠本身覆蓋這些方法。startup方法須要顯示被調用。
組件的connect()綁定事件處理方法。subscribe()監聽事件通知
dijit._Template提供了一種從HTML模版中建立用戶界面的方式。dijit._Templated是做爲一個混入類來使用的。在dojo.declear()定義新組件的時候,dijit._Widget須要做爲基類,而dijit._Templated要做爲混入類,也就是說在父類聲明中dijit._Widget須要做爲第一個出現,不然會出錯。
能夠經過templateString 和templatePath兩種方式指定使用的模版。
能夠經過設定widgetInTemplate的值爲true來聲明該dijit組件包含其餘組件。這些包含的組件在destroy方法中被銷燬。
在模版中可使用dojoAttachPoint和dojoAttachEvent兩個特殊的DOM節點屬性。dojoAttachPoint屬性的值是當前DOM節點,dojoAttachEvent屬性的值來完成事件處理綁定。
dijit._Container提供了管理子組件的功能。它所提供的方法有:
addChild(widget,insertIndex);
removeChild(widget);
getChildren();包含子組件的數組。
hasChildren();是否包含子組件。
getIndexOfChild();
須要注意:dijit._COntianer只能包含dijit組件,也就是必須繼承子dijit._Widget,不能包含普通的DOM組件。對於DOM節點能夠用dijit.layout.pane封裝以後,再添加到dijit._Container中。
7、draw類
1.<!DOCTYPE html> 2.<html> 3. <head> 4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5. <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9"> 6. <meta name="viewport" content="width=device-width,user-scalable=no"> 7. <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> 8. <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"> 9. <title>地圖工具欄</title> 10. 11. <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/dojo/dijit/themes/claro/claro.css"> 12. <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/esri/css/esri.css"> 13. <style> 14. html, body { 15. height: 100%; width: 100%; margin: 0; padding: 0; 16. } 17. </style> 18. 19. <script>var dojoConfig = { 20. parseOnLoad: true // 解析加載 21. };</script> 22. <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/"></script> 23. <script> 24. // 導入包 25. dojo.require("esri.map"); 26. dojo.require("esri.toolbars.draw"); 27. dojo.require("dijit.layout.BorderContainer"); 28. dojo.require("dijit.layout.ContentPane"); 29. 30. var map, toolbar, symbol, geomTask; 31. 32. function init() { 33. map = new esri.Map("map", { 34. basemap: "streets", // 指定的地圖底圖。如下是有效的選項:"streets","satellite","hybrid","topo","gray","oceans","national-geographic","osm". 35. center: [-15.469, 36.428], // 經緯度 36. zoom: 3 // 縮放深度 37. }); 38. 39. dojo.connect(map, "onLoad", createToolbar); // 綁定加載事件 40. } 41. 42. function createToolbar(themap) { 43. toolbar = new esri.toolbars.Draw(map); // esri.toolbars.Draw(map, options) 44. dojo.connect(toolbar, "onDrawEnd", addToMap); // 繪製完成觸發 45. } 46. 47. function addToMap(geometry) { 48. toolbar.deactivate(); // 關閉工具欄並激活地圖導航. 49. map.showZoomSlider(); //在地圖上顯示的縮放滑塊 50. // 判斷幾何圖形的類型 51. switch (geometry.type) { 52. case "point": 53. var symbol = new esri.symbol.SimpleMarkerSymbol( 54. esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, // 樣式,STYLE_CIRCLE(●),STYLE_CROSS(+),STYLE_DIAMOND(◆),STYLE_SQUARE(■),STYLE_X(X) 55. 10, // 像素 56. new esri.symbol.SimpleLineSymbol( 57. esri.symbol.SimpleLineSymbol.STYLE_SOLID, // 樣式,STYLE_DASH(破折號),STYLE_DASHDOT(點劃線),STYLE_DASHDOTDOT,STYLE_DOT(點),STYLE_NULL,STYLE_SOLID(實線) 58. new dojo.Color([255,0,0]), // 顏色 59. 1 // 像素 60. ), 61. new dojo.Color([0,255,0,0.25]) // 顏色和透明度 62. ); 63. break; 64. case "polyline": 65. var symbol = new esri.symbol.SimpleLineSymbol( 66. esri.symbol.SimpleLineSymbol.STYLE_SOLID, 67. new dojo.Color([255,0,0]), 68. 1 69. ); 70. break; 71. case "polygon": 72. var symbol = new esri.symbol.SimpleFillSymbol( 73. esri.symbol.SimpleFillSymbol.STYLE_SOLID, 74. new esri.symbol.SimpleLineSymbol( 75. esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, 76. new dojo.Color([255,0,0]), 77. 2 78. ), 79. new dojo.Color([255,255,0,0.25]) 80. ); 81. break; 82. case "extent": 83. var symbol = new esri.symbol.SimpleFillSymbol( 84. esri.symbol.SimpleFillSymbol.STYLE_SOLID, 85. new esri.symbol.SimpleLineSymbol( 86. esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, 87. new dojo.Color([255,0,0]), 88. 2 89. ), 90. new dojo.Color([255,255,0,0.25]) 91. ); 92. break; 93. case "multipoint": 94. var symbol = new esri.symbol.SimpleMarkerSymbol( 95. esri.symbol.SimpleMarkerSymbol.STYLE_DIAMOND, 96. 20, 97. new esri.symbol.SimpleLineSymbol( 98. esri.symbol.SimpleLineSymbol.STYLE_SOLID, 99. new dojo.Color([0,0,0]), 100. 1 101. ), 102. new dojo.Color([255,255,0,0.5]) 103. ); 104. break; 105. } 106. var graphic = new esri.Graphic(geometry, symbol); 107. map.graphics.add(graphic); // 將繪圖加入到圖層中 108. } 109. dojo.ready(init); // 初始化加載 110. </script> 111. </head> 112. <body class="claro"> 113.<div id="mainWindow" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;"> 114. <div id="header" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'" style="height:75px;text-align:left;font-weight:bold;font-size:14px;color:#400D12;overflow:hidden;"> 115. <span>繪製:<br /></span> 116. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.POINT);map.hideZoomSlider();}">Point(點)</button> 117. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.MULTI_POINT);map.hideZoomSlider();}">Multipoint(多點)</button> 118. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.LINE);map.hideZoomSlider();}">Line(線)</button> 119. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.POLYLINE);map.hideZoomSlider();}">Polyline(折線)</button> 120. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.POLYGON);map.hideZoomSlider();}">Polygon(多邊形)</button> 121. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.FREEHAND_POLYLINE);map.hideZoomSlider();}">Freehand Polyline(手繪折線)</button> 122. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.FREEHAND_POLYGON);map.hideZoomSlider();}">Freehand Polygon(手繪多邊形)</button> 123. <!-- 箭頭,三角形,圓形和橢圓類型全部繪製的多邊形符號 --> 124. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.ARROW);map.hideZoomSlider();}">Arrow(箭頭)</button> 125. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.TRIANGLE);map.hideZoomSlider();}">Triangle(三角形)</button> 126. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.CIRCLE);map.hideZoomSlider();}">Circle(圓形)</button> 127. <button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:function(){toolbar.activate(esri.toolbars.Draw.ELLIPSE);map.hideZoomSlider();}">Ellipse(橢圓)</button> 128. </div> 129. <div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"> 130. </div> 131.</div> 132. </body> 133.</html>
常量 |
描述 |
ARROW |
繪製箭頭. |
UP_ARROW |
繪製一個上箭頭. |
DOWN_ARROW |
繪製一個下箭頭 |
LEFT_ARROW |
繪製一個左箭頭. |
RIGHT_ARROW |
繪製一個右箭頭 |
POINT |
繪製點. |
MULTI_POINTPOINT |
繪製多點. |
ELLIPSE |
繪製一個橢圓形. |
POLYGON |
繪製多邊形. |
POLYLINE |
繪製折線. |
FREEHAND_POLYGON |
手繪多邊形. |
FREEHAND_POLYLINE |
手繪折線. |
LINE |
繪製線 |
RECTANGLE |
繪製一個矩形 |
CIRCLE |
繪製圓. |
TRIANGLE |
繪製一個三角形. |
EXTENT |
Draws an extent box. |
屬性 |
類型 |
描述 |
當繪製 Polyline 時使用的符號. |
||
當繪製 Point 繪製Multipoint 時使用的符號. |
||
Boolean |
設置爲false, 幾何圖形被修改爲拓撲正確項. 設置爲true,輸入幾何體不被修改. |
None |
激活工具欄的繪圖幾何形狀。激活工具欄禁用地圖導航。 |
|
None |
關閉工具欄並激活地圖導航. |
|
none |
最後,繪製的幾何形狀並觸發onDrawEnd事件.工做時使用此方法來完成繪製折線,多邊形或點對多點,支持觸摸的設備iPhone. |
|
None |
設置 fill symbol. |
|
None |
設置線符號 |
|
None |
設置標記符號 |
|
None |
Sets whether the polygon geometry should be modified to be topologically correct. |
<script type="text/javascript"> var dojoConfig={ baseUrl:"", tlmSiblingOfDojo: false, packages:[ {"name":"dojo","location":'dojo-release-1.10.4/dojo'}, {"name":"mytest","location":"mytest",main:"myModule"}, ] }; </script> <script data-dojo-config="async: true" src="dojo-release-1.10.4/dojo/dojo.js"></script> <script type="text/javascript"> require( ['mytest/myModule'],function(myModule){ //do something with myModule }) </script>
說明:
1.dojoConfig 必須set在加載dojo.js以前,不然在控制檯調試時會發現報錯。
2.baseUrl是什麼?
默認值是dojo.js所在文件夾的路徑,此例中即dojo-release-1.10.4/
全部的package路徑都是相對於baseUrl,例如:若是我這樣設置baseUrl:"/myfolder/",那麼當我加載模塊「mytest/myModule」,loader將會從下面路徑去加載:
/myfolder/mytest/myModule.js
3.tlmSiblingOfDojo是什麼?
默認值是true,此時loader將從dojo.js所在文件夾的同級文件夾中加載模塊
4.packages
一個array,包含多個module及每一個module對應的features。
※ name:the name of the package. 即包含了自定義module js文件的文件夾名,如此例中的「my」。
※ location:the location of the package. 能夠是基於baseUrl的相對路徑也能夠是絕對路徑。
採起相對路徑時,當我require「mytest/myModule」, loader將從形以下面的路徑加載module:
baseUrl+mytest的location+」/myModule.js
※ main:默認值是main.js。用於require package自己時告訴loader該去加載什麼文件。例如,當我require 「mytest」而不是「mytest/myModule」時,loader依然知道去load myModule.js。
另外一種狀況,當直接require一個沒有在packages裏define過的package時,如「anotherTest」時,loader將會嘗試去加載下面的文件:
baseUrl+anotherTest.js
9、圖層控制
1.dojo.connect(dynamicMapServiceLayer, "onLoad", loadLayerList); 2. function loadLayerList(layers) { 3. var html = "" 4. var infos = layers.layerInfos; 5. for (var i = 0, length = infos.length; i < length; i++) { 6. var info = infos[i]; 7. //圖層默認顯示的話就把圖層id添加到visible 8. if (info.defaultVisibility) { 9. visible.push(info.id); 10. } 11. //輸出圖層列表的html 12. html = html + "<div><input id='" + info.id + "' name='layerList' class='listCss' type='checkbox' value='checkbox' onclick='setLayerVisibility()' " + (info.defaultVisibility ? "checked" : "") + " />" + info.name + "</div>"; 13. } 14. //設置可視圖層 15. dynamicMapServiceLayer.setVisibleLayers(visible); 16. //在右邊顯示圖層名列表 17. dojo.byId("toc").innerHTML = html; 18. } 19. setLayerVisibility = function () { 20. //用dojo.query獲取css爲listCss的元素數組 21. var inputs = dojo.query(".listCss"); 22. visible = []; 23. //對checkbox數組進行變量把選中的id添加到visible 24. for (var i = 0; i < inputs.length; i++) { 25. if (inputs[i].checked) { 26. visible.push(inputs[i].id); 27. } 28. } 29. //設置可視圖層 30. dynamicMapServiceLayer.setVisibleLayers(visible); }
1.map.on("load", initSelectToolbar); 2. 3. var fieldsSelectionSymbol = 4. new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 10, 5. new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, 6. new Color([0, 255, 0]), 1), 7. new Color([255, 0, 0, 5])); 8. 9. featureLayer = new FeatureLayer("http://localhost:6080/arcgis/rest/services/MyMapService/MapServer/5"); 10. map.addLayer(featureLayer); 11. featureLayer.setSelectionSymbol(fieldsSelectionSymbol); 12. 13. on(dom.byId("selectFieldsButton"), "click", function () { 14. selectionToolbar.activate(Draw.EXTENT); 15. }); 16. 17. on(dom.byId("clearSelectionButton"), "click", function () { 18. featureLayer.clearSelection(); 19. }); 20. 21. function initSelectToolbar(event) { 22. selectionToolbar = new Draw(event.map); 23. var selectQuery = new Query(); 24. 25. on(selectionToolbar, "DrawEnd", function (geometry) { 26. selectionToolbar.deactivate(); 27. selectQuery.geometry = geometry; 28. featureLayer.selectFeatures(selectQuery, 29. FeatureLayer.SELECTION_NEW); 30. }); 31. } 32. 33. 34. }); 35. </script> </head>
1.<!DOCTYPE html> 2.<html> 3.<head> 4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5. <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /> 6. <title>final Map</title> 7. <link rel="stylesheet" href="http://localhost/arcgis_js_v314_api/arcgis_js_api/library/3.14/3.14/esri/css/esri.css"> 8. 9. <style> 10. html, body, #map { 11. height: 100%; 12. margin: 0; 13. padding: 0; 14. } 15. 16. body { 17. background-color: #FFF; 18. overflow: hidden; 19. font-family: "Trebuchet MS"; 20. } 21. 22. #BasemapToggle { 23. position: absolute; 24. right: 20px; 25. top: 20px; 26. z-index: 50; 27. } 28. 29. #HomeButton { 30. left: 25px; 31. position: absolute; 32. top: 93px; 33. z-index: 50; 34. } 35. 36. #LocateButton { 37. left: 25px; 38. position: absolute; 39. top: 130px; 40. z-index: 50; 41. } 42. 43. #search { 44. display: block; 45. position: absolute; 46. z-index: 2; 47. top: 25px; 48. left: 75px; 49. } 50. </style> 51. <script src="http://localhost/arcgis_js_v314_api/arcgis_js_api/library/3.14/3.14/init.js"></script> 52. <script> 53. var map, mapCenter, selectionToolbar, featureLayer; 54. var visible = [], setLayerVisibility;; 55. require([ 56. "esri/basemaps", 57. "esri/map", 58. "esri/layers/ArcGISTiledMapServiceLayer", 59. "esri/layers/FeatureLayer", 60. "esri/layers/GraphicsLayer", 61. "esri/geometry/Point", 62. 63. "esri/symbols/SimpleFillSymbol", 64. "esri/symbols/SimpleLineSymbol", 65. "esri/symbols/SimpleMarkerSymbol", 66. "esri/tasks/query", 67. "esri/toolbars/draw", 68. 69. "esri/graphic", 70. "esri/dijit/Scalebar", 71. "esri/dijit/HomeButton", 72. "esri/dijit/LocateButton", 73. "esri/dijit/BasemapToggle", 74. "esri/dijit/OverviewMap", 75. "esri/dijit/Search", 76. "esri/geometry/webMercatorUtils", 77. 78. "dojo/dom", 79. "dojo/on", 80. "dojo/_base/Color", 81. "dojox/charting/Chart2D", 82. "dojo/domReady!"], 83. function ( 84. esriBasemaps, 85. Map, 86. Tiled, 87. FeatureLayer, 88. GraphicsLayer, 89. Point, 90. 91. SimpleFillSymbol, SimpleLineSymbol, SimpleMarkerSymbol, 92. Query, 93. Draw, 94. 95. Graphic, 96. Scalebar, 97. HomeButton, 98. LocateButton, 99. BasemapToggle, 100. OverviewMap, 101. Search, 102. webMercatorUtils, 103. 104. dom, 105. on, 106. 107. Color, 108. Chart2D, 109. domConstruct) { 110. 111. esriBasemaps.delorme = { 112. baseMapLayers: [ 113. //中國矢量地圖服務 114. { url: "http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer" } 115. ], 116. //縮略圖 117. thumbnailUrl: "shiliang.jpg", 118. title: "矢量圖" 119. }; 120. 121. //初始化地圖 122. map = new esri.Map("map", { basemap: "delorme", logo: false, }); 123. 124. //map = new Map("map", {logo:false,slider: true}); 125. //var tiled = new Tiled("http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer"); 126. //map.addLayer(tiled,0); 127. var dynamicMapServiceLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/MyMapService/MapServer"); 128. map.addLayer(dynamicMapServiceLayer, 1); 129. var chartLayer = new GraphicsLayer({ "id": "chartLayer" }); 130. map.addLayer(chartLayer, 2); 131. mapCenter = new Point(103.847, 36.0473, map.spatialReference); 132. map.centerAndZoom(mapCenter, 4); 133. /*************************************************************************************/ 134. //衛星底圖 135. var toggle = new BasemapToggle({ 136. map: map, 137. basemap: "satellite" 138. }, "BasemapToggle"); 139. toggle.startup(); 140. //返回主視圖 141. var home = new HomeButton({ 142. map: map 143. }, "HomeButton"); 144. home.startup(); 145. //定位 146. var geoLocate = new LocateButton({ 147. map: map 148. }, "LocateButton"); 149. geoLocate.startup(); 150. //鷹眼 151. var overviewMapDijit = new OverviewMap({ 152. map: map, 153. expandFactor: 2, 154. attachTo: "bottom-left", 155. visible: true 156. }); 157. overviewMapDijit.startup(); 158. //比例尺 159. var scalebar = new esri.dijit.Scalebar({ 160. map: map,//地圖對象 161. attachTo: "bottom-right",//控件的位置,右下角 162. scalebarStyle: "ruler",//line 比例尺樣式類型 163. scalebarUnit: "metric"//顯示地圖的單位,這裏是km 164. }); 165.//搜索 166. var search = new Search({ 167. map: map 168. }, "search"); 169. search.startup(); 170. //顯示地圖座標 171. map.on("load", function () { 172. //after map loads, connect to listen to mouse move & drag events 173. map.on("mouse-move", showCoordinates); 174. map.on("mouse-drag", showCoordinates); 175. }); 176. function showCoordinates(evt) { 177. //the map is in web mercator but display coordinates in geographic (lat, long) 178. var mp = webMercatorUtils.webMercatorToGeographic(evt.mapPoint); 179. //display mouse coordinates 180. dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3); 181. } 182.<body> 183. <div id="map"> 184. 185. <!-- 返回初始化地圖按鈕--> 186. <div id="HomeButton"></div> 187. <!-- Html5定位按鈕--> 188. <div id="LocateButton"></div> 189. <!-- 切換底圖--> 190. <div id="BasemapToggle"></div> 191. <!-- 搜索欄--> 192. <div id="search"></div> 193. <!-- 座標--> 194. <span id="info" style="position:absolute; left:750px; bottom:5px; color:#000; z-index:50;"></span> 195. 196. <button id="selectFieldsButton">選框查詢</button> 197. <button id="clearSelectionButton" data-dojo-type="dijit/form/Button">清除選擇</button><br> 198. <div id="toc" style="position: absolute; left: 10px; bottom: 20px; border: 1px solid #9c9c9c; background: #fff; width: 100px; height: auto; z-index: 99;padding: 10px;"></div> 199. </div> 200.</body> </html>
this.map.getLayer("yhmap").setVisibility(!this.map._layers.yhmap.visible); //方式一,根據名稱使用GetLayer方法
this.map._layers.yhmapanno.setVisibility(!this.map._layers.yhmapanno.visible); //方式二,直接根據圖層Id名稱讀取
this.map._layers.yhimage.setVisibility(!this.map._layers.yhimage.visible);
this.map._layers.yhimageanno.setVisibility(!this.map._layers.yhimageanno.visible);
//注意,使用setVisibility()方法,若是 直接使用visible屬性無效果
dojo.require("esri.dijit.Geocoder"); //geocoder widget (the searchTextBox) var geocoderParas = [{ //self-defined geocoder url: "http://localhost:6080/arcgis/rest/services/subwayWGS84/stationLocator/GeocodeServer", name: "stationLocator"// name of Locator in geocodeService }]; geocoder = new esri.dijit.Geocoder({// construct geocoder widget map: map, autoComplete: true, arcgisGeocoder: false, //don't use argis global geocoder geocoders: geocoderParas, outFields: ["*"] }, "search"); geocoder.startup(); dojo.connect(geocoder, "onSelect", function (result) {//when one result is selected //result.feature is type graphic map.graphics.clear(); //clear previous graphics map.infoWindow.hide();
10、render(arcgis for js 中的渲染)
根據某個字段值按範圍劃分顏色
var symbol = new SimpleFillSymbol(); symbol.setColor(new Color([150, 150, 150, 0.5])); // Add five breaks to the renderer. // If you have ESRI's ArcMap available, this can be a good way to determine break values. // You can also copy the RGB values from the color schemes ArcMap applies, or use colors // from a site like www.colorbrewer.org // // alternatively, ArcGIS Server's generate renderer task could be used var renderer = new ClassBreaksRenderer(symbol, "POP07_SQMI"); renderer.addBreak(0, 25, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5]))); renderer.addBreak(25, 75, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5]))); renderer.addBreak(75, 175, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5]))); renderer.addBreak(175, 400, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5]))); renderer.addBreak(400, Infinity, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5]))); var infoTemplate = new InfoTemplate("${NAME}", "${*}"); var featureLayer = new FeatureLayer("https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/3", { mode: FeatureLayer.MODE_SNAPSHOT, outFields: ["*"], infoTemplate: infoTemplate }); featureLayer.setDefinitionExpression("STATE_NAME = 'Kansas'"); featureLayer.setRenderer(renderer); map.addLayer(featureLayer);
根據圖層不一樣字段的值,所佔的比重,實現不一樣顏色的融合渲染,官方給的例子是,根據地區房屋的使用狀況,出租,空置, 自住,所佔的比例實現Red,Green,Blue的融合渲染效果
19棟房子裏,有17棟都是自住的,所以,渲染結果是深藍色
下面的選中區域裏,24個自住,20個出租,兩個值基本至關,因此渲染的效果是Blue和Red融合的紫色
//Set the blendRenderer's parameters var blendRendererParams = { //blendMode:"overlay" //By default, it uses "source-over", uncomment to display different mode //See: http://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation symbol: new SimpleFillSymbol().setOutline(new SimpleLineSymbol().setWidth(0)), fields: [ { field: "OWNER_CY", color: new Color([0, 0, 255]) }, { field: "RENTER_CY", color: new Color([255, 0, 0]) }, { field: "VACANT_CY", color: new Color([0, 255, 0]) } ], opacityStops: [ { value: .1, opacity: 0 }, { value: 1, opacity: .7 } ], normalizationField: "TOTHU_CY" };
var serviceUrl = "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/nyc_parks_gardens_hist_sites/FeatureServer/0"; var layer = new FeatureLayer(serviceUrl, { outFields: [ "facname", "proptype", "factype", "address" ], featureReduction: { type: "cluster" }, infoTemplate: new PopupTemplate({ title: "{facname}", description: "{proptype} {factype} on {address}." }) }); map.addLayer(layer);
var map = new Map("map", { extent: new Extent({"xmin":-2460944,"ymin":-1389910,"xmax":2297115,"ymax":1643787,"spatialReference":{"wkid":102003}}) }); var layer = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/USA_County_Crops_2007/FeatureServer/0", { outFields: ["*"], infoTemplate: new InfoTemplate("${COUNTY}, ${STATE}", "<div style='font: 18px Segoe UI'>The percentage of the area of the county that represents farmland is <b>${M086_07:NumberFormat(places:0)}%</b>.</div>") }); var legend = new Legend({ map: map, layerInfos: [{ title: "Percentage of county area used for farming", layer: layer }] }, "legend"); layer.on("load", function(){ var renderer = new SimpleRenderer(new SimpleFillSymbol().setOutline(new SimpleLineSymbol().setWidth(0.1).setColor(new Color([128,128,128])))); renderer.setColorInfo({ field: "M086_07", minDataValue: 0, maxDataValue: 100, colors: [ new Color([255, 255, 255]), new Color([127, 127, 0]) ] }); layer.setRenderer(renderer); map.addLayer(layer); legend.startup();
因爲arcgis 發佈要素服務須要數據庫,因此選擇開源的支持空間數據較好的postgresql數據庫。
一:postgresql的下載與安裝:
1.1、下載官方地址:https://www.postgresql.org/download/(必定要下載含有postgis的版本)
1.2:安裝
參考此教程:https://jingyan.baidu.com/article/e75057f2c6f6eaebc91a89ed.html
1.3:創建數據庫
1.3.1、打開navicat
1.3.2、鏈接postgresql數據庫
1.3.3、創建數據庫
點擊肯定就創建成功
2、數據導入數據庫
2.1、打開arcmap,鏈接postgresql數據庫
2.2、將空間數據導入postgresql中
2.2.1、打開要發佈的shp數據
2.2.2、將arccatalog和postgresql數據庫鏈接
2.2.3、鏈接信息
點擊ok,出現以下狀況,表示鏈接成功
2.2.4、要素添加到postgresql數據庫中
2.2.5、點擊feature class(single)
2.2.6、點擊肯定,等待數據導入,若是導入成功,則出現下圖的所示
2.2.7、依次將其餘數據按照這種方式都加入到postgresql數據庫中
三:要素服務的發佈
3.1、關閉直接打開的shp數據,留下數庫中的數據
3.2、開始發佈要素服務。file-》share as ->service
點擊下一步
點擊一下一布
點擊下一步
選擇發佈服務類型
分析是否存在錯誤
有錯誤,下邊解決錯誤,
第一個錯誤:SEVERITY STATUSCODEDESCRIPTIONNAMETYPEDATA FRAME
High Unresolved00090Feature service requires a registered databaseLayersData FrameLayers
這個錯誤是沒有和數據庫關聯起來,須要數據庫
雙擊第一個錯誤,出現如圖
點擊加號添加數據庫
點擊ok 點擊肯定
解決第二個錯誤
SEVERITY STATUSCODEDESCRIPTIONNAMETYPEDATA FRAME
High Unresolved00002Data frame does not have a spatial referenceLayersData FrameLayers
沒有座標,須要點擊座標
雙擊錯誤,
錯誤所有消失,點擊發布,
發佈成功
3.3、瀏覽器查看發佈的服務
瀏覽器輸入https://localhost:6443/arcgis/manager/service
輸入帳號和密碼
原理:
建立兩個graphic圖層lineLayer、carLayer,在兩點之間進行插值,把小車圖片建立成graphic,而後顯示隱藏。簡單來講就是:根據設置的時間間隔,在兩個點之間建立n個點,而後表明小車的graphic在這些點的位置上依次添加
小車角度經過setAngle()進行控制,拐點處的停頓經過setInterval()控制
代碼:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>軌跡回放</title> <link rel="stylesheet" href="http://localhost/library/3.20/jsapi/js/dojo/dijit/themes/tundra/tundra.css" /> <link rel="stylesheet" type="text/css" href="http://localhost/library/3.20/jsapi/js/esri/css/esri.css" /> <style> html, body, #mapDiv { height: 550px; width: 100%; margin: 0; padding: 0; } </style> <script type="text/javascript" src="http://localhost/library/3.20/jsapi/init.js"></script> <script type="text/javascript"> dojo.require("esri.map"); dojo.require("esri.SpatialReference"); dojo.require("esri.tasks.GeometryService"); dojo.require("esri.dijit.Scalebar"); dojo.require("dojo.parser"); dojo.require("esri.Color"); var map; var points = []; var lineSymbol; var pointSymbol; var carSymbol; var carGraphic; var timer; function init() { map = new esri.Map("mapDiv"); var layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/BaseMap/MapServer"); map.addLayer(layer); lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color("red"), 3); pointSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([255, 0, 0, 1])); carSymbol = new esri.symbol.PictureMarkerSymbol("car.png", 24, 24) var lineLayer = new esri.layers.GraphicsLayer({ id: "lineLayer" }); var carLayer = new esri.layers.GraphicsLayer({ id: "carLayer" }); map.addLayer(lineLayer); map.addLayer(carLayer); dojo.connect(map, "onClick", Click); } /** * 點擊事件,添加點 */ function Click(e) { points.push(e.mapPoint); map.graphics.add(new esri.Graphic(e.mapPoint, pointSymbol)); } /** * 根據回放速度在兩點之間進行插值 */ function interpolation(pointA, pointB, speed) { var tmp = []; if (speed == undefined) { speed = 1; } speed = speed - 0.5; //不能大於播放速度 var count = Math.abs(speed) * 25; var disX = (pointB.x - pointA.x) / count; var disY = (pointB.y - pointA.y) / count; var i = 0; while (i <= count) { var x = pointA.x + i * disX; var y = pointA.y + i * disY; tmp.push(new esri.geometry.Point(x, y)); i++; } tmp.push(pointB);//防止插值出來的最後一個點到不了B點 return tmp; } var j = 0; /** * 播放 */ function play(tmpPoints) { var ref = setTimeout(function () { if (j < tmpPoints.length - 1) { var line = new esri.geometry.Polyline({ "paths": [[[tmpPoints[j].x, tmpPoints[j].y], [tmpPoints[j + 1].x, tmpPoints[j + 1].y]]] }); var lineGriphic = new esri.Graphic(line, lineSymbol); map.getLayer("lineLayer").add(lineGriphic); map.getLayer("carLayer").clear(); carGriphic = new esri.Graphic(tmpPoints[j + 1], carSymbol); map.getLayer("carLayer").add(carGriphic); j++; play(tmpPoints); } else { j = 0; } }, 40); //小車40毫秒換個位置閃現一次,25*40*speed就是兩點之間的時間間隔 } //計算兩個點的角度值 function Angle(startx, starty, endx, endy) { console.log("+++++++++"); var tan = 0 if (endx == startx) { tan = Math.atan(0) * 180 / Math.PI } else { tan = Math.atan(Math.abs((endy - starty) / (endx - startx))) * 180 / Math.PI console.log(tan); } if (endx >= startx && endy >= starty)//第一象限 { return -tan; } else if (endx > startx && endy < starty)//第四象限 { return tan; } else if (endx < startx && endy > starty)//第二象限 { return tan - 180; } else { return 180 - tan; //第三象限 } } //開始執行 function Start() { if (timer != null) { clearInterval(timer); map.getLayer("lineLayer").clear(); } var replayIndex=0; timer = setInterval(function () { if (replayIndex == points.length - 1) { clearInterval(timer); } else { if (replayIndex == 0) { map.getLayer("lineLayer").clear(); } var p1 = points[replayIndex]; var p2 = points[++replayIndex]; var tempPoints = interpolation(p1, p2, document.getElementById("txtSpeed").value); var angle = Math.ceil(Angle(p1.x, p1.y, p2.x, p2.y)) console.log(angle); carSymbol.setAngle(angle) //設置小車角度 play(tempPoints); } }, document.getElementById("txtSpeed").value * 1000); } </script> </head> <body class="tundra" onload="init()"> <div id="mapDiv"> </div> <div> 先添加點</div> 回放速度<input id="txtSpeed" type="text" value="4" style="width:30px" /><input type="button" value="回放" onclick="Start()" /> </body> </html>