概述
turf.js是一个开源的空间分析库,主要用实现在网页端空间几何对象关系的计算,测距只是其中的一个简单功能。
计算两个点的距离:
计算两个点以上的线段的总长度:
源码地址:https://github.com/Turfjs/turf
官网文档: http://turfjs.org/
代码中需引入turf.js库,可下载到本地,也可引用互联网上的,互联网在线引用:
另外,还引入了dojo的订阅发布消息模式,使代码更具灵活性和方便测试。
topic.publish:用于发布消息,接收任意多个参数,第一参数为要发布的信息名字(唯一标识),其他参数为传递给订阅回调函数的参数。
topic.subscribe:用于订阅消息,接收两个参数,第一参数为要订阅的消息名字(唯一标识),第二参数为回调函数。
实现效果:
所有引用和地图均来自互联网,复制可直接打开,全部代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>arcgis api 结合turf.js实现测距</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
<style>
body,
html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: Arial;
}
#map {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 0px dashed black;
background-color: rgb(0, 38, 48);
}
</style>
</head>
<body>
<button type="button" onclick="mouseClick()">测距</button>
<button type="button" onclick="clearLine()">清除</button>
<div id="map">
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://js.arcgis.com/3.20"></script>
<script type="text/javascript">
dojo.require("dojo.topic") //引入发布订阅者模式
var map, mouseClick, clearLine;
require([
"esri/map",
'esri/Color',
'esri/geometry/Point',
"esri/geometry/Polyline",
"esri/symbols/TextSymbol",
"esri/layers/GraphicsLayer",
"esri/layers/ArcGISTiledMapServiceLayer",
'esri/graphic',
'esri/symbols/SimpleMarkerSymbol',
'esri/symbols/SimpleLineSymbol',
"esri/geometry/Extent",
"dojo/domReady!"
], function(
Map,
Color,
Point,
Polyline,
TextSymbol,
GraphicsLayer,
ArcGISTiledMapServiceLayer,
Graphic,
SimpleMarkerSymbol,
SimpleLineSymbol,
Extent
) {
//地图范围
var mapExtent = new Extent({
xmax: 113.799760210539,
xmin: 106.57095767482662,
ymax: 20.459116202966324,
ymin: 18.27952992162579,
spatialReference: {
wkid: 4326
}
})
map = new Map("map", {
extent: mapExtent,
sliderStyle: "small",
logo: false,
});
map.on('load', function () {
map.hideZoomSlider()
map.hidePanArrows()
map.disableDoubleClickZoom() //禁用双击缩放
})
//arcgis 在线切片底图图
var myTileLayer = new ArcGISTiledMapServiceLayer("http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer");
map.addLayer(myTileLayer)
var graphicLayer = new GraphicsLayer() //绘制图层
map.addLayer(graphicLayer)
var lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH,new Color([176, 196, 222]),3); //线样式
var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 8, //点样式
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([0, 0, 0]), 1),
new Color([47, 79, 79, 0.5]))
var linePath = [] //鼠标点击获得经纬度集合
var index = 0 //点击次数
//激活鼠标点击方法
mouseClick = function() {
//鼠标单击并发布消息
map.on('click',function(evt) {
let lon = evt.mapPoint.getLongitude() //获得单击经度
let lat = evt.mapPoint.getLatitude() //获得单击纬度
let point = new Point(lon, lat) //生成点矢量
dojo.topic.publish("getPoint", point) //发布单击点消息
dojo.topic.publish("getLonLat", [lon, lat]) //发布单击经纬度消息
})
//鼠标双击并发布消息
map.on('DblClick', function(evt) {
let lon = evt.mapPoint.getLongitude() //获得双击经度
let lat = evt.mapPoint.getLatitude() //获得双击纬度
let point = new Point(lon, lat) //生成点矢量
dojo.topic.publish("dblGetPoint", point) //发布双击点消息
dojo.topic.publish("dblGetLonLat", [lon, lat])//发布双击经纬度消息
})
}
//单击:订阅点消息并添加到地图
dojo.topic.subscribe("getPoint", function(point) {
let pointGraphic = new Graphic(point,markerSymbol)
graphicLayer.add(pointGraphic)
})
//单击:订阅经纬度消息
dojo.topic.subscribe("getLonLat", function(data) {
linePath.push(data) //将单击获得的经纬度放入集合
if (linePath.length>=2) { //如果单击次数大于等于2
//单击点画线并添加到地图
let line = new Polyline()
line.addPath(linePath)
let lineGraphic = new Graphic(line, lineSymbol)
graphicLayer.add(lineGraphic)
//测量两点间的距离
let from = turf.point(linePath[index]) //上次点击的点
let to = turf.point(linePath[index+1]) //当前点击的点
let options = {units: 'metres'} //单位:米
let distance = turf.distance(from, to, options).toFixed(2) //测距
let textPoint = new Point(linePath[index+1][0],linePath[index+1][1])
let t = lengthFormat(distance)
let textSymbol = new TextSymbol(t) //标注实例
textSymbol.setOffset(0, 5) //标注偏移
let textGraphic = new Graphic(textPoint, textSymbol)
graphicLayer.add(textGraphic) //添加标注到地图
index++ //点击次数自增1
}
})
//双击:订阅点消息并添加到地图
dojo.topic.subscribe("dblGetPoint", function(point) {
let pointGraphic = new Graphic(point,markerSymbol)
graphicLayer.add(pointGraphic)
})
//双击:订阅经纬度消息
dojo.topic.subscribe("dblGetLonLat", function(data) {
let lineLength = linePath.length //单击次数
linePath.push(data) //将双击点经纬度加入集合
if (linePath.length>=2) { //双击后如果总的次数>=2
//所有点生成的线添加到地图
let line = new Polyline()
line.addPath(linePath)
let lineGraphic = new Graphic(line, lineSymbol)
graphicLayer.add(lineGraphic)
//测量最后两点的距离
let from = turf.point(linePath[lineLength-1]) //最后单击的点
let to = turf.point(data) //双击的点
let options = {units: 'metres'} //单位:米
let distance = turf.distance(from, to, options).toFixed(2) //测距
//最后两点距离标注点
let endPoint = new Point(data[0],data[1]) //标注位置
let t = lengthFormat(distance)
console.log(t)
let textSymbol = new TextSymbol(t) //标注实例
textSymbol.setOffset(0, 5) //标注偏移
let textGraphic = new Graphic(endPoint, textSymbol)
graphicLayer.add(textGraphic) //添加标注到地图
//计算总长度和弹窗
let length = turf.lineString(linePath) //全部线段
let allLength = turf.length(length, {units: 'metres'}).toFixed(2) //计算全部线段长度
let lengthText = lengthFormat(allLength) //单位转换
map.infoWindow.setContent(lengthText) //弹窗内容
map.infoWindow.show(endPoint) //弹窗显示位置
linePath.length = 0 //下次测量前清空集合
index = 0 //双击后点击次数归零
}
else {
alert("最少需要两个点")
graphicLayer.clear() //清除
map.infoWindow.hide() //隐藏弹窗
linePath.length = 0 //下次测量前清空集合
}
})
//清除
clearLine = function() {
graphicLayer.clear()
map.infoWindow.hide()
}
//长度单位转换
function lengthFormat(length) {
if (length < 2000) {
return lengthText = "总长:" + length + "米"
}
else {
length = (length/1000).toFixed(2)
return lengthText = "总长:" + length + "千米"
}
}
});
</script>
</html>
最后
以上就是默默翅膀为你收集整理的arcgis api 结合turf.js实现测距的全部内容,希望文章能够帮你解决arcgis api 结合turf.js实现测距所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复