var MapUtil = {
|
_map: '',
|
_satellite: '',
|
_object3Dlayer: '',
|
_canvas: '',
|
_customLayer: '',
|
_dpi: Util.dpi(),
|
_isDragging: false,
|
|
init: function (elementId) {
|
this._map = new AMap.Map(elementId, {
|
resizeEnable: true,
|
center: [121.6039283, 31.25295567],
|
zoom: 12,
|
});
|
},
|
|
setCenter: function (lnglat) {
|
if (this._isDragging) {
|
return;
|
}
|
var now = new Date();
|
if (
|
this.lasttime == undefined ||
|
now.getTime() - this.lasttime.getTime() >= 1000
|
) {
|
this._map.setCenter(lnglat);
|
this.lasttime = now;
|
}
|
},
|
|
clearMap: function () {
|
this._map.clearMap();
|
this._car = undefined;
|
},
|
|
clear3D: function () {
|
this._object3Dlayer.remove(this._cylinder);
|
this._cylinder = undefined;
|
},
|
|
addViews: function (views, fit) {
|
this._map.add(views);
|
if (fit != false) {
|
this._map.setFitView(views);
|
}
|
},
|
|
removeViews: function (views) {
|
this._map.remove(views);
|
},
|
|
addElasticMarkers(markers) {
|
const zoomStyleMapping = {
|
14: 0,
|
15: 0,
|
16: 0,
|
17: 0,
|
18: 0,
|
19: 0,
|
20: 0,
|
};
|
const mList = [];
|
markers.forEach((m) => {
|
let name = m.name;
|
if (m.name.length > 9) {
|
const i = m.name.length / 2;
|
const str1 = m.name.slice(0, i + 1);
|
const str2 = m.name.slice(i + 1, m.name.length);
|
name = `${str1}<br />${str2}`;
|
}
|
var marker = new AMap.ElasticMarker({
|
title: m.name,
|
zoom: [14, 20],
|
position: new AMap.LngLat(m.lng, m.lat),
|
styles: [
|
{
|
icon: {
|
img: './asset/mipmap/scene.png',
|
size: [16, 16], //可见区域的大小
|
ancher: [8, 16], //锚点
|
fitZoom: 14, //最合适的级别
|
scaleFactor: 1.4, //地图放大一级的缩放比例系数
|
maxScale: 2, //最大放大比例
|
minScale: 1, //最小放大比例
|
},
|
label: {
|
content: `<div>${name}</div>`,
|
offset: [-35, 0],
|
position: 'BM',
|
minZoom: 15,
|
},
|
},
|
],
|
zoomStyleMapping: zoomStyleMapping,
|
});
|
mList.push(marker);
|
});
|
this.addViews(mList, false);
|
return mList;
|
},
|
|
_markers: [],
|
/**
|
*
|
* @param {*} fDatas 所有走航监测因子数据
|
* @param {*} _factor 当前选中的监测因子数据
|
* @param {*} lineChart 需要联动的折线图
|
* @param {*} onClick 标记点击事件回调
|
* @param {boolean} merge 是否和之前的标记合并绘制
|
*/
|
drawMarker: function (fDatas, _factor, lineChart, onClick, merge) {
|
if (!this._showDataMarker) {
|
return;
|
}
|
const interval = this._getMarkerInterval();
|
if (fDatas) {
|
if (merge != true && this._markers.length > 0) {
|
this.removeViews(this._markers);
|
this._markers = [];
|
}
|
const lnglats = fDatas.lnglats_GD;
|
const factor = fDatas.factor;
|
|
for (let i = 0; i < lnglats.length; i++) {
|
// 创建一个 Marker 实例:
|
var marker = new AMap.Marker({
|
position: new AMap.LngLat(lnglats[i][0], lnglats[i][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
|
title: `${fDatas.times[i]}\r\n${_factor.factorName}: ${_factor.datas[i].factorData} mg/m³`,
|
offset: new AMap.Pixel(-13, -12),
|
// anchor: 'center',
|
icon: new AMap.Icon({
|
image: './asset/mipmap/ic_up_white.png',
|
// imageSize: [12, 12],
|
}),
|
});
|
marker.on('click', (event) => {
|
// console.log(event);
|
// console.log(i);
|
// 绘制溯源扇形区域
|
var windDir = 0;
|
const d = factor[17].datas[i];
|
if (d != undefined) {
|
windDir = d.factorData;
|
}
|
var windSpeed = 1;
|
const s = factor[16].datas[i];
|
if (s != undefined) {
|
windSpeed = s.factorData;
|
}
|
// 1. 绘制扇形区域
|
this.drawSector3(lnglats[i], windDir, windSpeed);
|
|
// 2. 绘制对话框
|
const window = DialogUtil.createInfoWindow(fDatas, i, () => {
|
// 移除扇形区域
|
this.clearSector3();
|
});
|
window.open(MapUtil._map, lnglats[i]);
|
|
// 3. 趋势图跳转定位
|
const progress = FChart.locate(
|
lineChart.chart,
|
lineChart.option,
|
i,
|
_factor.factorName
|
);
|
// 4. 表格数据跳转定位
|
Table.locate(i);
|
// 5. 自定义点击事件
|
onClick(progress);
|
});
|
// this._map.add(marker);
|
this._markers.push(marker);
|
}
|
}
|
const _markers = [];
|
for (let i = 0; i < this._markers.length; i += interval) {
|
_markers.push(this._markers[i]);
|
}
|
this.removeViews(this._markers);
|
this.addViews(_markers, false);
|
},
|
|
_massMarks: undefined,
|
/**
|
* 绘制海量点标记
|
* @param {*} fDatas 所有走航监测因子数据
|
* @param {*} _factor 当前选中的监测因子数据
|
* @param {*} lineChart 需要联动的折线图
|
* @param {*} onClick 标记点击事件回调
|
*/
|
drawMassMarks(fDatas, _factor, lineChart, onClick) {
|
if (!this._showDataMarker) {
|
return;
|
}
|
if (this._massMarks) {
|
this.removeViews(this._massMarks);
|
this._massMarks = undefined;
|
}
|
const lnglats = fDatas.lnglats_GD;
|
const factor = fDatas.factor;
|
var data = [];
|
for (let i = 0; i < lnglats.length; i++) {
|
data.push({
|
lnglat: lnglats[i], //点标记位置
|
name: `${fDatas.times[i]}<br/>${_factor.factorName}: ${_factor.datas[i].factorData} mg/m³`,
|
id: i,
|
});
|
}
|
|
// 创建样式对象
|
var styleObject = {
|
url: 'https://a.amap.com/jsapi_demos/static/images/mass1.png',
|
// url: './asset/mipmap/ic_up_white.png', // 图标地址
|
size: new AMap.Size(11, 11), // 图标大小
|
anchor: new AMap.Pixel(5, 5), // 图标显示位置偏移量,基准点为图标左上角
|
};
|
var massMarks = new AMap.MassMarks(data, {
|
zIndex: 5, // 海量点图层叠加的顺序
|
zooms: [15, 18], // 在指定地图缩放级别范围内展示海量点图层
|
style: styleObject, // 设置样式对象
|
});
|
massMarks.on('click', (event) => {
|
const i = event.data.id;
|
// 绘制溯源扇形区域
|
var windDir = 0;
|
const d = factor[17].datas[i];
|
if (d != undefined) {
|
windDir = d.factorData;
|
}
|
var windSpeed = 1;
|
const s = factor[16].datas[i];
|
if (s != undefined) {
|
windSpeed = s.factorData;
|
}
|
// 1. 绘制扇形区域
|
this.drawSector3(lnglats[i], windDir, windSpeed);
|
|
// 2. 绘制对话框
|
DialogUtil.openNewWindow(fDatas, i, MapUtil._map, lnglats[i], () => {
|
// 移除扇形区域
|
// this.clearSector3();
|
});
|
|
// 3. 趋势图跳转定位
|
const progress = FChart.locate(
|
lineChart.chart,
|
lineChart.option,
|
i,
|
_factor.factorName
|
);
|
// 4. 表格数据跳转定位
|
Table.locate(i);
|
// 5. 自定义点击事件
|
onClick(progress);
|
});
|
var marker = new AMap.Marker({
|
content: ' ',
|
map: this._map,
|
offset: new AMap.Pixel(13, 12),
|
});
|
var timeout;
|
massMarks.on('mouseover', (e) => {
|
if (timeout) {
|
clearTimeout(timeout);
|
}
|
marker.setPosition(e.data.lnglat);
|
marker.setLabel({ content: e.data.name });
|
this.addViews(marker, false);
|
timeout = setTimeout(() => {
|
this.removeViews(marker);
|
}, 2000);
|
});
|
this._massMarks = massMarks;
|
this.addViews(massMarks, false);
|
},
|
|
_polyline: '',
|
drawLine: function (lnglats) {
|
this._map.remove(this._polyline);
|
var path = this.parse2LngLat(lnglats);
|
// 创建折线实例
|
this._polyline = new AMap.Polyline({
|
path: path,
|
strokeStyle: 'solid',
|
isOutline: true,
|
borderWeight: 2,
|
outlineColor: 'white',
|
strokeWeight: 4, // 线条宽度,默认为 1
|
strokeColor: '#CC0000', // 线条颜色
|
lineJoin: 'round', // 折线拐点连接处样式
|
showDir: true,
|
});
|
// 将折线添加至地图实例
|
this._map.add(this._polyline);
|
return this._polyline;
|
},
|
|
/**
|
* 根据坐标点、距离和角度,得到另一个坐标点
|
* @param {*} pos
|
* @param {*} distance 米
|
* @param {*} angle
|
*/
|
_getLatLon: function (pos, distance, angle) {
|
var Ea = 6378137; // 赤道半径
|
var Eb = 6356725; // 极半径
|
var dx = distance * Math.sin((angle * Math.PI) / 180);
|
var dy = distance * Math.cos((angle * Math.PI) / 180);
|
var ec = Eb + ((Ea - Eb) * (90.0 - pos[1])) / 90.0;
|
var ed = ec * Math.cos((pos[1] * Math.PI) / 180);
|
var lng = ((dx / ed + (pos[0] * Math.PI) / 180.0) * 180.0) / Math.PI;
|
var lat = ((dy / ec + (pos[1] * Math.PI) / 180.0) * 180.0) / Math.PI;
|
return [lng, lat];
|
},
|
|
_defaultDeg: 30,
|
_sector: undefined,
|
_sectorViews3: {},
|
drawSector3: function (lnglat, windDir, windSpeed) {
|
if (windSpeed > 10) {
|
return;
|
}
|
if (MapUtil._sectorViews3['text10'] != undefined) {
|
this.clearSector3();
|
}
|
|
var sector = new AMap.Object3D.Mesh();
|
sector.transparent = true;
|
sector.backOrFront = 'both';
|
|
var unit = 5;
|
|
var sDeg = windDir - this._defaultDeg; //扇形起始角度(以上方作为0度)
|
// sDeg = sDeg < 0 ? sDeg + 360 : sDeg
|
var eDeg = windDir + this._defaultDeg; //扇形结束角度
|
// eDeg = eDeg < 0 ? eDeg + 360 : eDeg
|
|
var distance = windSpeed * 10 * 60; //半径(风速*时间)
|
var lnglat2 = this._getLatLon(lnglat, distance, sDeg);
|
var lnglat3 = this._getLatLon(lnglat, distance, windDir);
|
var lnglat4 = this._getLatLon(lnglat, distance, eDeg);
|
var list = this.parse2LngLat([lnglat, lnglat2, lnglat3, lnglat4]);
|
|
var distance2 = windSpeed * 5 * 60; //半径(风速*时间)
|
var lnglat2_2 = this._getLatLon(lnglat, distance2, sDeg);
|
var lnglat2_3 = this._getLatLon(lnglat, distance2, windDir);
|
var lnglat2_4 = this._getLatLon(lnglat, distance2, eDeg);
|
var list2 = this.parse2LngLat([lnglat2_2, lnglat2_3, lnglat2_4]);
|
|
var p0 = this.lngLatToGeodeticCoord([lnglat])[0];
|
var geometry = sector.geometry;
|
|
var count = distance / unit;
|
var unitDeg = (eDeg - sDeg) / count;
|
for (let i = 0; i < count; i++) {
|
var angle1 = sDeg + unitDeg * i;
|
var angle2 = sDeg + unitDeg * (i + 1);
|
|
var l1 = this._getLatLon(lnglat, distance, angle1);
|
var l2 = this._getLatLon(lnglat, distance, angle2);
|
var l3 = this._getLatLon(lnglat, distance2, angle1);
|
var l4 = this._getLatLon(lnglat, distance2, angle2);
|
|
var coors = this.lngLatToGeodeticCoord([l1, l2, l3, l4]);
|
l1 = coors[0];
|
l2 = coors[1];
|
l3 = coors[2];
|
l4 = coors[3];
|
|
// 内测扇形
|
geometry.vertices.push(p0.x, p0.y, 0);
|
geometry.vertices.push(l3.x, l3.y, 0);
|
geometry.vertices.push(l4.x, l4.y, 0);
|
// 外侧扇形
|
geometry.vertices.push(l3.x, l3.y, 0);
|
geometry.vertices.push(l4.x, l4.y, 0);
|
geometry.vertices.push(l1.x, l1.y, 0);
|
geometry.vertices.push(l2.x, l2.y, 0);
|
// console.log(l3.x + ',' + l3.y + ' | ' + l1.x + ',' + l1.y);
|
|
// 内测扇形颜色
|
geometry.vertexColors.push(1, 0.11, 0.25, 0.6);
|
geometry.vertexColors.push(1, 0.11, 0.25, 0.6);
|
geometry.vertexColors.push(1, 0.11, 0.25, 0.6);
|
//外侧扇形颜色
|
geometry.vertexColors.push(1, 0.37, 0.07, 0.5);
|
geometry.vertexColors.push(1, 0.37, 0.07, 0.5);
|
geometry.vertexColors.push(1, 0.37, 0.07, 0.5);
|
geometry.vertexColors.push(1, 0.37, 0.07, 0.5);
|
|
var index = i * 7;
|
geometry.faces.push(index, index + 1, index + 2);
|
geometry.faces.push(index + 3, index + 4, index + 5);
|
geometry.faces.push(index + 4, index + 5, index + 6);
|
}
|
this._object3Dlayer.add(sector);
|
this._sector = sector;
|
|
distance = distance.toFixed(0);
|
distance2 = distance2.toFixed(0);
|
const zoomStyleMapping = {
|
14: 0,
|
15: 0,
|
16: 0,
|
17: 0,
|
18: 0,
|
19: 0,
|
20: 0,
|
};
|
//10分钟扇形
|
var text15 = new AMap.ElasticMarker({
|
zoom: [14, 20],
|
position: list[2],
|
styles: [
|
{
|
icon: {
|
img: './asset/mipmap/location.png',
|
size: [16, 16], //可见区域的大小
|
ancher: [8, 16], //锚点
|
fitZoom: 18, //最合适的级别
|
scaleFactor: 1, //地图放大一级的缩放比例系数
|
maxScale: 2, //最大放大比例
|
minScale: 1, //最小放大比例
|
},
|
label: {
|
content: '<div>10分钟</div>',
|
offset: [-35, 0],
|
position: 'BM',
|
minZoom: 15,
|
},
|
},
|
],
|
zoomStyleMapping: zoomStyleMapping,
|
});
|
MapUtil._sectorViews3['text10'] = text15;
|
var textM = new AMap.ElasticMarker({
|
zoom: [14, 20],
|
position: list[1],
|
styles: [
|
{
|
icon: {
|
img: './asset/mipmap/location.png',
|
size: [16, 16], //可见区域的大小
|
ancher: [8, 16], //锚点
|
fitZoom: 18, //最合适的级别
|
scaleFactor: 1, //地图放大一级的缩放比例系数
|
maxScale: 2, //最大放大比例
|
minScale: 1, //最小放大比例
|
},
|
label: {
|
content: `<div>${distance}m</div>`,
|
offset: [-35, 0],
|
position: 'BM',
|
minZoom: 15,
|
},
|
},
|
],
|
zoomStyleMapping: zoomStyleMapping,
|
});
|
MapUtil._sectorViews3['textM'] = textM;
|
MapUtil._map.add(MapUtil._sectorViews3['text10']);
|
MapUtil._map.add(MapUtil._sectorViews3['textM']);
|
|
//5分钟扇形
|
pList = list2;
|
path = [
|
[pList[0].lng, pList[0].lat],
|
[pList[1].lng, pList[1].lat, pList[2].lng, pList[2].lat],
|
];
|
|
var text5 = new AMap.ElasticMarker({
|
position: pList[1],
|
styles: [
|
{
|
icon: {
|
img: './asset/mipmap/location.png',
|
size: [16, 16], //可见区域的大小
|
ancher: [8, 16], //锚点
|
fitZoom: 18, //最合适的级别
|
scaleFactor: 1, //地图放大一级的缩放比例系数
|
maxScale: 2, //最大放大比例
|
minScale: 1, //最小放大比例
|
},
|
label: {
|
content: `<div>5分钟</div>`,
|
offset: [-35, 0],
|
position: 'BM',
|
minZoom: 15,
|
},
|
},
|
],
|
zoomStyleMapping: zoomStyleMapping,
|
});
|
MapUtil._sectorViews3['text5'] = text5;
|
var textM5 = new AMap.ElasticMarker({
|
position: pList[0],
|
styles: [
|
{
|
icon: {
|
img: './asset/mipmap/location.png',
|
size: [16, 16], //可见区域的大小
|
ancher: [8, 16], //锚点
|
fitZoom: 18, //最合适的级别
|
scaleFactor: 1, //地图放大一级的缩放比例系数
|
maxScale: 2, //最大放大比例
|
minScale: 1, //最小放大比例
|
},
|
label: {
|
content: `<div>${distance2}m</div>`,
|
offset: [-35, 0],
|
position: 'BM',
|
minZoom: 15,
|
},
|
},
|
],
|
zoomStyleMapping: zoomStyleMapping,
|
});
|
MapUtil._sectorViews3['textM5'] = textM5;
|
MapUtil._map.add(MapUtil._sectorViews3['textM5']);
|
MapUtil._map.add(MapUtil._sectorViews3['text5']);
|
|
// 查询范围内的监测站点
|
SceneUtil.searchByCoordinate(lnglat[0], lnglat[1], distance);
|
},
|
|
clearSector3: function () {
|
var list = [];
|
for (const key in this._sectorViews3) {
|
list.push(this._sectorViews3[key]);
|
}
|
this.removeViews(list);
|
this._object3Dlayer.remove(this._sector);
|
},
|
|
parse2LngLat: function (lnglats) {
|
// 创建包含4个节点的折线及文字标注
|
var path = [];
|
lnglats.forEach(function (value) {
|
path.push(new AMap.LngLat(value[0], value[1]));
|
});
|
return path;
|
},
|
|
//*****************3d相关*************************
|
_margin: 0.00025,
|
//监测数据
|
_factorDatas: {
|
lnglats: [],
|
heights: [],
|
type: '',
|
},
|
//当前选中的监测因子数据
|
_factor: {},
|
_zoomFirst: true,
|
_onMapZoom: function () {
|
// 首次地图缩放监听不执行(因为设定监听函数后会立即执行一次,可能官方函数有相关参数,后续待修改)
|
if (this._zoomFirst) {
|
this._zoomFirst = false;
|
return;
|
}
|
const fDatas = MapUtil._factorDatas;
|
const factor = MapUtil._factor;
|
// MapUtil._object3Dlayer.clear()
|
// MapUtil.drawMesh(f.lnglats, f.heights, f.type, false)
|
MapUtil.drawMesh2(fDatas, factor);
|
MapUtil.drawMarker();
|
},
|
|
init3D: function (elementId) {
|
//setFeatures(feature:Array)
|
var that = this;
|
this._map = new AMap.Map(elementId, {
|
rotateEnable: true,
|
pitchEnable: true,
|
alwaysRender: false,
|
showLabel: true,
|
showBuildingBlock: true,
|
mapStyle: 'amap://styles/e1e78509de64ddcd2efb4cb34c6fae2a',
|
features: ['bg', 'road'],
|
pitch: 45, // 地图俯仰角度,有效范围 0 度- 83 度
|
viewMode: '3D', // 地图模式
|
resizeEnable: true,
|
center: [121.6039283, 31.25295567],
|
zooms: [3, 18],
|
zoom: 14,
|
});
|
// 卫星图层
|
this._satellite = new AMap.TileLayer.Satellite();
|
this._satellite.show();
|
this._map.add([this._satellite]);
|
this._map.addControl(
|
new AMap.ControlBar({
|
position: {
|
right: '300px',
|
top: '260px',
|
},
|
})
|
);
|
|
// 默认把地图工具箱关闭
|
// var closeControlbar = setInterval(() => {
|
// $('.amap-controlbar').hide();
|
// }, 100);
|
// 地图图块加载完成后触发
|
// this._map.on('complete', function () {
|
// $('.amap-controlbar').hide();
|
// clearInterval(closeControlbar);
|
// });
|
|
// AMap.plugin(['AMap.ControlBar', 'AMap.MapType'], function() { //异步同时加载多个插件
|
// 在图面添加类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
|
// MapUtil._map.addControl(new AMap.MapType({
|
// position: {
|
// left: '10px',
|
// top: '300px'
|
// }
|
// }));
|
// });
|
this._object3Dlayer = new AMap.Object3DLayer();
|
this._map.add(this._object3Dlayer);
|
|
this._canvas = document.createElement('canvas');
|
this._customLayer = new AMap.CustomLayer(this._canvas, {
|
zooms: [3, 20],
|
alwaysRender: true, //缩放过程中是否重绘,复杂绘制建议设为false
|
zIndex: 1,
|
opacity: 0.6,
|
});
|
this._customLayer.setMap(this._map);
|
|
// 设置地图拖拽监听事件
|
this._map.on('dragstart', function () {
|
clearTimeout(that.dragEndEvent);
|
that._isDragging = true;
|
});
|
this._map.on('dragend', function () {
|
that.dragEndEvent = setTimeout(() => {
|
that._isDragging = false;
|
}, 8000);
|
});
|
},
|
|
_feature: false,
|
/**
|
* 设置地图显示的内容
|
* @param {*} type
|
*/
|
setFeatures: function () {
|
this._feature = !this._feature;
|
if (!this._feature) {
|
this._map.setFeatures(['bg', 'road']);
|
return '地物标注:关';
|
} else {
|
this._map.setFeatures(['bg', 'road', 'point', 'building']);
|
return '地物标注:开';
|
}
|
},
|
|
_showLayer: true,
|
/**
|
* 切换图层
|
*/
|
toggleLayer: function () {
|
this._showLayer = !this._showLayer;
|
if (this._showLayer) {
|
this._satellite.show();
|
return '卫星地图:开';
|
} else {
|
this._satellite.hide();
|
return '卫星地图:关';
|
}
|
},
|
|
_controlbar: true,
|
/**
|
* 地图工具箱
|
*/
|
toggleControlbar: function () {
|
this._controlbar = !this._controlbar;
|
if (this._controlbar) {
|
$('.amap-controlbar').show();
|
return '控制罗盘:开';
|
} else {
|
$('.amap-controlbar').hide();
|
return '控制罗盘:关';
|
}
|
},
|
|
_showDataMarker: true,
|
toggleDataMarker() {
|
this._showDataMarker = !this._showDataMarker;
|
if (this._showDataMarker) {
|
this.addViews(this._markers, false);
|
return '数据标记:开';
|
} else {
|
this.removeViews(this._markers);
|
return '数据标记:关';
|
}
|
},
|
|
/**
|
* 坐标拾取功能
|
*/
|
_locationMarker: undefined,
|
_locationText: undefined,
|
_onClickListener: function (e) {
|
var text = `经度: ${e.lnglat.getLng()}<br/>纬度: ${e.lnglat.getLat()}`;
|
if (MapUtil._locationMarker == undefined) {
|
var textM = new AMap.Text({
|
style: {
|
'font-size': '12px',
|
},
|
text: text,
|
position: e.lnglat,
|
offset: new AMap.Pixel(0, 30),
|
});
|
// textM.setStyle()
|
|
var icon = new AMap.Icon({
|
size: new AMap.Size(60, 60),
|
imageSize: new AMap.Size(60, 60),
|
image: './asset/mipmap/pungent.png',
|
});
|
var marker = new AMap.Marker({
|
position: e.lnglat,
|
// icon: icon,
|
// anchor: 'top-center',
|
content:
|
'<i class="fa fa-map-marker fa-2x" style="color: #E6DB06;" aria-hidden="true"></i>',
|
});
|
MapUtil._map.add(marker);
|
MapUtil._map.add(textM);
|
MapUtil._locationMarker = marker;
|
MapUtil._locationText = textM;
|
} else {
|
MapUtil._locationMarker.setPosition(e.lnglat);
|
MapUtil._locationText.setPosition(e.lnglat);
|
MapUtil._locationText.setText(text);
|
}
|
},
|
_isOpen: false,
|
locationMark: function (onClickListener) {
|
this._isOpen = !this._isOpen;
|
if (onClickListener == undefined) {
|
onClickListener = this._onClickListener;
|
}
|
if (this._isOpen) {
|
this._map.on('click', onClickListener);
|
return '坐标拾取:开';
|
} else {
|
this._map.off('click', onClickListener);
|
this._map.remove([this._locationMarker, this._locationText]);
|
this._locationMarker = undefined;
|
this._locationText = undefined;
|
return '坐标拾取:关';
|
}
|
},
|
|
_prepare4convert: function (lnglats) {
|
var coor = [];
|
var maxLength = 1000;
|
var start = 0;
|
var end = start + maxLength;
|
while (end <= lnglats.length) {
|
coor.push(lnglats.slice(start, end));
|
start += maxLength;
|
end += maxLength;
|
}
|
if (start < lnglats.length) {
|
coor.push(lnglats.slice(start));
|
}
|
return coor;
|
},
|
|
/**
|
* 将gps经纬度转换为高德地图经纬度
|
* @param {*} lnglats
|
* @param {*} callback
|
*/
|
_convertLatlng: function (index, coor, lnglats, callback) {
|
if (index < coor.length) {
|
var path = MapUtil.parse2LngLat(coor[index]);
|
AMap.convertFrom(path, 'gps', function (status, result) {
|
if (result.info === 'ok') {
|
lnglats.push.apply(lnglats, result.locations);
|
MapUtil._convertLatlng(index + 1, coor, lnglats, callback);
|
}
|
});
|
} else {
|
callback(lnglats);
|
}
|
},
|
|
convertFromGPS: function (gps, callback) {
|
var coor = MapUtil._prepare4convert(gps);
|
MapUtil._convertLatlng(0, coor, [], function (result) {
|
var gd = [];
|
result.forEach((r) => {
|
gd.push([r.lng, r.lat]);
|
});
|
callback(gd);
|
});
|
},
|
|
lngLatToGeodeticCoord: function (lnglats_GD) {
|
var coors_GD = [];
|
|
for (let i = 0; i < lnglats_GD.length; i++) {
|
var gd = lnglats_GD[i];
|
var r = new AMap.LngLat(...gd);
|
var p = MapUtil._map.lngLatToGeodeticCoord(r);
|
// **记录转换后的3D地图图形坐标
|
coors_GD.push(p);
|
}
|
return coors_GD;
|
},
|
|
_cylinder: undefined, // 3d图形
|
_minH: -1, // 当前绘制的图形中的最小高度
|
_maxH: -1, // 当前绘制的图形中的最大高度
|
drawMesh_Test: function (fDatas, factor, merge, setCenter) {
|
const lnglats_GD = fDatas.lnglats_GD;
|
const coors_GD = fDatas.coors_GD;
|
const heights = factor.heights;
|
const colors = factor.colors;
|
const bColor = factor.bottomColor;
|
// 1.关闭地图缩放监听
|
this._map.off('zoomend', this._onMapZoom);
|
|
// 2.计算绘图高度的边界值
|
if (merge != true) {
|
var minH = MapUtil._minH < 0 ? heights[0] : MapUtil._minH;
|
var maxH = MapUtil._maxH < 0 ? heights[0] : MapUtil._maxH;
|
for (let i = 0; i < heights.length; i++) {
|
const h = heights[i];
|
minH = Math.min(minH, h);
|
maxH = Math.max(maxH, h);
|
}
|
MapUtil._minH = minH;
|
MapUtil._maxH = maxH;
|
}
|
|
// 3.确定定位坐标点
|
var center;
|
if (setCenter && lnglats_GD.length > 0) {
|
var p = lnglats_GD[0];
|
for (let i = 0; i < lnglats_GD.length; i++) {
|
const e = lnglats_GD[i];
|
if (e[0] != 0) {
|
p = e;
|
break;
|
}
|
}
|
center = new AMap.LngLat(...p);
|
}
|
|
// 5.绘制3D图形
|
MapUtil.drawMesh2(fDatas, factor, center, merge);
|
|
// 缩放地图到合适的视野级别
|
// MapUtil._map.setFitView()
|
|
// 6.开启地图缩放监听
|
if (lnglats_GD.length > 0) {
|
this._map.on('zoomend', this._onMapZoom);
|
}
|
},
|
/**
|
* 绘图
|
* @param {*} lnglats_GD 高德地图坐标
|
* @param {*} coors 通过高德地图 Map.lngLatToGeodeticCoord() 转换后的3d地图坐标
|
* @param {*} heights 每个坐标对应的高度
|
* @param {*} center 定位的坐标点
|
*/
|
drawMesh2: function (fDatas, factor, center, merge) {
|
const lnglats_GD = fDatas.lnglats_GD;
|
const coors = fDatas.coors_GD;
|
const heights = factor.heights;
|
const colors = factor.colors;
|
const bColor = factor.bottomColor;
|
if (center) {
|
MapUtil._map.setZoomAndCenter(16, center);
|
}
|
|
var cylinder = new AMap.Object3D.Mesh();
|
cylinder.backOrFront = 'both';
|
cylinder.transparent = true;
|
|
var geometry = cylinder.geometry;
|
|
const scale = MapUtil._getScale(MapUtil._minH, MapUtil._maxH);
|
for (let i = 0; i < coors.length; i++) {
|
var r = lnglats_GD[i];
|
var lastP = lnglats_GD[i - 1];
|
// if (r[0] == 0) {
|
// continue
|
// }
|
// if (lastP[0] == 0) {
|
// continue
|
// }
|
var p = coors[i];
|
// var p = MapUtil._map.lngLatToGeodeticCoord(r)
|
var h = MapUtil._getHeight(
|
heights[i],
|
MapUtil._minH,
|
MapUtil._maxH,
|
scale
|
);
|
if (heights[i] == -1) {
|
h = -1;
|
}
|
|
geometry.vertices.push(p.x, p.y, 0); //底部顶点
|
geometry.vertices.push(p.x, p.y, 0 - h); //顶部顶点
|
|
if (i > 0) {
|
var distance = AMap.GeometryUtil.distance(r, lastP);
|
//两个数据点最小间隔时间为4s,假设车速按照120km/h计算,4s行驶最大距离作为132米,
|
//设定超过1分钟的数据绘制特殊的连线
|
if (distance <= 500 && h != -1) {
|
var bottomIndex = i * 2;
|
var topIndex = bottomIndex + 1;
|
var lastBottomIndex = bottomIndex - 2;
|
var lastTopIndex = bottomIndex - 1;
|
geometry.faces.push(bottomIndex, topIndex, lastTopIndex);
|
geometry.faces.push(bottomIndex, lastBottomIndex, lastTopIndex);
|
}
|
}
|
|
// var bColor = bColor
|
var tColor = colors[i];
|
geometry.vertexColors.push.apply(geometry.vertexColors, bColor); //底部顶点颜色
|
geometry.vertexColors.push.apply(geometry.vertexColors, tColor); //顶部顶点颜色
|
}
|
|
// 7.根据合并选项重置或新增当前缓存数据
|
if (merge != true) {
|
this._factorDatas = fDatas;
|
this._factor = factor;
|
if (MapUtil._cylinder != undefined) {
|
MapUtil._object3Dlayer.remove(MapUtil._cylinder);
|
}
|
} else {
|
// this._factorDatas.lnglats.push.apply(
|
// this._factorDatas.lnglats,
|
// lnglats_GD
|
// );
|
// this._factorDatas.coors.push.apply(this._factorDatas.coors, coors);
|
// this._factorDatas.heights.push.apply(this._factorDatas.heights, heights);
|
// this._factorDatas.colors.push.apply(this._factorDatas.colors, colors);
|
// this._factorDatas.bottomColor = bColor;
|
}
|
MapUtil._object3Dlayer.add(cylinder);
|
/**************test ****************/
|
MapUtil._object3Dlayer.on('mouseover', function (e) {
|
console.log(
|
`鼠标移入覆盖物! [${e.lnglat.getlng()}, ${e.lnglat.getLat()}]`
|
);
|
});
|
/**************test ****************/
|
MapUtil._cylinder = cylinder;
|
},
|
|
_maxHeight: 1000,
|
_minHeight: 100,
|
_lastZoom: -1,
|
/**
|
* 获取当前地图缩放等级下的绘制高度缩放比例
|
* @param {*} minH 当前监测数据的最小高度
|
* @param {*} maxH 当前监测数据的最大高度
|
*/
|
_getScale(minH, maxH) {
|
var zoom = MapUtil._map.getZoom();
|
console.log(`zoom: ${zoom}`);
|
if (this._lastZoom == -1) {
|
this._lastZoom = zoom;
|
} else if (this._lastZoom <= 8) {
|
this._lastZoom = zoom;
|
return;
|
} else if (this._lastZoom >= 18) {
|
this._lastZoom = zoom;
|
return;
|
}
|
if (zoom <= 8) {
|
MapUtil._maxHeight = 10000;
|
MapUtil._minHeight = 1000;
|
} else if (zoom <= 9) {
|
MapUtil._maxHeight = 9000;
|
MapUtil._minHeight = 900;
|
} else if (zoom <= 10) {
|
MapUtil._maxHeight = 8000;
|
MapUtil._minHeight = 800;
|
} else if (zoom <= 11) {
|
MapUtil._maxHeight = 7000;
|
MapUtil._minHeight = 700;
|
} else if (zoom <= 12) {
|
MapUtil._maxHeight = 6000;
|
MapUtil._minHeight = 600;
|
} else if (zoom <= 14) {
|
MapUtil._maxHeight = 5000;
|
MapUtil._minHeight = 500;
|
} else if (zoom <= 15) {
|
MapUtil._maxHeight = 4500;
|
MapUtil._minHeight = 450;
|
} else if (zoom <= 16) {
|
MapUtil._maxHeight = 4000;
|
MapUtil._minHeight = 400;
|
} else if (zoom <= 17) {
|
MapUtil._maxHeight = 2500;
|
MapUtil._minHeight = 250;
|
} else if (zoom > 17) {
|
MapUtil._maxHeight = 1000;
|
MapUtil._minHeight = 100;
|
}
|
|
var scale = (MapUtil._maxHeight - MapUtil._minHeight) / (maxH - minH);
|
return scale;
|
},
|
/**
|
* 根据地图缩放等级获取监测因子图形的绘制高度范围
|
* @param {*} height 当前数据的原始高度
|
* @param {*} minH 当前监测数据的最小高度
|
* @param {*} maxH 当前监测数据的最大高度
|
* @param {*} scale 缩放比例
|
* @returns
|
*/
|
_getHeight: function (height, minH, maxH, scale) {
|
// var offset = minH - (maxH - minH) * (this._minHeight / this._maxHeight)
|
// height = ((height - offset) < 0 ? 0 : (height - offset)) * scale
|
// // console.log("scale: " + height);
|
// return height
|
height = (height - minH) * scale + MapUtil._minHeight;
|
return height;
|
},
|
|
/**
|
* 根据地图缩放等级,获取走航监测点标记的绘制间隔
|
*/
|
_getMarkerInterval() {
|
var zoom = MapUtil._map.getZoom();
|
if (this._lastZoom == -1) {
|
this._lastZoom = zoom;
|
} else if (this._lastZoom <= 8) {
|
this._lastZoom = zoom;
|
return;
|
} else if (this._lastZoom >= 18) {
|
this._lastZoom = zoom;
|
return;
|
}
|
var interval = 1;
|
if (zoom <= 8) {
|
interval = 1000;
|
} else if (zoom <= 9) {
|
interval = 800;
|
} else if (zoom <= 10) {
|
interval = 600;
|
} else if (zoom <= 11) {
|
interval = 400;
|
} else if (zoom <= 12) {
|
interval = 100;
|
} else if (zoom <= 13) {
|
interval = 20;
|
} else if (zoom <= 14) {
|
interval = 10;
|
} else if (zoom <= 15) {
|
interval = 5;
|
} else if (zoom <= 16) {
|
interval = 2;
|
} else if (zoom <= 17) {
|
interval = 1;
|
} else if (zoom > 17) {
|
interval = 1;
|
}
|
return interval;
|
},
|
};
|