测量误差中JS是什么意思

JavaScript08

测量误差中JS是什么意思,第1张

每条查询都用唯一的StringBuilder来生成。

模板引擎实际上处理的是字符而并非正则表达式。

选择尽可能的使用数组,尤其是在对监听器进行迭代时。

对JDBC的方法敬而远之。

ArcGIS JS其实已经提供了量算的Widget,但是用过的童鞋都知道,那个玩意儿实在是太丑了,和程序搭配起来实在很突兀,因此自己实现一个量算工具是无疑是最好的办法,无图无真相,我先放两张效果图。

图1.量算面积

图2 量算距离

官方给出的Sample里,测量距离和面积都要用到GeoServeice,而且网上也都是类似的代码,都不是直接在客户端进行的量算。好在ArcGIS JS 在 3.13版本增加了 "esri/geometry/geometryEngine" 模块,借助这个模块就可以实现客户端的量算。

这个模块还有很多方法,具体内容可以到官网上查看geometryEngine的详细信息。

//计算距离

_calDistance: function (point1, point2) {            var line = new Polyline(this.defaults.map.spatialReference)

line.addPath([point1, point2])           if (this.defaults.map.spatialReference.isWebMercator()||this.defaults.map.spatialReference.wkid == "4326") {//在web麦卡托投影和WGS84坐标系下的计算方法

return geometryEngine.geodesicLength(line, "meters")

} else {//在其他投影坐标系下的计算方法

return geometryEngine.planarLength(line, "meters")

}

},

//计算面积

_calArea: function (polygon) {            var spatialReference = this.defaults.map.spatialReference           if (spatialReference.isWebMercator()||spatialReference.wkid == "4326" ) {                return geometryEngine.geodesicArea(polygon, "square-meters")

} else {                return geometryEngine.planarArea(polygon, "square-meters")

}

},

好了,解决了核心问题,剩下的就只需要如何分段显示距离和提高用户体验了。

1.测量距离

绘制线的时候,用的是ArcGIS JS 的Draw 模块在开始测量的时候,监听地图点击事件,把在地图上点击到的点加到 this._stopPoints 数组中,然后每次点击地图,就用当前点和上一个点进行距离计算,计算结果添加到this_stopDistances数组中,接着把计算结果用graphic添加到地图上。

//开始测量距离

_startMeasureDistance: function () {            this._clearMapMouseClickEvent()           this._stopPoints = []           this._stopDistances = []           this._measureLayer.clear()           this.toolbar.deactivate()           this.toolbar.activate(Draw.POLYLINE)           var stopPoints = this._stopPoints           var stopDistances = this._stopDistances           var self = this           this._mapClickFlag = this.defaults.map.on("click", function (evt) {                var distance = 0               var stopPoint = evt.mapPoint               if (stopPoints.length >0) {                    var startPoint = stopPoints[stopPoints.length - 1]

distance = self._calDistance(startPoint, stopPoint)                   if (self._stopDistances.length >0) {

distance += self._stopDistances[self._stopDistances.length - 1]

}

stopDistances.push(distance)

}

stopPoints.push(stopPoint)               var stopGraphic = new Graphic(stopPoint, self.defaults.markerSymbol)               var textGraphic = self._getStopPointGraphic(stopPoint, distance)

self._measureLayer.add(stopGraphic)

self._measureLayer.add(textGraphic)

})

},

结束量测,添加清除按钮,这里的清除按钮是用svg路径绘制的,在代码最后的this._clearMapMouseClickEvent()是用于取消监听map的click事件,在最后我会贴出全部代码。

//测量距离结束,添加清除按钮、测量线段

_endMeasureDistance:function(line,endPoint){            var lineGraphic = new Graphic(line, this.toolbar.lineSymbol)           var clearGraphic = this._createClearBtn(endPoint)           this._measureLayer.add(clearGraphic)           this._measureLayer.add(lineGraphic)

lineGraphic.getDojoShape().moveToBack()           this._clearMapMouseClickEvent()

},

2.面积量测

面积量测就相对简单了,用Draw模块绘制完成Polygon后,利用之前贴出的计算面积的方法计算完成后再把结果添加到地图上。

//开始测量面积

_startMeasureArea: function () {            this._clearMapMouseClickEvent()           this._measureLayer.clear()           this.toolbar.deactivate()           this.toolbar.activate(Draw.POLYGON)

},        //测量面积结束,添加清除按钮、测量结果

_endMeasureArea: function (polygon) {            var area = this._calArea(polygon)           if (area >1000000) {

area = (area / 1000000).toFixed(2) + "平方千米"

} else {

area = area.toFixed(2) + "平方米"

}            var center = polygon.getCentroid()           var ploygonGraphic = new Graphic(polygon, this.toolbar.fillSymbol)           var textSymbol = this._createTextSymbol(area)

textSymbol.setOffset(30, 10)           var textGraphic = new Graphic(center, textSymbol)           var clearBtn = this._createClearBtn(center)           this._measureLayer.add(ploygonGraphic)           this._measureLayer.add(textGraphic)           this._measureLayer.add(clearBtn)

ploygonGraphic.getDojoShape().moveToBack()

},

下面我们就来看一看如何使用这个自定义的测量模块了。

<!DOCTYPE html><html lang="en"><head>

<meta charset="UTF-8">

<title>Extra-Map-App</title>

<link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/css/esri.css">

<link rel="stylesheet" href="css/mainApp.css">

<script>

