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>