返回
var mapPointAddress = getQueryString('mapPointAddress');
var _qValue = 0.001;
var _rValue = 0.01;
//坐标点下标
var coordIndex = 0;
//起点终点坐标
var points = [{
x: 13028218.4785,
y: 4737039.7298,
groupID: 1
},
{
x: 13028218.4785,
y: 4737009.7298,
groupID: 1
}
];
var naviState = false; //导航状态,是否导航中
// 导航对象
var navi = null;
var XYobj = {};
var resultX = 31;
var resultY = 12;
var zhuanhuanXY; //地图坐标
var Ldirection = 180; //浏览器方向
var newCoord = {
x: 0,
y: 0
}
var locationCount = 0;
//获取版本号,设置title
document.title = '室内定位' + fengmap.VERSION;
//定义全局map变量
var map;
var fmapID = 'location-test';
var locationMarker;
//楼层ID
var lastGid = null;
//第一人称、第三人称控制开关;定位跟随开关
var others = true;
var layer = null
window.onload = function() {
var mapCoord = {
x: 13028218.4785,
y: 4737030.7298,
groupID: 1
}; // websocket传过来的坐标信息,经过转换的可直接在地图上显示。
map = new fengmap.FMMap({
//渲染dom
container: document.getElementById('fengMap'),
//地图数据位置
mapServerURL: './data/' + fmapID,
//主题数据位置
mapThemeURL: 'data/theme/',
//设置主题
defaultThemeName: '2001',
// 默认比例尺级别设置为20级
defaultMapScaleLevel: 22,
//开启2维,3维切换的动画显示
viewModeAnimateMode: true,
//方向枚举型。可设置正南、正北、正东、正西、东南、西南等方向值。具体可参考fengmap.ControlsPoseEnum类。NORTH WEST SOUTH
defaultControlsPose: fengmap.FMDirection.NORTH,
defaultViewMode: fengmap.FMViewMode.MODE_2D, //初始二维还是三维状态,三维状态为MODE_3D,
//开发者申请应用下web服务的key
key: '670072019dff394f3f991e88e98024d5',
//开发者申请应用名称
appName: 'innerMap',
});
//打开Fengmap服务器的地图数据和主题
map.openMapById(fmapID);
//显示指北针
map.showCompass = true;
//地图加载完成回调
map.on('loadComplete', function() {
FengZhuangXY();
WebSocketTest();
//初始化导航对象
navi = new fengmap.FMNavigation({
map: map,
// 设置导航线的样式
lineStyle: {
//设置线为导航线样式
lineType: fengmap.FMLineType.FMARROW,
lineWidth: 6,
}
});
var zhuanXY = {
x: resultX,
y: resultY,
}
var coord = CoordTransform(zhuanXY);
coord.groupID = 1;
addlocationMarker(coord);
// 设置导航事件
navi.on('walking', function(data) {
console.log('data', data)
setLocationMakerPosition(data.point, data.angle);
//显示导航展示信息
cardInfo(data);
});
if(mapPointAddress) {
mapPointAddress = JSON.parse(mapPointAddress);
console.log('mapPointAddress', mapPointAddress)
navi.setEndPoint({
x: mapPointAddress.x,
y: mapPointAddress.y,
height: 2,
groupID: mapPointAddress.groupID,
url: 'image/end.png',
size: 32
});
}
});
//设置图片标注点位置信息
function setLocationMakerPosition(coord, angle) {
var data = {
//设置定位点的x坐标
x: coord.x,
//设置定位点的y坐标
y: coord.y,
//设置定位点所在楼层
groupID: coord.groupID,
time: .50,
callback: function() {
//回调函数
},
zOffset: 1
};
//设置定位图标旋转角度
if(angle) {
locationMarker.rotateTo(-angle);
if(others) {
map.rotateTo({
to: angle,
time: 1
});
}
}
//不同楼层
if(lastGid !== coord.groupID) {
lastGid = coord.groupID;
locationMarker.setPosition(data);
}
locationMarker.moveTo(data);
map.moveTo({
x: coord.x,
y: coord.y,
groupID: coord.groupID,
time: 1
});
}
//添加定位点图层
function addlocationMarker(coord) {
locationMarker = new fengmap.FMLocationMarker({
//设置图片的路径
url: 'image/pointer.png',
//设置图片显示尺寸
size: 46,
//设置图片高度
height: 1,
});
//添加定位点标注
map.addLocationMarker(locationMarker);
//设置定位图标位置
setLocationMakerPosition(coord, 180);
return locationMarker;
};
//导航
map.on('mapClickNode', function(event) {
if(event.nodeType == fengmap.FMNodeType.MODEL && navi != undefined) {
var modelLabel = event.label;
var coord;
// 如果拾取的模型没有Label对象,则使用模型中心点的坐标
// 有则使用与模型对应的Label对象的坐标。
if(!modelLabel) {
coord = {
x: event.mapCoord.x,
y: event.mapCoord.y,
groupID: event.groupID
}
} else {
coord = {
x: modelLabel.mapCoord.x,
y: modelLabel.mapCoord.y,
groupID: event.groupID
};
}
navi.clearAll();
navi.setEndPoint({
x: coord.x,
y: coord.y,
height: 2,
groupID: coord.groupID,
url: 'image/end.png',
size: 32
});
}
})
//开始导航
$('#navigation').on('click', function() {
//切换导航与取消导航
if(naviState) {
navi.clearAll();
naviState = false; //修改导航状态
$("#description").hide();
$(".navigation_text").text("去这里");
} else {
var zhuanXY = {
x: resultX,
y: resultY,
}
var coord = CoordTransform(zhuanXY);
coord.groupID = 1;
//获取当前位置
navi.setStartPoint({
x: coord.x,
y: coord.y,
height: 2,
groupID: coord.groupID,
url: 'image/start.png',
size: 32
});
navi.drawNaviLine();
naviState = true; //修改导航状态
$(".navigation_text").text("取消导航");
}
});
function realNavigation(coord) {
navi.locate(coord);
}
function CoordTransform(Coord) {
//创建转换器
var trasformer = new fengmap.MapCoordTransform();
//来至定位系统的参数 定位的原点坐标 已经定位的范围,(矩形对角线的2个点)
var locOrigion = {
'x': 0,
'y': 0
}; //定位坐标原点
var locRange = {
'x': 32.387,
'y': 32.202
}; //定位范围
//根据定位四个角点的地图坐标点
var mapParas = [];
mapParas[0] = {
'x': 13028246.2666,
'y': 4737041.5179
}; //定位原点地图坐标
mapParas[1] = {
'x': 13028214.5795,
'y': 4737041.5179
}; //X轴终点地图坐标
mapParas[2] = {
'x': 13028214.5702,
'y': 4737009.6396
}; //定位原点对角点地图坐标
mapParas[3] = {
'x': 13028246.2666,
'y': 4737009.6302
}; //Y轴终点地
//转换器初始化
trasformer.init(locOrigion, locRange, mapParas);
//定位系统中的定位坐标
var loc = {
'x': Coord.x,
'y': Coord.y
}; //定位系统所返回的坐标点
//转换后的地图坐标
var mapCoord = trasformer.transform(loc);
return mapCoord;
}
function WebSocketTest() {
if("WebSocket" in window) {
var ws = new WebSocket("wss://www.dowino2o.net:8087/api/websocket?openId=map" + 123456);
ws.onopen = function() {
setInterval(function() {
console.log('发送')
ws.send("保持心跳");
}, 50000)
};
ws.onmessage = function(evt) {
var received_msg = evt.data;
console.log('收到消息:', received_msg);
try {
var jsonObj = JSON.parse(received_msg);
console.log('jsonObj', jsonObj)
if(jsonObj.x) {
XYobj = jsonObj;
console.log('XYobj', XYobj)
} else {
return false;
}
//做卡尔曼
var finalXY = suanXY(resultX, resultY, 0, Ldirection, XYobj.x, XYobj.y, _qValue, _rValue)
resultX = finalXY._data[0][0];
resultY = finalXY._data[1][0];
var zhuanXY = {
x: resultX,
y: resultY,
}
var coord = CoordTransform(zhuanXY);
coord.groupID = 1;
console.log('coord', coord)
if(naviState) {
realNavigation(coord);
} else {
setLocationMakerPosition(coord, Ldirection)
}
} catch(err) {}
};
ws.onclose = function() {
console.log('连接已关闭')
};
} else {
alert("您的浏览器不支持 WebSocket!");
}
}
//计步定位
function FengZhuangXY() {
//状态:静止
var STAY = 0;
//状态:运动
var MOVE = 1;
//运动状态判断数组,长度20
var stateValue = new Array(20).fill(0);
//加速度数组 长度100
var Accs = new Array(100).fill(0);;
//每次传入加速度的时间,省去定时器 长度100
var time = new Array(100).fill(0);
//数组下标
var count = 0;
//行走步数
var Step = 0;
//步长
var Length = 0;
//行进距离
var Distance = 0;
var RDistance = 0;
//状态
var State = STAY;
var currentTime, lastTime, timeCount;
//监听方向变化
try {
window.addEventListener("deviceorientation", orientationHandler, false);
function orientationHandler(event) {
Ldirection = Math.round(event.webkitCompassHeading);
console.log('Ldirection1', Ldirection)
Ldirection += 135;
Ldirection += 180;
if(Ldirection > 360) {
Ldirection -= 360;
}
console.log('Ldirection2', Ldirection)
setLocationMakerPosition(null, Ldirection);
}
} catch(e) {
console.log('Ldirection3', Ldirection)
};
//监听加速计变化
if(window.DeviceMotionEvent) {
window.addEventListener('devicemotion', deviceMotionHandler, false);
}
var vibrateSupport = "vibrate" in navigator
if(vibrateSupport) { //兼容不同的浏览器
navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
}
function deviceMotionHandler(eventData) {
var acceleration = eventData.accelerationIncludingGravity;
var valuesArray = [acceleration.x, acceleration.y, acceleration.z];
if(!lastTime) {
lastTime = new Date().getTime();
}
currentTime = new Date().getTime();
let timeCha = currentTime - lastTime;
if(timeCha > 1500) {
_qValue = 0.001;
_rValue = 0.01;
} else {
_qValue = 0;
_rValue = 1;
}
refreshAcc(valuesArray, currentTime);
}
function refreshAcc(values, timestamp) {
Accs[count] = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
time[count] = timestamp;
//检查运动状态
stateValue[count % 20] = Accs[count];
checkState();
//设置检测点,检测点的值为到最新数据的距离,如果太近了将无法确定其为波峰波谷
//检测点的作用是来减少计算量
var ckpoint = Accs.length / 5;
//运动状态判断加上判断检测点是否有波谷存在
if(State == MOVE && Accs[(count - ckpoint + Accs.length) % Accs.length] < Accs[(count - ckpoint + Accs.length + 1) % Accs.length] &&
Accs[(count - ckpoint + Accs.length) % Accs.length] <
Accs[(count - ckpoint + Accs.length - 1) % Accs.length]) {
//求均值
var ave0 = 0;
for(var i = 0; i < Accs.length; ++i) {
ave0 += Accs[i];
}
ave0 /= Accs.length;
//调整数组顺序,把新数据放在前面,同时把数据减去均值
var data = new Array(Accs.length).fill(0);
for(var i1 = 0, j = count; i1 < data.length; ++i1, --j) {
if(j < 0) {
j += data.length
};
data[i1] = Accs[j] - ave0;
}
//寻找波峰波谷
var sign = new Array(Accs.length).fill(0);
for(var i2 = 1; i2 < Accs.length - 1; ++i2) {
if(Math.abs(data[i2]) > 0.8 &&
Math.abs(2 * data[i2]) > Math.abs((data[i2 - 1] + data[i2 + 1]))) {
if(data[i2] > 0) {
sign[i2] = 1;
} else {
sign[i2] = -1;
}
}
}
for(var i3 = 1; i3 < sign.length - 1;) {
var idx = i3;
while(++i3 < sign.length - 1 &&
(sign[i3] == 0 || sign[i3] == sign[idx])) {
if(sign[i3] != 0 && Math.abs(data[i3]) > Math.abs(data[idx])) {
sign[idx] = 0;
idx = i3;
} else {
sign[i3] = 0;
}
}
}
//再次判断检测点是否是波谷
if(sign[ckpoint] < 0) {
var index = ckpoint;
//寻找下个波峰
while(++index < sign.length && sign[index] == 0);
if(index < sign.length && sign[index] > 0) {
var peak = index;
//寻找下个波谷
while(++index < sign.length && sign[index] == 0);
if(index < sign.length && sign[index] < 0) {
var valley = index;
//计算H和T
var H = data[peak] - 0.5 * data[ckpoint] - 0.5 * data[valley];
var T = time[(count - ckpoint + time.length) % time.length] - time[(count - valley + time.length) % time.length];
if(H > 1 && T > 300 && T < 1400) {
_qValue = 0;
_rValue = 1;
lastTime = new Date().getTime();
//步长计算
var steplength = 0.35 - 0.000155 * T + 0.1638 * Math.sqrt(H);
//var steplength = 0.65 - 0.000155 * T + 0.1638 * Math.sqrt(H);
Length = (Length + steplength) / 2;
Distance += steplength;
++Step;
//做卡尔曼
var finalXY = suanXY(resultX, resultY, steplength, Ldirection, XYobj.x, XYobj.y, _qValue, _rValue)
resultX = finalXY._data[0][0];
resultY = finalXY._data[1][0];
var zhuanXY = {
x: resultX,
y: resultY,
}
var coord = CoordTransform(zhuanXY);
coord.groupID = 1;
if(naviState) {
realNavigation(coord);
} else {
setLocationMakerPosition(coord, Ldirection)
}
}
}
}
}
}
if(++count == 100) count = 0;
};
//检查运动状态
function checkState() {
var ave = 0;
var Var = 0;
//求均值
for(var i = 0; i < stateValue.length; i++) {
ave += stateValue[i];
}
ave /= stateValue.length;
//求方差
for(var i = 0; i < stateValue.length; i++) {
Var += (stateValue[i] - ave) * (stateValue[i] - ave);
}
Var /= stateValue.length;
//状态判决
State = Var > 0.1 ? MOVE : STAY;
};
//获取当前时间戳
function getCurrentTime() {
var timestamp = new Date().getTime();
return timestamp;
};
};
//显示路径数据
function cardInfo(data) {
//距终点的距离
var distance = data.remain;
var maxEndDistance = 1;
//路线提示信息
var prompt = navi.naviDescriptions[data.index];
//当距离小于距离终点的最大距离时结束导航
if(distance < maxEndDistance) {
distance = 0;
prompt = '到达终点';
//navigation = true;
//楼层控件可点击
//groupControl.enableExpand = true;
//$('#navigation').removeClass('btn-primary');
//map.mapScaleLevel = startNaviScaleLevel; //还原地图为导航前缩放比例
}
//普通人每分钟走80米。
var time = distance / 80;
var m = parseInt(time);
var s = Math.floor((time % 1) * 60);
$("#description").show();
$('#description').html('
距终点:' + distance.toFixed(1) + ' 米
大约需要: ' + m + ' 分钟 ' + s + ' 秒
路线提示:' + prompt + '
');//$('.layerMask').html('F' + data.groupID);
};
$('#goback').on('click', function() {
window.history.back(-1);
})
};
一键复制
编辑
Web IDE
原始数据
按行查看
历史