var dojoConfig = {

packages: [{

name: 'custom',

location: location.pathname.replace(/\/[^/]+$/, '') + '/custom'//从cdn加载自己定义的模块方法

},

{

name: 'dextra',

location: '/extra.arcgis.3.x/dist/'//从cdn加载自己定义的模块方法                }]

}   </script>

<script src="https://js.arcgis.com/3.16/"></script>

<script src="js/mainApp.js"></script>

<style>

#measureTools {

position: absolute

top: 50px

left: 50px

z-index: 1000

}

</style></head><body><div id="measureTools">

<button class="measure-distance">距离</button>

<button class="measure-area">面积</button></div><div id="map" style="overflow: hidden"></div></body></html>

在使构造时测量工具时,添加”.measure-distance”类表示测量距离;添加”.measure-area”类表示测量面积。在这个例子中,我的自定义模块名叫dextra,添加引用时按照dojo的AMD规范来进行加载。

require([    "esri/map",    "dextra/dijit/MeasureTools",    "dextra/layers/GoogleImageLayer",    "dextra/layers/GoogleImageAnnoLayer",    "dojo/domReady!"],    function(Map,

deMeasureTools,GoogleImageLayer,GoogleImageAnnoLayer) {        var map = new Map("map", {

showAttribution:false,

fadeOnZoom:true,

force3DTransforms:true,

center: [101.7, 24.6],

zoom: 10,

autoResize:true,

sliderPosition:"bottom-right",

logo:false,

})       var googleimgLayer=new GoogleImageLayer()       var googleAnnoLayer=new GoogleImageAnnoLayer()

map.addLayer(googleimgLayer)

map.addLayer(googleAnnoLayer)       var measureTool=new deMeasureTools({

map:map

},"measureTools")

})

offset 自己的

目的: js中有一套方便的获取元素尺寸的办法就是offset家族;

div { width:220px border-left:2px solid redpadding:10px}

div.offsetWidth = 220 + 2 + 20

为什么不用 div.style.width 因为东西 只能得到行内的数值

如果 父级 都没有定位则以body 为准

这里的父级指的是所上一级 不仅仅指的是 父亲 还可以是 爷爷 曾爷爷 曾曾爷爷。。。。

offsetParent返回该对象的父级 (带有定位) 不一定是亲的爸爸

前面学过一个返回父亲(亲的)parentNode 有所区别

如果当前元素的父级元素没有进行CSS定位(position为absolute或relative),offsetParent为body。

如果当前元素的父级元素中有CSS定位(position为absolute或relative),offsetParent取最近的那个父级元素。

1.最大区别在于 offsetLeft 可以返回没有定位盒子的距离左侧的位置。 而 style.top 不可以 只有定位的盒子 才有 left top right

2.offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。

3.offsetTop 只读,而 style.top 可读写。

4.如果没有给 HTML 元素指定过 top 样式,则 style.top 返回的是空字符串。

5.最重要的区别 style.left 只能得到 行内样式 offsetLeft 随便

我们学过一些事件 : onmouseover onmouseoutonclick .....

event 单词翻译过来 事件 的意思

event 就是事件的对象指向的是 事件 是 onclick

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象,但支持的方式不同。

比如鼠标操作时候,会添加鼠标位置的相关信息到事件对象中。

普通浏览器支持 event

ie 678 支持 window.event

是以我们的 电脑屏幕 为基准点 测量

以我们的 文档(绝对定位) 的基准点 对齐

ie678 不认识

可视区域 为基准点 类似于固定定位

onmouseover onmouseout onclick

onmousemove当鼠标移动的时候就是说,鼠标移动一像素就会执行的事件

div.onmousemove = function() { 语句 }

当鼠标再div 身上移动的时候,就会执行。

他们相同点 都是 经过 div 才会触发

div.onmouseover只触发一次

div.onmousemove 每移动一像素,就会触发一次

onmouseup 当鼠标弹起

onmousedown 当鼠标按下的时候

1.拖动 原理 == 鼠标按下 接着 移动鼠标 。

bar.onmousedown = function(){

document.onmousemove = function(){

}

}

2.当我们按下鼠标的时候,就要记录当前 鼠标 的位置 - 大盒子的位置

算出 bar 当前 在 大盒子内的距离 。

我们知道 按下鼠标然后拖拽可以选择文字 的。

清除选中的内容

offset 自己的 偏移

offsetWidth得到自己的宽度

offsetHeight

构成 : width + padding + border

divwidth 200 border 3pxpadding-right: 15px

div offsetWidth =200 + 6 + 15 = 221

◆ offsetLeft和 offsetTop

div.offsetLeft

得到距离 这个 div 最近的 带有定位的 父 盒子 左边距离

◆ offsetParent 返回自己的父亲元素 (带有定位的)

parentNode这个返回亲父亲 不管父亲是否带有定位

◆ style.top 和 offsetTop

offsetTop 只读只可以得到结果 但是不能赋值

style.top能得到 (行内式 )但是可以给值

style.top 得到的是 25px

offsetTop 得到的是 25

◆ 事件对象 event

div.onclick = function(event) { } event 是点击的事件对象

event 集合点击事件的相关信息

pageX文档的 参考点

clientX可视区域

ScreenX 屏幕

◆ 常用事件

onmouseover 经过

onmouseout 离开

onmousemove 鼠标移动

var num = 0

div.onmouseover = function() { num++ console.log(num))} 1

div.onmousemove = function() { num++ console.log(num))}

onmousedown 按下鼠标

onmouseup 弹起鼠标

拖拽: 先按下鼠标 然后 移动鼠标

bar.onmousedown = funtion() {

document.onmousemove = function() {}

}

最大 window 对象 document对象

今日案例:筋斗云、点击跟随鼠标、放大镜案例素材获取

链接: http://pan.baidu.com/s/1jINmiOI

密码:homu