以本机为例
使用工具:arcmap,arcserver,tif转terrain工具;
准备数据:地形数据点云.shp
地形数据点云.shp —> 地形.tin —> 地形.tif —> 地形.terrain (具体方法就不细说了)
把“地形.terrain”文件夹放到..\Cesium1.45\Apps\mapserver目录下,以备后续使用
P.S.在磁盘跟目录新建文件夹ARCGISDATA,存放所有arcmap用到的文件
(1)3D分析工具 —> 可见性 —> 通视分析工具 —> 输入“分析路径line.shp”(line不能超出地形.tif范围)
得到通视分析结果(两个.shp文件,一条线,一个点)
(2)发布
勾选需要发布的要素
发布结果
Buffer同理
使用工具:vscode或pycharm(IDE随意),Cseium,ArcServer
先启动Cesium服务,以后使用是一定要记得开启Cesium服务,不然地图不会加载的。
Cesium使用方法不细说了,这里附上地形加载代码
查看地形是否加载
通视分析和缓冲区分析结果采用异步加载的方式,代码如下
HTML
分析结果加载
: (经度,纬度)
: (经度,纬度)
CSS
.shell {
position: fixed;
background-color: rgba(216, 207, 207, 1);
left: 5%;
top: 10%;
width: auto;
height: auto;
border: #080202 solid 5px;
}
.shell3{
position: fixed;
background-color:rgba(216, 207, 207, 1);
right: 5%;
bottom: 12%;
width: auto;
height: auto;
border: #080202 solid 3px;
}
JS
计算模块:
//获取鼠标位置
function getPosition() {
//得到当前三维场景
var scene = viewer.scene;
//得到当前三维场景的椭球体
var ellipsoid = scene.globe.ellipsoid;
//设置样式
var entity = viewer.entities.add({
label: {
show: false,
font: '24px Helvetica',
fillColor: Cesium.Color.SKYBLUE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(200, -50)
}
});
var longitudeString = null;
var latitudeString = null;
var cartesian = null;
// 定义当前场景的画布元素的事件处理
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
//设置鼠标移动事件的处理函数,这里负责监听x,y坐标值变化
handler.setInputAction(function (movement) {
//通过指定的椭球或者地图对应的坐标系,将鼠标的二维坐标转换为对应椭球体三维坐标
cartesian = viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid);
if (cartesian) {
//将笛卡尔坐标转换为地理坐标
var cartographic = ellipsoid.cartesianToCartographic(cartesian);
// //将弧度转为度的十进制度表示
longitudeString = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
latitudeString = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
//获取地理坐标和高度
// lonunit_m = cartesian.longitude;
// latunit_m = cartesian.latitude;
height = scene.globe.getHeight(cartographic);
entity.position = cartesian;
entity.label.show = true;
// entity.label.text = cartesia + '(' + cartographic.longitude + ', ' + cartographic.latitude + "," + height + ')';
entity.label.text =
'Cartesian: ' + cartesian + '\u00B0' +
'\nLon: ' + longitudeString +
'\nLat: ' + latitudeString +
'\nHeight: ' + height + '\n' + '\n' + '\n' + '\n';
} else {
entity.label.show = false;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 坐标输出
$(function () {
$(".No1point").click(function (event) {
$(window).unbind("dblclick");
$(window).dblclick(function (event) {
$("#aa").html(longitudeString);
$("#bb").html(latitudeString);
var lon = $("#aa").html();
var lat = $("#bb").html();
var entity = viewer.entities.add({
name: 'start point',
position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
point: {
color: Cesium.Color.YELLOW,
pixelSize: 30
}
});
});
});
$(".No2point").click(function (event) {
$(window).unbind("dblclick");
$(window).dblclick(function (event) {
$("#cc").html(longitudeString);
$("#dd").html(latitudeString);
var lon = $("#cc").html();
var lat = $("#dd").html();
var entity = viewer.entities.add({
name: 'end point',
position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
point: {
color: Cesium.Color.RED,
pixelSize: 30
}
});
});
});
$(".No3point").click(function (event) {
$(window).unbind("dblclick");
// $(window).dblclick(function (event) {
// console.log("结束");
// });
$("#result02").html(" 正在计算LOS,请等待...
");
$.ajax({
// url: 'http://localhost:5000/oneLinetoLOS',
url: '/oneLinetoLOS02',
// url: '/LinestoLOS',
data: {
a2: $('#aa').html(),
b2: $('#bb').html(),
c2: $('#cc').html(),
d2: $('#dd').html()
},
dataType: 'JSON',
type: 'GET',
success: function () {
$("#result02").html(" 计算完成,LOSline03查看
");
}
});
});
$(".No4point").click(function (event) {
$(window).unbind("dblclick");
$("#result02").html(" 正在计算Buffer,请等待...
");
$.ajax({
url: '/Buffer01',
data: {
a3: $('#aa').html(),
b3: $('#bb').html(),
c3: $('#cc').html(),
d3: $('#dd').html()
},
dataType: 'JSON',
type: 'GET',
success: function (responseText, status, xhr) {
if (responseText != '') {
$("#result02").html(" 计算完成,Buffer01查看
");
} else {
$('#result02').html(" error
");
}
}
});
});
});
}
getPosition();
ArcServer服务加载模块:
在F:\ARCGISDATA\python\templates目录下新建3个txt文件
LOSlineremove.txt;Buffer01.txt; 80LOSline01.txt
LOSlineremove.txt
Buffer01.txt
80LOSline01.txt
展示模块:
$(function () {
$('button#buttonLOS03').click(function (event) {
$.ajax({
url: "/80LOSline01.txt",
success: function (responseText, status, xhr) {
if (responseText != '') {
$('.LOSscri').html(responseText);
} else {
$('.LOSscri').html("没有搜索到 ");
}
}
})
});
$('button#buttonBuffer01').click(function (event) {
$.ajax({
url: "/Buffer01.txt",
success: function (responseText, status, xhr) {
if (responseText != '') {
$('.LOSscribuffer').html(responseText);
} else {
$('.LOSscribuffer').html("没有搜索到 ");
}
}
})
});
$('button#LOSCLEAR').click(function (event) {
//alert("键盘键松开触发,HTML: " + $('#search').val());
$.ajax({
url: "/LOSlineremove.txt", // 请求路径
// type: "GET", //请求方式
// data: $("form").serialize(),//请求参数
success: function (responseText, status, xhr) {//异步执行成功执行的回调函数
$('.LOSscri').html(responseText);//地图上打标志
}
})
});
});
FLASK框架教程:http://docs.jinkan.org/docs/flask/quickstart.html
ArcPy帮助文档:http://desktop.arcgis.com/zh-cn/arcmap/latest/analyze/arcpy/what-is-arcpy-.htm
通视分析
新建run.py文件,写入以下代码
#coding:utf-8
from flask import Flask, render_template, request, jsonify
import arcpy
from arcpy import env
# 自定义函数
from LonLat2XYpy2 import lonlat2xy
from Buffer_anatest import buffertest
/////////////////
# 鼠标点击地图,通视分析
@app.route('/oneLinetoLOS02')
def oneLinetoLOS02():
print("LOSana start")
# point_start = [93342.212,4308755.437]
# point_end = [93325.940, 4308611.767]
aa = request.args.get("a2", 0, type=float)
# print('aa: %s '%aa)
bb = request.args.get("b2", 0, type=float)
cc = request.args.get("c2", 0, type=float)
dd = request.args.get("d2", 0, type=float)
pointstart = lonlat2xy(aa, bb)
pointend = lonlat2xy(cc, dd)
# print('point_start: %s ' % (pointstart,))
# print('point_end: %s ' % (pointend,))
line01 = [pointstart, pointend]
line02 = [pointstart, pointend]
feature_info = [line01, line02]
# print('line01: %s '%line01)
features = []
for feature in feature_info:
features.append(
arcpy.Polyline(
arcpy.Array([arcpy.Point(*coords) for coords in feature])))
# Set workspace
env.workspace = "F:/ARCGISDATA"
# Execute Delete
LOSline01 = "80LOSline01.shp"
arcpy.Delete_management(LOSline01)
LOSposition = "80LOSposition01.shp"
arcpy.Delete_management(LOSposition)
insurface01 = "alltif1.tif"
inline01 = features
outlos01 = "80LOSline01.shp"
outobs01 = "80LOSposition01.shp"
# print('in_line01: %s '%inline01)
arcpy.LineOfSight_3d(insurface01, inline01, outlos01, outobs01)
print("LOSana end")
return jsonify(result=line02)
缓冲区分析
新建Buffer_anatest.py
# Import system modules
import arcpy
from arcpy import env
def buffertest(p1,p2):
print("buffertest start")
env.workspace = "F:/ARCGISDATA"
line01 = [p1, p2]
line02 = [p2, p1]
feature_info = [line01, line02]
# print('line01: %s ' % line01)
features = []
for feature in feature_info:
features.append(
arcpy.Polyline(
arcpy.Array([arcpy.Point(*coords) for coords in feature])))
# Set local variables
infeatures = features
outfeatures = "bufferana2.shp"
bufferDistance = 30
# Execute Buffer
arcpy.Buffer_analysis(infeatures, outfeatures, bufferDistance)
print("buffertest end")
return 1
高斯投影函数:(由于在arcmap处理地图时,使用的Xian_80投影坐标系,所以这里需要做经纬度坐标转投影坐标)
LatLon2XYpy2.py
# coding:utf-8
# 参考文献《基于高斯投影的经纬度距离参数修正方法》
import math
def lonlat2xy(longitude, latitude):
# WGS-84
# b = 6356752.3142
# c = 6399593.6258
# alpha = 1 / 298.257223563
# e2 = 0.0066943799013
# epep = 0.00673949674227
# 80
a = 6378140.0
# b = 6356755.288157528
e1 = 0.00669438499959
e2 = 0.00673950181947
# alpha = 1 / 298.2570
B = (math.pi / 180.0) * latitude
Lcm = 126.0 # Central_Meridian: 126.0
tsin = math.sin(B)
tcos = math.cos(B)
t = math.tan(B)
A = (math.pi / 180.0) * (longitude - Lcm) * tcos
C = e2 * pow(tcos, 2)
M = a * ((1 - e1 / 4.0 - pow(e1, 2) * 3.0 / 64.0 - pow(e1, 3) * 5.0 / 256.0) * B
- (pow(e1, 2) * 3.0 / 8.0 + pow(e1, 2) * 3.0 / 32.0 + pow(e1, 3) * 45.0 / 1024.0) * math.sin(2.0 * B)
+ (pow(e1, 2) * 15.0 / 256.0 + pow(e1, 3) * 45.0 / 1024.0) * math.sin(4.0 * B)
- pow(e1, 3) * 35.0 / 3072.0 * math.sin(6 * B))
N = a / math.sqrt(1 - e1 * pow(tsin, 2))
# zi dai pian yi - 15535.6 i dont know
y = - 15535.6 + M + N * t * (0.5 * pow(A, 2) + (5.0 - pow(t, 2) + 9.0 * C + 4 * pow(C, 2)) * pow(A, 4) / 24.0
+ (61.0 - 58.0 * pow(t, 2) + pow(t, 4) + 270 * C -330 * pow(t, 2) * C) * pow(A, 6) / 720.0)
x = 500000.0 + N * (A + (1.0 - pow(t, 2) + C) * pow(A, 3) / 6.0
+ (5.0 - 18.0 * pow(t, 2) + pow(t, 4) + 14.0 * C - 58.0 * C * pow(t, 2)) * pow(A, 5) / 120.0)
# x0 = 4309134.741- x
# y0 = 92760.635 - y
# return x0, y0,x ,y
return x, y
在run.py中加入以下代码,下面展示完整run.py文件
#coding:utf-8
from flask import Flask, render_template, request, jsonify
import arcpy
from arcpy import env
# 自定义函数
from LonLat2XYpy2 import lonlat2xy
from Buffer_anatest import buffertest
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello World
'
@app.route('/80LOSline01.txt')
def txt01():
return render_template('80LOSline01.txt')
@app.route('/Buffer01.txt')
def txt02():
return render_template('Buffer01.txt')
@app.route('/LOSlineremove.txt')
def txt03():
return render_template('LOSlineremove.txt')
# 地图主界面
@app.route('/Intro_Cesium_python.html')
def los():
return render_template('Cesium_python.html')
# 鼠标点击地图,通视分析
@app.route('/oneLinetoLOS02')
def oneLinetoLOS02():
print("LOSana start")
# point_start = [93342.212,4308755.437]
# point_end = [93325.940, 4308611.767]
aa = request.args.get("a2", 0, type=float)
# print('aa: %s '%aa)
bb = request.args.get("b2", 0, type=float)
cc = request.args.get("c2", 0, type=float)
dd = request.args.get("d2", 0, type=float)
pointstart = lonlat2xy(aa, bb)
pointend = lonlat2xy(cc, dd)
# print('point_start: %s ' % (pointstart,))
# print('point_end: %s ' % (pointend,))
line01 = [pointstart, pointend]
line02 = [pointstart, pointend]
feature_info = [line01, line02]
features = []
for feature in feature_info:
features.append(
arcpy.Polyline(
arcpy.Array([arcpy.Point(*coords) for coords in feature])))
# Set workspace
env.workspace = "F:/ARCGISDATA"
# Execute Delete
LOSline01 = "80LOSline01.shp"
arcpy.Delete_management(LOSline01)
LOSposition = "80LOSposition01.shp"
arcpy.Delete_management(LOSposition)
insurface01 = "alltif1.tif"
inline01 = features
outlos01 = "80LOSline01.shp"
outobs01 = "80LOSposition01.shp"
arcpy.LineOfSight_3d(insurface01, inline01, outlos01, outobs01)
print("LOSana end")
return jsonify(result=line02)
# 鼠标点击地图-缓冲区分析
@app.route('/Buffer01')
def Buffer01():
print("Buffer01 start")
aa = request.args.get("a3", 0, type=float)
bb = request.args.get("b3", 0, type=float)
cc = request.args.get("c3", 0, type=float)
dd = request.args.get("d3", 0, type=float)
pointstart = lonlat2xy(aa, bb)
pointend = lonlat2xy(cc, dd)
Bufline01 = "bufferana2.shp"
arcpy.Delete_management(Bufline01)
print("jieguo start")
jieguo = buffertest(pointstart, pointend)
print("jieguo end")
return jsonify(result=jieguo)
if __name__ == '__main__':
app.run(debug = True)
使用Pycharm打开F:\ARCGISDATA\文件夹
点击File —> Default Settings... —> 添加Flask模块,添加Python2.7路径
右击run.py,点击Run‘run’,结果如下
在浏览器输入http://127.0.0.1:5000/Intro_Cesium_python.html
即可访问网页