You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8192 lines
305 KiB
8192 lines
305 KiB
var Map_QM,
|
|
renderFrame = -1,
|
|
renderCount = 0,
|
|
pathCameraState,
|
|
mapState = "mall",
|
|
iconState = "3d",
|
|
heatmapInstance,
|
|
isShowElement = true,
|
|
isJUZ = false,
|
|
allJU = true,
|
|
hasLine = false,
|
|
startRotate = false,
|
|
intTimer,
|
|
shopTime,
|
|
allTime,
|
|
language = "zh";
|
|
//basePath 基础路径 graphPath最佳路径 ftPath 扶梯路径 dtPath 电梯路径
|
|
|
|
var typeObj = [
|
|
{ ft: 0, type: 0, code: "ft", name: "扶梯" },
|
|
{ upft: 1, type: 1, code: "upft", name: "上扶梯" },
|
|
{ downft: 2, type: 2, code: "downft", name: "下扶梯" },
|
|
{ mys: 3, type: 3, code: "mys", name: "母婴室" },
|
|
{ xsj: 4, type: 4, code: "xsj", name: "洗手间" },
|
|
{ dt: 5, type: 5, code: "dt", name: "直梯" },
|
|
{ hxkj: 6, type: 6, code: "hxkj", name: "焕醒空间" },
|
|
{ fwt: 7, type: 7, code: "fwt", name: "服务台" },
|
|
{ tcc: 8, type: 8, code: "tcc", name: "停车场" },
|
|
{ hhkj: 9, type: 9, code: "hhkj", name: "焕活空间" },
|
|
{ cjr: 10, type: 10, code: "cjr", name: "无障碍洗手间" },
|
|
{ xys: 11, type: 11, code: "xys", name: "吸烟室" },
|
|
{ upft: 12, type: 12, code: "upft", name: "上扶梯" },
|
|
{ downft: 13, type: 13, code: "downft", name: "下扶梯" },
|
|
{ dkbc: 14, type: 14, code: "dkbc", name: "代客泊车" },
|
|
{ tczj: 15, type: 15, code: "tczj", name: "童车租借" },
|
|
{ ysc: 16, type: 16, code: "ysc", name: "饮水处" },
|
|
{ ztg: 17, type: 17, code: "ztg", name: "L1自提柜" },
|
|
{ thg: 18, type: 18, code: "thg", name: "B1自提柜" },
|
|
{ cwysd: 19, type: 19, code: "cwysd", name: "宠物饮水点" },
|
|
{ td: 20, type: 20, code: "td", name: "人行通道" },
|
|
{ dit: 21, type: 21, code: "dit", name: "地铁" },
|
|
{ czc: 22, type: 22, code: "czc", name: "出租车" },
|
|
{ atm: 23, type: 23, code: "atm", name: "ATM" },
|
|
{ jcfw: 24, type: 24, code: "jcfw", name: "寄存服务" },
|
|
{ sjcd: 25, type: 25, code: "sjcd", name: "手机充电" },
|
|
{ bc: 26, type: 26, code: "bc", name: "泊车" },
|
|
{ cjc: 27, type: 27, code: "cjc", name: "裁剪处" },
|
|
{ jtn: 28, type: 28, code: "jtn", name: "家庭洗手间(男)" },
|
|
{ jtv: 29, type: 29, code: "jtv", name: "家庭洗手间(女)" },
|
|
{ ksgj: 30, type: 30, code: "ksgj", name: "公交" },
|
|
{ sjxsn: 31, type: 31, code: "sjxsn", name: "无障碍洗手间男" },
|
|
{ sjxsv: 32, type: 32, code: "sjxsv", name: "无障碍洗手间女" },
|
|
{ tcjf: 33, type: 33, code: "tcjf", name: "停车缴费" },
|
|
{ vip: 34, type: 34, code: "vip", name: "VIP" },
|
|
{ xsjn: 35, type: 35, code: "xsjn", name: "男洗手间" },
|
|
{ xsjv: 36, type: 36, code: "xsjv", name: "女洗手间" },
|
|
{ yszj: 37, type: 37, code: "yszj", name: "雨伞租借" },
|
|
{ dyj: 38, type: 38, code: "dyj", name: "打印机" },
|
|
{ door: 39, type: 39, code: "door", name: "出入口" },
|
|
{ pq: 40, type: 40, code: "pq", name: "喷泉" },
|
|
{ d1k: 41, type: 41, code: "d1k", name: "1号出入口" },
|
|
{ d2k: 42, type: 42, code: "d2k", name: "2号出入口" },
|
|
{ d3k: 43, type: 43, code: "d3k", name: "3号出入口" },
|
|
{ d4k: 44, type: 44, code: "d4k", name: "4号出入口" },
|
|
{ mjzyf: 45, type: 45, code: "mjzyf", name: "门急诊药房" },
|
|
{ cryc: 46, type: 46, code: "cryc", name: "出入院处" },
|
|
{ rggh: 47, type: 47, code: "rggh", name: "人工挂号收费处" },
|
|
{ zzyl: 48, type: 48, code: "zzyl", name: "自动饮料贩卖机" },
|
|
{ gxly: 49, type: 49, code: "gxly", name: "共享轮椅" },
|
|
{ ysp: 50, type: 50, code: "ysp", name: "艺术品" },
|
|
{ B1up: 51, type: 51, code: "B1up", name: "" },
|
|
{ B1down: 52, type: 52, code: "B1down", name: "" },
|
|
{ B2up: 53, type: 53, code: "B2up", name: "" },
|
|
{ B2down: 54, type: 54, code: "B2down", name: "" },
|
|
{ B3up: 55, type: 55, code: "B3up", name: "" },
|
|
{ B3down: 56, type: 56, code: "B3down", name: "" },
|
|
{ xcgc: 57, type: 57, code: "xcgc", name: "下沉广场" },
|
|
{ tthy: 58, type: 58, code: "tthy", name: "天台花园" },
|
|
{ ybck: 59, type: 59, code: "ybck", name: "医保窗口" },
|
|
{ zzfw: 60, type: 60, code: "zzfw", name: "自助服务" },
|
|
{ gjj: 61, type: 61, code: "gjj", name: "工具间" },
|
|
{ syt1: 62, type: 62, code: "syt1", name: "mall收银台" },
|
|
{ gwc: 63, type: 63, code: "gwc", name: "购物车" },
|
|
{ ht: 64, type: 64, code: "ht", name: "花坛" },
|
|
{ jrc: 65, type: 65, code: "jrc", name: "自助加热" },
|
|
{ qbc: 66, type: 66, code: "qbc", name: "自助取冰" },
|
|
{ zxc: 67, type: 67, code: "zxc", name: "自行车停放" },
|
|
{ jws: 68, type: 68, code: "jws", name: "警务室" },
|
|
{ etxsj: 69, type: 69, code: "etxsj", name: "儿童洗手间" },
|
|
{ vip_xxq: 70, type: 70, code: "vip_xxq", name: "vip休息区" },
|
|
{ ab: 71, type: 71, code: "ab", name: "安保" },
|
|
{ abjks: 72, type: 72, code: "abjks", name: "安保监控室" },
|
|
{ bys: 73, type: 73, code: "bys", name: "播音室" },
|
|
{ cpgys: 74, type: 74, code: "cpgys", name: "裁判更衣室" },
|
|
{ gzyld: 75, type: 75, code: "gzyld", name: "观众医疗点" },
|
|
{ hqgys: 76, type: 76, code: "hqgys", name: "后勤更衣室" },
|
|
{ jjs: 77, type: 77, code: "jjs", name: "急救室" },
|
|
{ jw: 78, type: 78, code: "jw", name: "警卫" },
|
|
{ ksj: 79, type: 79, code: "ksj", name: "开水间" },
|
|
{ kt: 80, type: 80, code: "kt", name: "看台" },
|
|
{ qzgysn: 81, type: 81, code: "qzgysn", name: "亲自更衣(男)" },
|
|
{ rsggys: 82, type: 82, code: "rsggys", name: "热身馆更衣室" },
|
|
{ swzl: 83, type: 83, code: "swzl", name: "失物招领" },
|
|
{ tsgbs1: 84, type: 84, code: "tsgbs1", name: "特殊贵宾室1" },
|
|
{ tsgbs2: 85, type: 85, code: "tsgbs2", name: "特殊贵宾室2" },
|
|
{ tsgbs3: 86, type: 86, code: "tsgbs3", name: "特殊贵宾室3" },
|
|
{ wxc: 87, type: 87, code: "wxc", name: "闻讯处" },
|
|
{ lt: 88, type: 88, code: "lt", name: "楼梯" },
|
|
{ yhs: 89, type: 89, code: "yhs", name: "医护室" },
|
|
{ yls: 90, type: 90, code: "yls", name: "医疗室" },
|
|
{ ylz: 91, type: 91, code: "ylz", name: "医疗站" },
|
|
{ ydygys: 92, type: 92, code: "ydygys", name: "运动员更衣室" },
|
|
{ ydygysn: 93, type: 93, code: "ydygysn", name: "运动员男更衣室" },
|
|
{ ydygysv: 94, type: 94, code: "ydygysv", name: "运动员女更衣室" },
|
|
{ zls: 95, type: 95, code: "zls", name: "诊疗室" },
|
|
{ zys: 96, type: 96, code: "zys", name: "直饮水" },
|
|
{ zas: 97, type: 97, code: "zas", name: "治安室" },
|
|
{ xxq: 98, type: 98, code: "xxq", name: "休息区" },
|
|
{ jtxsj: 99, type: 99, code: "jtxsj", name: "家庭洗手间" },
|
|
{ hzs: 100, type: 100, code: "hzs", name: "化妆室" },
|
|
{ brs: 101, type: 101, code: "brs", name: "哺乳室" },
|
|
{ mtl: 102, type: 102, code: "mtl", name: "摩天轮" },
|
|
{ dgnxsj: 103, type: 103, code: "dgnxsj", name: "多功能洗手间" },
|
|
{ wxbxsj: 104, type: 104, code: "wxbxsj", name: "无性别洗手间" },
|
|
{ sjzx: 105, type: 105, code: "sjzx", name: "设计中心" },
|
|
{ dxp: 106, type: 106, code: "dxp", name: "导向牌" },
|
|
{ gydh: 107, type: 107, code: "gydh", name: "公用电话" },
|
|
{ sgq: 108, type: 108, code: "sgq", name: "石拱桥" },
|
|
{ wxw: 109, type: 109, code: "wxw", name: "无线网" },
|
|
{ xmb: 110, type: 110, code: "xmb", name: "小卖部" },
|
|
{ zyzfwz: 111, type: 111, code: "zyzfwz", name: "志愿者服务站" },
|
|
{ ykzx: 112, type: 112, code: "ykzx", name: "服务中心" },
|
|
{ zjyy: 113, type: 113, code: "zjyy", name: "专家预约处" },
|
|
{ yjt: 114, type: 114, code: "yjt", name: "预检台" },
|
|
{ mzjd: 115, type: 115, code: "mzjd", name: "门诊综合接待室" },
|
|
{ hd: 116, type: 116, code: "hd", name: "活动点" },
|
|
{ bsl: 117, type: 117, code: "bsl", name: "白石龙" },
|
|
{ xzl: 118, type: 118, code: "xzl", name: "写字楼" },
|
|
{ axzj: 119, type: 119, code: "axzj", name: "爱心租借" },
|
|
{ cdz: 120, type: 120, code: "cdz", name: "充电桩" },
|
|
{ hjcq: 121, type: 121, code: "hjcq", name: "黑金车区" },
|
|
{ yjjj: 122, type: 122, code: "yjjj", name: "宜家家居" },
|
|
];
|
|
|
|
var QMUtil = function () {
|
|
this.shopServerInfo = "./static/offline/JSON/QueryShopList.json";
|
|
this.mapServerInfo = "./static/offline/JSON/GetMapInfo.json";
|
|
this.beforPath = "./"; //https://qianmu-iot.1000my.com/QMAPSDK/
|
|
this.tomUrl = "https://qianmu-iot.1000my.com";
|
|
this.options = {
|
|
playSpeed: 8, //动画播放速度
|
|
speedMult: 1, //动画播放倍数
|
|
collision: true, //是否支持名称的碰撞检测
|
|
modelIcon: true, //是否使用模型 true 模型 false 图标
|
|
otherPath: [], //人为干预的路线 [{f:"0_5_10",s:"1_5_47",d:500},{f:"1_5_47",s:"0_5_10",d:500}];
|
|
bSpace: 3000,
|
|
fSpace: 500, //双叠层状态下楼层的间距
|
|
maxDis: 700,
|
|
minDis: 100,
|
|
shadow: false, //是否显示阴影
|
|
navColor: 0xee6a50, //途径店铺颜色
|
|
aRadius: 2, //圆角半径 大于2 则店铺box显示圆角
|
|
iconName: false, //图标名称是否显示
|
|
mapScale: 18, //地图比例尺
|
|
pathColor: "#6e95fe", //
|
|
pathColor2: "#6e7dfe", //'rgb(110,125,254)'
|
|
pathBgColor: "#a9b5d3", //'rgb(169,181,211)'
|
|
pathBgColor2: "#bdc0cb", //'rgb(189, 192, 203)',
|
|
pathStyle: "3D",
|
|
shopStyle: "shopName", //设置box显示名称shopName或编号shopNum
|
|
inArea: true, //点击后是否聚焦到店铺
|
|
boxShop: [], //设置box上显示的文字(过滤指),可点击触发onlyShop
|
|
deviceAng: false, //地图初始化方向是否使用设备角度
|
|
northShow: false, //指南针显示
|
|
facSize: 20, //设施大小
|
|
};
|
|
this.showHouseNumberAndName = false;
|
|
this.lightOptions = {
|
|
d_col: "#ffffff",
|
|
d_int: 0.2,
|
|
s_col: "#fffffa",
|
|
g_col: "#ffffff",
|
|
a_int: 0.85,
|
|
};
|
|
this.m_zoom = 1.2; //2D地图缩放大小
|
|
this._clock = new THREE.Clock();
|
|
this._indexPathFloor = 0; // 遍历途径数据
|
|
this.changeDist = { inner: 300, outner: 900 };
|
|
/**
|
|
* isPathState 寻路状态
|
|
*/
|
|
this.pathStateObj = {
|
|
isPathState: false,
|
|
isPathPlay: true,
|
|
basePath: "",
|
|
graphPath: "",
|
|
ftPath: "",
|
|
dtPath: "",
|
|
facAllArr: [],
|
|
forShopArr: {},
|
|
elevator: null,
|
|
straight: null,
|
|
elevatorDown: null,
|
|
seldtFacNo: { type: "", no: "" },
|
|
};
|
|
this.timeObj = { collTime: -1, pathTime: -1 };
|
|
this.sceneGap = { cameraX: 15, cameraY: 220, cameraZ: 220, x: 15, y: 0, z: 0, scale: 0.08 }; //改变地图位置,大小
|
|
this.isMorePath = false; //多节点寻路模式
|
|
this.selectBuild = 0;
|
|
this.selectFloor = 0;
|
|
this.deviceObj = {}; //angle --- 设备旋转角度 node ---- 设备导航点位 floor --- 设备楼层
|
|
this.startObj = {}; // 导航起点;
|
|
this.overObj = {}; //导航结束点
|
|
this.buildHeight = 5;
|
|
this.shopHeight = 30; //店铺高度 控制店铺相关的其它第三方组件高度
|
|
//添加平铺logo {floor:5, logoUrl:"./static/img/ss.png", imgW:395, imgH:376, xaxis:1550, yaxis:-860, site:30}
|
|
this.logos = [];
|
|
/**
|
|
* 外立面
|
|
* Map_QM.util.initModelArr=[{url:"./static/img/out/yong.glb",type:"out", scale:1, rot:{x:0,y:0,z:0}, site:{x:0,y:0,z:0}, colorModel:"gama" }];
|
|
*/
|
|
this.initModelArr = []; //
|
|
/**
|
|
* 一直显示不隐藏, 在楼层内显示
|
|
* {floor:6, url:"static/img/out/skp.glb", list:[{size:{x:12.5,y:12.5,z:12.5}, rot:{x:1.5708,y:0,z:0}, site:{x:0,y:0,z:0}}]}
|
|
*/
|
|
this.modelArr = [];
|
|
this.modelStr = [
|
|
//种树
|
|
{key: "tree", url: "static/img/model/tree.gltf", colorModel: "line", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 1, y: 1, z: 1 }, load: false },
|
|
{key: "tree2", url: "static/img/model/tree2.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "tree3", url: "static/img/model/tree3.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "grass", url: "static/img/model/grass.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "flower1", url: "static/img/model/flower1.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 },load: false},
|
|
{ key: "flower2", url: "static/img/model/flower2.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{ key: "subway", url: "static/img/model/subway.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
|
|
{key: "huatan1", url: "static/img/model/huatan1.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "huatan2", url: "static/img/model/huatan2.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "penquan2", url: "static/img/model/penquan2.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche1", url: "static/img/model/qiche1.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche2", url: "static/img/model/qiche2.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche3", url: "static/img/model/qiche3.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche4", url: "static/img/model/qiche4.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche5", url: "static/img/model/qiche5.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche6", url: "static/img/model/qiche6.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche7", url: "static/img/model/qiche7.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche8", url: "static/img/model/qiche8.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "qiche9", url: "static/img/model/qiche9.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "jt_up", url: "static/img/model/jt_up.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "jt_left", url: "static/img/model/jt_left.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "jt_left_up", url: "static/img/model/jt_left_up.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "jt_right", url: "static/img/model/jt_right.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "jt_right_up", url: "static/img/model/jt_right_up.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "jt_turn", url: "static/img/model/jt_turn.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "ludeng", url: "static/img/model/ludeng.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "taiyangsan", url: "static/img/model/taiyangsan.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "honglvdeng", url: "static/img/model/honglvdeng.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "park_paly", url: "static/img/model/park_paly.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 80, y: 80, z: 80 }, load: false },
|
|
{key: "chongdianzhuang", url: "static/img/model/chongdianzhuang.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "IDS_H", url: "static/img/model/IDS_H.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "IDS_V", url: "static/img/model/IDS_V.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "officeTV", url: "static/img/model/officeTV.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "xiaofangshuan", url: "static/img/model/xiaofangshuan.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "tingchechang", url: "static/img/model/tingchechang.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "chechanglangan", url: "static/img/model/chechanglangan.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "bangongyi", url: "static/img/model/bangongyi.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "lvzhi", url: "static/img/model/lvzhi.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "ren1", url: "static/img/model/ren1.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "ren2", url: "static/img/model/ren2.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "ren3", url: "static/img/model/ren3.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "ren4", url: "static/img/model/ren4.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "ren5", url: "static/img/model/ren5.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "ren6", url: "static/img/model/ren6.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "table", url: "static/img/model/table.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "yizi1", url: "static/img/model/yizi1.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
{key: "gjz1", url: "static/img/model/gjz1.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
|
|
];
|
|
this.fbxModels = []; //精灵模型
|
|
/**
|
|
* 模型弹窗
|
|
* { htmlUrl: "<p onclick='Map_QM.goHome()' class='other-pop'>进入商场</p>", x: 55, y: 12, z: 3, show:"zh", type: "out" }
|
|
*/
|
|
this.tipArr = []; //模型标签 periphery
|
|
/**
|
|
* 室内地图标签
|
|
* Map_QM.util.labelIconArr([{floor:0,title:'<img src="./static/img/iconInfo/lbl_bl.png" width="70" style="position: absolute; bottom: 0px; transform: translateX(-35px);" alt="" >', click:false, site:{x:0,y:1870,z:10},data:{type:"labelIcon",id:"1",show:"cn"}}]);
|
|
*/
|
|
this.labelIconArr = [];
|
|
this.spriteMaterialArr = [];
|
|
this.lineBasicMaterialArr = [];
|
|
this.meshMaterialArr = [];
|
|
this.parkMaterialArr = [];
|
|
this.shopData = []; //店铺数据
|
|
this.iconUrl = [];
|
|
this.allMap = [];
|
|
/*** ------------------------------------------------ 参数 API START ------------------------------------------------- */
|
|
this.exportImg = function () {
|
|
let tempSrc = Map_QM.renderer.domElement.toDataURL("image/png");
|
|
let a = document.createElement("a");
|
|
a.href = tempSrc;
|
|
a.setAttribute("download", "floor.png");
|
|
a.click();
|
|
};
|
|
/**
|
|
* @api {方法} changePlaySpeed(speedMult) 改变导航速度倍数
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 改变导航播放速度倍数
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {int} speedMult 播放速度倍数(默认 1)
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.util.changePlaySpeed()
|
|
*
|
|
*/
|
|
this.changePlaySpeed = function (speedMult = 1) {
|
|
Map_QM.util.options.speedMult = speedMult;
|
|
};
|
|
/*** ----------------------------------------------- 参数 API END ----------------------------------------------- **** */
|
|
this.Point = function (x = 0, y = 0) {
|
|
this.x = x;
|
|
this.y = y;
|
|
};
|
|
this.WallLine = function (start, end) {
|
|
this.start = start; //起始点位
|
|
this.end = end; //结束点位
|
|
this.leftParLine; //左侧平行线段
|
|
this.rightParLine; //右侧平行线段
|
|
this.leftPoint; //左侧平行线交点
|
|
this.rightPoint; //右侧平行线交点
|
|
};
|
|
|
|
this.assignUVs = function (geometry) {
|
|
geometry.computeBoundingBox();
|
|
let max = geometry.boundingBox.max,
|
|
min = geometry.boundingBox.min;
|
|
let offset = new THREE.Vector2(0 - min.x, 0 - min.y);
|
|
let range = new THREE.Vector2(max.x - min.x, max.y - min.y);
|
|
let addX = 1,
|
|
addY = 1;
|
|
range.x / range.y < 1
|
|
? (addX = range.x / range.y)
|
|
: (addY = range.y / range.x);
|
|
geometry.faceVertexUvs[0] = [];
|
|
|
|
for (let face of geometry.faces) {
|
|
let v1 = geometry.vertices[face.a],
|
|
v2 = geometry.vertices[face.b],
|
|
v3 = geometry.vertices[face.c];
|
|
if (face.normal.z == 0) {
|
|
//侧面
|
|
if (range.x / range.y >= 1) {
|
|
let repY = range.y / 256 >= 2 ? 256 : range.y;
|
|
face.materialIndex = Math.abs(face.normal.x) < 0.7 ? 2 : 1;
|
|
geometry.faceVertexUvs[0].push(
|
|
face.materialIndex == 1
|
|
? [
|
|
new THREE.Vector2((v1.y + offset.y) / repY, v1.z / 512),
|
|
new THREE.Vector2((v2.y + offset.y) / repY, v2.z / 512),
|
|
new THREE.Vector2((v3.y + offset.y) / repY, v3.z / 512),
|
|
]
|
|
: [
|
|
new THREE.Vector2((v1.x + offset.x) / range.x, v1.z / 64),
|
|
new THREE.Vector2((v2.x + offset.x) / range.x, v2.z / 64),
|
|
new THREE.Vector2((v3.x + offset.x) / range.x, v3.z / 64),
|
|
]
|
|
);
|
|
} else {
|
|
face.materialIndex = Math.abs(face.normal.x) < 0.7 ? 1 : 2;
|
|
geometry.faceVertexUvs[0].push(
|
|
face.materialIndex == 1
|
|
? [
|
|
new THREE.Vector2((v1.x + offset.x) / range.x, v1.z / 512),
|
|
new THREE.Vector2((v2.x + offset.x) / range.x, v2.z / 512),
|
|
new THREE.Vector2((v3.x + offset.x) / range.x, v3.z / 512),
|
|
]
|
|
: [
|
|
new THREE.Vector2((v1.y + offset.y) / range.y, v1.z / 64),
|
|
new THREE.Vector2((v2.y + offset.y) / range.y, v2.z / 64),
|
|
new THREE.Vector2((v3.y + offset.y) / range.y, v3.z / 64),
|
|
]
|
|
);
|
|
}
|
|
} else {
|
|
//顶面和底面
|
|
face.materialIndex = 0;
|
|
geometry.faceVertexUvs[0].push([
|
|
new THREE.Vector2(
|
|
((v1.x + offset.x) / range.x) * addX,
|
|
((v1.y + offset.y) / range.y) * addY
|
|
),
|
|
new THREE.Vector2(
|
|
((v2.x + offset.x) / range.x) * addX,
|
|
((v2.y + offset.y) / range.y) * addY
|
|
),
|
|
new THREE.Vector2(
|
|
((v3.x + offset.x) / range.x) * addX,
|
|
((v3.y + offset.y) / range.y) * addY
|
|
),
|
|
]);
|
|
}
|
|
}
|
|
geometry.uvsNeedUpdate = true;
|
|
};
|
|
this.packUv = function (geometry) {
|
|
geometry.computeBoundingBox();
|
|
let max = geometry.boundingBox.max,
|
|
min = geometry.boundingBox.min;
|
|
let offset = new THREE.Vector2(0 - min.x, 0 - min.y);
|
|
let range = new THREE.Vector2(max.x - min.x, max.y - min.y);
|
|
geometry.faceVertexUvs[0] = [];
|
|
let allReag = 0;
|
|
for (let i = 0; i < geometry.faces.length; i += 2) {
|
|
let v1 = geometry.vertices[geometry.faces[i].a],
|
|
v2 = geometry.vertices[geometry.faces[i].b];
|
|
if (geometry.faces[i].normal.z == 0) {
|
|
//侧面
|
|
if (Math.abs(geometry.faces[i].normal.x) < 0.7) {
|
|
//左右
|
|
allReag += Math.abs(v2.x - v1.x);
|
|
} else {
|
|
allReag += Math.abs(v2.y - v1.y);
|
|
}
|
|
}
|
|
}
|
|
for (let face of geometry.faces) {
|
|
let v1 = geometry.vertices[face.a],
|
|
v2 = geometry.vertices[face.b],
|
|
v3 = geometry.vertices[face.c];
|
|
if (face.normal.z == 0) {
|
|
//侧面
|
|
face.materialIndex = 1;
|
|
if (Math.abs(face.normal.x) < 0.7) {
|
|
//前后
|
|
geometry.faceVertexUvs[0].push([
|
|
new THREE.Vector2((v1.x + offset.x) / allReag, v1.z / 512),
|
|
new THREE.Vector2((v2.x + offset.x) / allReag, v2.z / 512),
|
|
new THREE.Vector2((v3.x + offset.x) / allReag, v3.z / 512),
|
|
]);
|
|
} else {
|
|
geometry.faceVertexUvs[0].push([
|
|
new THREE.Vector2((v1.y + offset.y) / allReag, v1.z / 512),
|
|
new THREE.Vector2((v2.y + offset.y) / allReag, v2.z / 512),
|
|
new THREE.Vector2((v3.y + offset.y) / allReag, v3.z / 512),
|
|
]);
|
|
}
|
|
} else {
|
|
//顶面和底面
|
|
face.materialIndex = 0;
|
|
geometry.faceVertexUvs[0].push([
|
|
new THREE.Vector2(
|
|
(v1.x + offset.x) / range.x,
|
|
(v1.y + offset.y) / range.y
|
|
),
|
|
new THREE.Vector2(
|
|
(v2.x + offset.x) / range.x,
|
|
(v2.y + offset.y) / range.y
|
|
),
|
|
new THREE.Vector2(
|
|
(v3.x + offset.x) / range.x,
|
|
(v3.y + offset.y) / range.y
|
|
),
|
|
]);
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* 检测点是否在多边形区域内
|
|
*/
|
|
this.checkBoundary = function (p, ptPolygon) {
|
|
// 判断边界方法
|
|
let nCount = ptPolygon.length;
|
|
let nCross = 0;
|
|
for (let i = 0; i < nCount; i++) {
|
|
let p1 = ptPolygon[i]; //当前节点
|
|
let p2 = ptPolygon[(i + 1) % nCount]; //下一个节点
|
|
// 求解 y=p.y 与 p1p2 的交点
|
|
if (p1.y == p2.y)
|
|
// p1p2 与 y=p0.y平行
|
|
continue;
|
|
if (p.y < Math.min(p1.y, p2.y))
|
|
// 交点在p1p2延长线上
|
|
continue;
|
|
if (p.y >= Math.max(p1.y, p2.y))
|
|
// 交点在p1p2延长线上
|
|
continue;
|
|
// 从P发射一条水平射线 求交点的 X 坐标 ------原理: ((p2.y-p1.y)/(p2.x-p1.x))=((y-p1.y)/(x-p1.x))
|
|
//直线k值相等 交点y=p.y
|
|
let x = ((p.y - p1.y) * (p2.x - p1.x)) / (p2.y - p1.y) + p1.x;
|
|
if (x > p.x) nCross++; // 只统计单边交点
|
|
}
|
|
// 单边交点为偶数,点在多边形之外 ---
|
|
return nCross % 2 == 1;
|
|
};
|
|
this.requestNoJM = function (params) {
|
|
params.method = params.method || "GET";
|
|
let xmlhttp = new XMLHttpRequest();
|
|
xmlhttp.onreadystatechange = function () {
|
|
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
|
|
let jsonObject;
|
|
try {
|
|
jsonObject = JSON.parse(xmlhttp.responseText);
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
params.fail();
|
|
return;
|
|
}
|
|
params.success(jsonObject);
|
|
}
|
|
if (
|
|
xmlhttp.readyState === 4 &&
|
|
(xmlhttp.status === 404 || xmlhttp.status === 405)
|
|
) {
|
|
params.fail();
|
|
}
|
|
};
|
|
xmlhttp.onerror = function () {
|
|
params.fail();
|
|
};
|
|
xmlhttp.open(params.method, params.url, true);
|
|
//xmlhttp.setRequestHeader("Access-Control-Allow-Origin", "*");
|
|
xmlhttp.setRequestHeader("Content-type", "application/json");
|
|
xmlhttp.send(params.data);
|
|
};
|
|
//解密
|
|
this.decrypt = function (word, keyStr) {
|
|
keyStr = keyStr ? keyStr : "cqmyg#hdhxt!saas";
|
|
var key = CryptoJS.enc.Utf8.parse(keyStr); //Latin1 w8m31+Yy/Nw6thPsMpO5fg==
|
|
var decrypt = CryptoJS.AES.decrypt(word, key, {
|
|
mode: CryptoJS.mode.ECB,
|
|
padding: CryptoJS.pad.Pkcs7,
|
|
});
|
|
return CryptoJS.enc.Utf8.stringify(decrypt).toString();
|
|
};
|
|
this.timeStamp = function () {
|
|
return parseInt(new Date().getTime() / 1000);
|
|
};
|
|
|
|
this.readTextFile = function (file, callback) {
|
|
let rawFile = new XMLHttpRequest();
|
|
rawFile.overrideMimeType("application/json");
|
|
rawFile.open("GET", file, true);
|
|
rawFile.onreadystatechange = function () {
|
|
if (rawFile.readyState === 4 && rawFile.status == 200) {
|
|
try {
|
|
let jsonObject = JSON.parse(rawFile.response);
|
|
callback(jsonObject);
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
}
|
|
}
|
|
};
|
|
rawFile.onerror = function () {
|
|
callback(null);
|
|
};
|
|
rawFile.send(null);
|
|
};
|
|
/**碰撞检测
|
|
* 传入A中心点和A的宽、高
|
|
* B的中心点和B的宽、高
|
|
*/
|
|
this.isCollision = function (A, B) {
|
|
return (
|
|
A.x < B.x + B.width &&
|
|
A.x + A.width > B.x &&
|
|
A.y < B.y + B.height &&
|
|
A.y + A.height > B.y
|
|
);
|
|
};
|
|
this.changeParkToString = function (area) {
|
|
let areaArr = [];
|
|
for (let i = 0; i < area.hasLines.length; i++) {
|
|
let line = area.hasLines[i];
|
|
let array = [];
|
|
array.push(
|
|
line.startPoint.x,
|
|
line.startPoint.y,
|
|
line.endPoint.x,
|
|
line.endPoint.y
|
|
);
|
|
areaArr.push(array);
|
|
}
|
|
return areaArr;
|
|
};
|
|
this.changeAreaToString = function (area) {
|
|
let areaArr = [];
|
|
for (let i = 0; i < area.hasLines.length; i++) {
|
|
let line = area.hasLines[i];
|
|
let array = [];
|
|
if (line.isStrLine) {
|
|
array.push(
|
|
line.startPoint.x,
|
|
line.startPoint.y,
|
|
line.endPoint.x,
|
|
line.endPoint.y
|
|
);
|
|
} else {
|
|
array.push(
|
|
line.startPoint.x,
|
|
line.startPoint.y,
|
|
line.ctrlPoint1.x,
|
|
line.ctrlPoint1.y,
|
|
line.ctrlPoint2.x,
|
|
line.ctrlPoint2.y,
|
|
line.endPoint.x,
|
|
line.endPoint.y
|
|
);
|
|
}
|
|
areaArr.push(array);
|
|
}
|
|
return areaArr;
|
|
};
|
|
this.changeWallToString = function (area) {
|
|
let areaArr = [];
|
|
let points = Map_QM.util.getWallPoints(area.pathPoints, area.thick);
|
|
for (let i = 0; i < points.length; i++) {
|
|
let array = [];
|
|
let pend = i == points.length - 1 ? points[0] : points[i + 1];
|
|
array.push(points[i].x, points[i].y, pend.x, pend.y);
|
|
areaArr.push(array);
|
|
}
|
|
return areaArr;
|
|
};
|
|
|
|
this.QM_Line_Father = function (
|
|
sPoint,
|
|
ePoint,
|
|
ctrlPoint1,
|
|
ctrlPoint2,
|
|
isStrLine
|
|
) {
|
|
this.startPoint = sPoint; //起始点
|
|
this.endPoint = ePoint; //结束点
|
|
this.ctrlPoint1 = ctrlPoint1;
|
|
this.ctrlPoint2 = ctrlPoint2;
|
|
this.isStrLine = isStrLine; //是否是直线
|
|
};
|
|
//根据配置参数转换店铺圆角
|
|
this.changeShopLinesToString = function (area) {
|
|
let areaStr = [];
|
|
let lines = [];
|
|
for (let m = 0; m < area.hasLines.length; m++) {
|
|
let sPoint, ePoint, cPoint1, cPoint2;
|
|
sPoint = new Map_QM.util.Point(
|
|
area.hasLines[m].startPoint.x,
|
|
area.hasLines[m].startPoint.y
|
|
);
|
|
ePoint = new Map_QM.util.Point(
|
|
area.hasLines[m].endPoint.x,
|
|
area.hasLines[m].endPoint.y
|
|
);
|
|
if (area.hasLines[m].isStrLine) {
|
|
cPoint1 = null;
|
|
cPoint2 = null;
|
|
} else {
|
|
cPoint1 = new Map_QM.util.Point(
|
|
area.hasLines[m].ctrlPoint1.x,
|
|
area.hasLines[m].ctrlPoint1.y
|
|
);
|
|
cPoint2 = new Map_QM.util.Point(
|
|
area.hasLines[m].ctrlPoint2.x,
|
|
area.hasLines[m].ctrlPoint2.y
|
|
);
|
|
}
|
|
let line = new Map_QM.util.QM_Line_Father(
|
|
sPoint,
|
|
ePoint,
|
|
cPoint1,
|
|
cPoint2,
|
|
area.hasLines[m].isStrLine
|
|
);
|
|
lines.push(line);
|
|
}
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
let line0 = lines[i];
|
|
let line1 = i < lines.length - 1 ? lines[i + 1] : lines[0];
|
|
if (Map_QM.util.options.aRadius > 2) {
|
|
if (line0.isStrLine &&line1.isStrLine &&Math.abs(line0.endPoint.x - line0.startPoint.x) + Math.abs(line0.endPoint.y - line0.startPoint.y) > parseInt(Map_QM.util.options.aRadius) * 2) {
|
|
let x1 = line0.endPoint.x;
|
|
let y1 = line0.endPoint.y;
|
|
let x2 = line0.startPoint.x;
|
|
let y2 = line0.startPoint.y;
|
|
let x3 = line1.endPoint.x;
|
|
let y3 = line1.endPoint.y;
|
|
if (Math.abs((x3 - x1) / (x2 - x1) - (y3 - y1) / (y2 - y1)) < 0.1) {
|
|
let yArr = [];
|
|
yArr.push(line0.startPoint.x,line0.startPoint.y, line0.endPoint.x, line0.endPoint.y);
|
|
areaStr.push(yArr);
|
|
continue;
|
|
}
|
|
|
|
let result = Map_QM.util.getIncircleByLines(x1,y1,x2,y2,x3,y3,Map_QM.util.options.aRadius);
|
|
let bezierResult = Map_QM.util.getBezier(result.center.x,result.center.y, result.tangencyPoints[0].x, result.tangencyPoints[0].y, result.tangencyPoints[1].x, result.tangencyPoints[1].y, x1, y1, Map_QM.util.options.aRadius);
|
|
|
|
if (i > 0) {
|
|
let ctrlPoint1,
|
|
ctrlPoint2,
|
|
array = [];
|
|
ctrlPoint1 = ctrlPoint2 = new Map_QM.util.Point(((bezierResult[0].x - line0.startPoint.x) / 2 + line0.startPoint.x) >>0, ((bezierResult[0].y - line0.startPoint.y) / 2 +line0.startPoint.y) >> 0); //控制点
|
|
array.push(
|
|
line0.startPoint.x,
|
|
line0.startPoint.y,
|
|
ctrlPoint1.x,
|
|
ctrlPoint1.y,
|
|
ctrlPoint2.x,
|
|
ctrlPoint2.y,
|
|
bezierResult[0].x,
|
|
bezierResult[0].y
|
|
);
|
|
areaStr.push(array);
|
|
} else {
|
|
lines[0].endPoint.x = bezierResult[0].x;
|
|
lines[0].endPoint.y = bezierResult[0].y;
|
|
}
|
|
let arr = [];
|
|
arr.push(
|
|
bezierResult[0].x,
|
|
bezierResult[0].y,
|
|
bezierResult[1].x,
|
|
bezierResult[1].y,
|
|
bezierResult[2].x,
|
|
bezierResult[2].y,
|
|
bezierResult[3].x,
|
|
bezierResult[3].y
|
|
);
|
|
areaStr.push(arr);
|
|
line1.startPoint.x = bezierResult[3].x;
|
|
line1.startPoint.y = bezierResult[3].y;
|
|
} else {
|
|
/////////////////////////////
|
|
if (i != 0) {
|
|
let pArr = [];
|
|
if (line0.isStrLine) {
|
|
pArr.push(
|
|
line0.startPoint.x,
|
|
line0.startPoint.y,
|
|
line0.endPoint.x,
|
|
line0.endPoint.y
|
|
);
|
|
} else {
|
|
pArr.push(
|
|
line0.startPoint.x,
|
|
line0.startPoint.y,
|
|
line0.ctrlPoint1.x,
|
|
line0.ctrlPoint1.y,
|
|
line0.ctrlPoint2.x,
|
|
line0.ctrlPoint2.y,
|
|
line0.endPoint.x,
|
|
line0.endPoint.y
|
|
);
|
|
}
|
|
areaStr.push(pArr);
|
|
}
|
|
}
|
|
if (i == lines.length - 1) {
|
|
let ocPoint1,
|
|
ocPoint2,
|
|
oArr = [];
|
|
if (line1.isStrLine) {
|
|
oArr.push(
|
|
line1.startPoint.x,
|
|
line1.startPoint.y,
|
|
line1.endPoint.x,
|
|
line1.endPoint.y
|
|
);
|
|
} else {
|
|
ocPoint1 = new Map_QM.util.Point(line1.ctrlPoint1.x,line1.ctrlPoint1.y);
|
|
ocPoint2 = new Map_QM.util.Point(line1.ctrlPoint2.x,line1.ctrlPoint2.y);
|
|
oArr.push(
|
|
line1.startPoint.x,
|
|
line1.startPoint.y,
|
|
ocPoint1.x,
|
|
ocPoint1.y,
|
|
ocPoint2.x,
|
|
ocPoint2.y,
|
|
line1.endPoint.x,
|
|
line1.endPoint.y
|
|
);
|
|
}
|
|
areaStr.push(oArr);
|
|
}
|
|
} else {
|
|
let yArr = [];
|
|
if (line0.isStrLine) {
|
|
yArr.push(line0.startPoint.x, line0.startPoint.y, line0.endPoint.x,line0.endPoint.y);
|
|
} else {
|
|
yArr.push(
|
|
line0.startPoint.x,line0.startPoint.y,
|
|
line0.ctrlPoint1.x,line0.ctrlPoint1.y,
|
|
line0.ctrlPoint2.x, line0.ctrlPoint2.y,
|
|
line0.endPoint.x, line0.endPoint.y
|
|
);
|
|
}
|
|
areaStr.push(yArr);
|
|
}
|
|
}
|
|
return areaStr;
|
|
};
|
|
|
|
//根据圆心、两个切点、切点相交线顶点和半径 计算三次贝塞尔曲线的控制点
|
|
this.getBezier = function (x1, y1, x2, y2, x3, y3, x4, y4, radius) {
|
|
//切线向量A
|
|
var vectorAx = x2 - x1;
|
|
var vectorAy = y2 - y1;
|
|
//切线向量B
|
|
var vectorBx = x3 - x1;
|
|
var vectorBy = y3 - y1;
|
|
|
|
//计算切点和圆形组成相交线的夹角
|
|
var angle = Math.acos(
|
|
(vectorAx * vectorBx + vectorAy * vectorBy) /
|
|
(Math.sqrt(vectorAx * vectorAx + vectorAy * vectorAy) *
|
|
Math.sqrt(vectorBx * vectorBx + vectorBy * vectorBy))
|
|
);
|
|
//计算切点到控制点的距离
|
|
var tempDistence = (4 / 3) * radius * Math.tan(angle / 4);
|
|
return [
|
|
{
|
|
x: x2,
|
|
y: y2,
|
|
},
|
|
Map_QM.util.getPointFromLine(x2, y2, x4, y4, tempDistence),
|
|
Map_QM.util.getPointFromLine(x3, y3, x4, y4, tempDistence),
|
|
{
|
|
x: x3,
|
|
y: y3,
|
|
},
|
|
];
|
|
};
|
|
//根据半径计算两条线段相切圆的圆心和切点坐标
|
|
this.getIncircleByLines = function (x1, y1, x2, y2, x3, y3, radius) {
|
|
//向量夹角
|
|
let angle = Map_QM.util.getVectorAngle(x2 - x1, y2 - y1, x3 - x1, y3 - y1);
|
|
angle = (angle > 180 ? 360 - angle : angle) / 2;
|
|
//根据夹角计算侧边切点相对于顶点距离
|
|
let distance = radius / Math.tan((Math.PI * angle) / 180);
|
|
//计算侧边相切点具体坐标
|
|
let tangencyPoints = [
|
|
Map_QM.util.getPointFromLine(x1, y1, x2, y2, distance),
|
|
Map_QM.util.getPointFromLine(x1, y1, x3, y3, distance),
|
|
];
|
|
|
|
let centerX, centerY;
|
|
let areaSize = (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
|
|
//计算圆心坐标
|
|
if (areaSize < 0) {
|
|
centerX =
|
|
(tangencyPoints[0].x * (1 / Math.tan((Math.PI * angle) / 180)) +
|
|
tangencyPoints[0].y -y1) /(1 / Math.tan((Math.PI * angle) / 180));
|
|
centerY = (tangencyPoints[0].y * (1 / Math.tan((Math.PI * angle) / 180)) + x1 - tangencyPoints[0].x) /(1 / Math.tan((Math.PI * angle) / 180));
|
|
} else {
|
|
centerX = (tangencyPoints[1].x * (1 / Math.tan((Math.PI * angle) / 180)) +tangencyPoints[1].y -y1) / (1 / Math.tan((Math.PI * angle) / 180));
|
|
centerY = (tangencyPoints[1].y * (1 / Math.tan((Math.PI * angle) / 180)) + x1 -tangencyPoints[1].x) /(1 / Math.tan((Math.PI * angle) / 180));
|
|
}
|
|
return {
|
|
center: {
|
|
x: centerX,
|
|
y: centerY,
|
|
},
|
|
tangencyPoints: tangencyPoints,
|
|
angle: (Math.PI * angle) / 90,
|
|
};
|
|
};
|
|
|
|
//根据距离计算线段上某一点的具体坐标
|
|
this.getPointFromLine = function (startX, startY, endX, endY, distance) {
|
|
if (startX == endX)
|
|
return {
|
|
x: startX,
|
|
y: startY < endY ? startY + distance : startY - distance,
|
|
};
|
|
|
|
let k = ((startY - endY) * 1.0) / (startX - endX);
|
|
let b = startY - k * startX;
|
|
let A = Math.pow(k, 2) + 1;
|
|
let B = 2 * ((b - startY) * k - startX);
|
|
let C =
|
|
Math.pow(b - startY, 2) + Math.pow(startX, 2) - Math.pow(distance, 2);
|
|
let x1 = (-B + Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
|
|
let x2 = (-B - Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
|
|
let x = 0;
|
|
|
|
if (x1 == x2) x = x1;
|
|
else if ((startX <= x1 && x1 <= endX) || (endX <= x1 && x1 <= startX))
|
|
x = x1;
|
|
else if ((startX <= x2 && x2 <= endX) || (endX <= x2 && x2 <= startX))
|
|
x = x2;
|
|
|
|
let y = k * x + b;
|
|
return {
|
|
x: x,
|
|
y: y,
|
|
};
|
|
};
|
|
|
|
//计算两个向量之间的夹角
|
|
this.getVectorAngle = function (x1, y1, x2, y2) {
|
|
let epsilon = 1.0e-6;
|
|
let dist, dot, degree, angle;
|
|
dist = Math.sqrt(x1 * x1 + y1 * y1);
|
|
x1 /= dist;
|
|
y1 /= dist;
|
|
dist = Math.sqrt(x2 * x2 + y2 * y2);
|
|
x2 /= dist;
|
|
y2 /= dist;
|
|
dot = x1 * x2 + y1 * y2;
|
|
if (Math.abs(dot - 1.0) <= epsilon) angle = 0;
|
|
else if (Math.abs(dot + 1.0) <= epsilon) angle = Math.PI;
|
|
else {
|
|
angle = Math.acos(dot);
|
|
let cross = x1 * y2 - x2 * y1;
|
|
if (cross < 0) angle = 2 * Math.PI - angle;
|
|
}
|
|
degree = (angle * 180) / Math.PI;
|
|
return degree;
|
|
};
|
|
//检测区域是否在区域内 true (area2包含area)
|
|
this.checkAreaInArea = function (area, area2) {
|
|
if (!area2.hasLines || !area.hasLines) {
|
|
return false;
|
|
}
|
|
let ptPolygon = [];
|
|
for (let i = 0; i < area2.hasLines.length; i++) {
|
|
let line = area2.hasLines[i];
|
|
let pArr;
|
|
if (line.isStrLine) {
|
|
pArr = Map_QM.util.getPointArrOnLine(line.startPoint, line.endPoint);
|
|
} else {
|
|
pArr = Map_QM.util.getPointArr(line.startPoint, line.ctrlPoint1,line.ctrlPoint2,line.endPoint,0.1);
|
|
}
|
|
ptPolygon.push(...pArr);
|
|
}
|
|
for (let f = 0; f < area.hasLines.length; f++) {
|
|
let line2 = area.hasLines[f];
|
|
let sPoint = Map_QM.util.checkBoundary(new Map_QM.util.Point(line2.startPoint.x, line2.startPoint.y),ptPolygon);
|
|
let ePoint = Map_QM.util.checkBoundary(new Map_QM.util.Point(line2.endPoint.x, line2.endPoint.y),ptPolygon);
|
|
if (!sPoint || !ePoint) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* 返回取得点的数组
|
|
* s1--起点 s2 --终点 s3,s4 --控制点
|
|
*/
|
|
this.getPointArr = function (s1, s3, s4, s2, sp = 0.01) {
|
|
let pArr = [];
|
|
let sz = [s1, s3, s4, s2];
|
|
let p;
|
|
for (let j = 0; j < 1; j += sp) {
|
|
p = Map_QM.util.P_BEZ(j, sz);
|
|
pArr.push(p);
|
|
}
|
|
return pArr;
|
|
};
|
|
|
|
this.P_BEZ = function (t, sz) {
|
|
//n次
|
|
let x_p = 0;
|
|
let y_p = 0;
|
|
let n = sz.length;
|
|
for (let i = 0; i < sz.length; i++) {
|
|
let son = Map_QM.util.jie_cheng(n - 1);
|
|
let mother = Map_QM.util.jie_cheng(i) * Map_QM.util.jie_cheng(n - 1 - i);
|
|
let b = (son / mother) * Math.pow(t, i) * Math.pow(1 - t, n - 1 - i);
|
|
x_p += sz[i].x * b;
|
|
y_p += sz[i].y * b;
|
|
}
|
|
|
|
x_p = Number(x_p * 1000) / 1000;
|
|
y_p = Number(y_p * 1000) / 1000;
|
|
return new Map_QM.util.Point(x_p, y_p);
|
|
};
|
|
|
|
this.jie_cheng = function (i) {
|
|
//阶乘
|
|
let n = 1;
|
|
for (let j = 1; j <= i; j++) {
|
|
n *= j;
|
|
}
|
|
return n;
|
|
};
|
|
|
|
/**
|
|
* 获取线段上的所有点
|
|
*/
|
|
this.getPointArrOnLine = function (s1, s2) {
|
|
let points = [];
|
|
if (s1.x == s2.x) {
|
|
let vy = s1.y < s2.y ? 1 : -1;
|
|
for (let m = 1; m < Math.abs(s1.y - s2.y); m++) {
|
|
let y0 = s1.y + m * vy;
|
|
let x0 = s1.x;
|
|
points.push(new Map_QM.util.Point(x0, y0));
|
|
}
|
|
return points;
|
|
}
|
|
let k = (s1.y - s2.y) / (s1.x - s2.x); // 坐标直线斜率k
|
|
let b = s1.y - k * s1.x; // 坐标直线b
|
|
if (Math.abs(s1.x - s2.x) > Math.abs(s1.y - s2.y)) {
|
|
let vx = s1.x < s2.x ? 1 : -1;
|
|
for (let i = 1; i < Math.abs(s1.x - s2.x); i++) {
|
|
let x0 = s1.x + i * vx;
|
|
let y0 = k * x0 + b;
|
|
points.push(new Map_QM.util.Point(x0, y0));
|
|
}
|
|
} else {
|
|
let vy = s1.y < s2.y ? 1 : -1;
|
|
for (let n = 1; n < Math.abs(s1.y - s2.y); n++) {
|
|
let y0 = s1.y + n * vy;
|
|
let x0 = (y0 - b) / k;
|
|
points.push(new Map_QM.util.Point(x0, y0));
|
|
}
|
|
}
|
|
return points;
|
|
};
|
|
|
|
//转换公共设施type值
|
|
this.getFacType = function (str) {
|
|
for (let i = 0; i < typeObj.length; i++) {
|
|
if (typeObj[i].code && typeObj[i].code == str) {
|
|
return typeObj[i].type;
|
|
}
|
|
}
|
|
};
|
|
this.getFacName = function (str) {
|
|
for (let i = 0; i < typeObj.length; i++) {
|
|
if (typeObj[i].code && typeObj[i].code == str) {
|
|
return typeObj[i].name;
|
|
}
|
|
}
|
|
};
|
|
//店铺排序
|
|
this.sortShopByFloor = function (a, b) {
|
|
return a.floorOrder < b.floorOrder ? -1 : 1;
|
|
};
|
|
this.sortNode = function (a, b) {
|
|
return a.id - b.id;
|
|
};
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
this.getWallPoints = function (points, wallWidth) {
|
|
if (points.length < 2) {
|
|
return new Array();
|
|
}
|
|
//构建线段列表
|
|
let lines = new Array();
|
|
for (let index = 0; index < points.length - 1; index++) {
|
|
let startPoint = points[index];
|
|
let endPoint = points[index + 1];
|
|
let line = Map_QM.util.getParallelLine(startPoint, endPoint, wallWidth);
|
|
lines.push(line);
|
|
}
|
|
//生成线段对应的左右两侧平行线
|
|
for (let index = 0; index < lines.length - 1; index++) {
|
|
let start = lines[index];
|
|
let end = lines[index + 1];
|
|
if (
|
|
start.leftParLine != null &&
|
|
start.rightParLine != null &&
|
|
end.leftParLine != null &&
|
|
end.rightParLine != null
|
|
) {
|
|
start.leftPoint = Map_QM.util.getIntersectionByLines(
|
|
start.leftParLine,
|
|
end.leftParLine
|
|
);
|
|
start.rightPoint = Map_QM.util.getIntersectionByLines(
|
|
start.rightParLine,
|
|
end.rightParLine
|
|
);
|
|
}
|
|
}
|
|
//循环线段列表 获取墙体所有点位 顺序为 左侧起始点->左侧所有交点->左侧结束点->右侧结束点->右侧所有交点->右侧起始点
|
|
let leftPointList = new Array();
|
|
let rightPointList = new Array();
|
|
for (let index = 0; index < lines.length; index++) {
|
|
//第一条线段 记录左右两侧平行线的起点坐标
|
|
if (index == 0) {
|
|
leftPointList.push(lines[index].leftParLine.start);
|
|
rightPointList.push(lines[index].rightParLine.start);
|
|
}
|
|
//最后一条线段 记录左右两侧平行线的终点坐标
|
|
if (index == lines.length - 1) {
|
|
leftPointList.push(lines[index].leftParLine.end);
|
|
rightPointList.push(lines[index].rightParLine.end);
|
|
} else {
|
|
//记录线段左右平行线交点坐标
|
|
if (
|
|
!isNaN(lines[index].leftPoint.x) ||
|
|
!isNaN(lines[index].leftPoint.y) ||
|
|
!isNaN(lines[index].rightPoint.x) ||
|
|
!isNaN(lines[index].rightPoint.y)
|
|
) {
|
|
leftPointList.push(lines[index].leftPoint);
|
|
rightPointList.push(lines[index].rightPoint);
|
|
}
|
|
}
|
|
}
|
|
rightPointList.reverse();
|
|
return leftPointList.concat(rightPointList);
|
|
};
|
|
//生成线段左右两侧的平行线
|
|
this.getParallelLine = function (start, end, wallWidth) {
|
|
let line = new Map_QM.util.WallLine(start, end);
|
|
//计算当前线段的斜率
|
|
let gradient = (start.y - end.y) / (start.x - end.x);
|
|
//计算垂直线的斜率
|
|
let perGradient = -1 / gradient;
|
|
//获取垂直线上左右两侧 与当前点位相距一定距离的两个定点
|
|
let startResult = Map_QM.util.getParallelPoints( perGradient, start, wallWidth);
|
|
let endResult = Map_QM.util.getParallelPoints(perGradient, end, wallWidth);
|
|
let x1 = startResult[0].x;
|
|
let y1 = startResult[0].y;
|
|
let x2 = endResult[0].x;
|
|
let y2 = endResult[0].y;
|
|
let x3 = end.x;
|
|
let y3 = end.y;
|
|
let x4 = startResult[1].x;
|
|
let y4 = startResult[1].y;
|
|
let x5 = endResult[1].x;
|
|
let y5 = endResult[1].y;
|
|
let s = (x1 - x3) * (y2 - y3) - (y1 - y3) * (x2 - x3);
|
|
//判断点位位于线段的左侧还是右侧
|
|
if (s >= 0) {
|
|
line.leftParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x1, y1), new Map_QM.util.Point(x2, y2));
|
|
line.rightParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x4, y4), new Map_QM.util.Point(x5, y5));
|
|
} else {
|
|
line.leftParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x4, y4), new Map_QM.util.Point(x5, y5));
|
|
line.rightParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x1, y1), new Map_QM.util.Point(x2, y2));
|
|
}
|
|
return line;
|
|
};
|
|
// 生成线段起始 和 结束 点位 对应的 两条 与线段垂直的直线 并记录坐标
|
|
this.getParallelPoints = function (gradient, point, wallWidth) {
|
|
let x, y;
|
|
//斜率为无穷大时 计算不了垂直线 指定点位
|
|
if (gradient == Number.NEGATIVE_INFINITY || gradient == Number.POSITIVE_INFINITY) {
|
|
x = point.x;
|
|
y = point.y + 5;
|
|
} else {
|
|
//不是横线时 根据斜率计算点位
|
|
x = point.x + 5;
|
|
y = gradient * (x - point.x) + point.y;
|
|
}
|
|
|
|
return Map_QM.util.pointXY(
|
|
point,
|
|
new Map_QM.util.Point(x, y),
|
|
wallWidth / 2
|
|
);
|
|
};
|
|
// 获取点位在直线上的坐标
|
|
this.pointXY = function (curPoint, nextPoint, length) {
|
|
let result = new Array();
|
|
//x值相等 说明是竖线 只需增减y轴坐标
|
|
if (curPoint.x == nextPoint.x) {
|
|
result.push(new Map_QM.util.Point(curPoint.x, curPoint.y + length));
|
|
result.push(new Map_QM.util.Point(curPoint.x, curPoint.y - length));
|
|
return result;
|
|
}
|
|
//根据 斜率 和 距离 计算出对应的两个点位
|
|
let k = (curPoint.y - nextPoint.y) / (curPoint.x - nextPoint.x);
|
|
let b = curPoint.y - k * curPoint.x;
|
|
let A = Math.pow(k, 2) + 1;
|
|
let B = 2 * ((b - curPoint.y) * k - curPoint.x);
|
|
let C =
|
|
Math.pow(b - curPoint.y, 2) +
|
|
Math.pow(curPoint.x, 2) -
|
|
Math.pow(length, 2);
|
|
let x1 = (-B + Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
|
|
let x2 = (-B - Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
|
|
|
|
result.push(new Map_QM.util.Point(x1, k * x1 + b));
|
|
result.push(new Map_QM.util.Point(x2, k * x2 + b));
|
|
return result;
|
|
};
|
|
//计算两条直线的相交点
|
|
this.getIntersectionByLines = function (line1, line2) {
|
|
//直线斜率
|
|
let gradient1 =
|
|
(line1.end.y - line1.start.y) / (line1.end.x - line1.start.x);
|
|
let gradient2 =
|
|
(line2.end.y - line2.start.y) / (line2.end.x - line2.start.x);
|
|
//斜率差值小于一定范围 表示两条线近似平行 因为交点太远 可能超出屏幕 直接取线段中点为交点
|
|
if (Math.abs(gradient1 - gradient2) < 0.1)
|
|
return new Map_QM.util.Point(line1.end.x, line1.end.y);
|
|
let x1 = line1.start.x;
|
|
let y1 = line1.start.y;
|
|
let x2 = line1.end.x;
|
|
let y2 = line1.end.y;
|
|
let x3 = line2.start.x;
|
|
let y3 = line2.start.y;
|
|
let x4 = line2.end.x;
|
|
let y4 = line2.end.y;
|
|
|
|
//计算交点坐标
|
|
let x =
|
|
((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1)) /
|
|
((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
|
|
let y =
|
|
((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4)) /
|
|
((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
|
|
return new Map_QM.util.Point(x, y);
|
|
};
|
|
/**
|
|
* 根据色值获取材质
|
|
*/
|
|
this.getMeshMaterial = function (color, alphaModle = 0.9) {
|
|
let meshMaterial;
|
|
for (let k = 0; k < Map_QM.util.meshMaterialArr.length; k++) {
|
|
let color2 = new THREE.Color(color);
|
|
if (
|
|
Map_QM.util.meshMaterialArr[k].color &&
|
|
Map_QM.util.meshMaterialArr[k].color.equals(color2) &&
|
|
Map_QM.util.meshMaterialArr[k].opacity == alphaModle
|
|
) {
|
|
meshMaterial = Map_QM.util.meshMaterialArr[k];
|
|
}
|
|
}
|
|
if (!meshMaterial) {
|
|
meshMaterial = new THREE.MeshPhongMaterial({
|
|
color: color,
|
|
emissive: 0x000000,
|
|
specular: 0x000000,
|
|
transparent: true,
|
|
side: THREE.DoubleSide,
|
|
opacity: alphaModle,
|
|
});
|
|
Map_QM.util.meshMaterialArr.push(meshMaterial);
|
|
}
|
|
return meshMaterial;
|
|
};
|
|
this.rotateYZ = function (geometry, ry, rz) {
|
|
let center = new THREE.Vector3();
|
|
geometry.computeBoundingBox();
|
|
geometry.boundingBox.getCenter(center);
|
|
let x = center.x;
|
|
let y = center.y;
|
|
let z = center.z;
|
|
geometry.center();
|
|
geometry.rotateY(ry);
|
|
geometry.rotateX(rz);
|
|
geometry.translate(x, y, z);
|
|
};
|
|
//用于生成uuid
|
|
this.guid = function () {
|
|
function S4() {
|
|
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
|
}
|
|
return S4() + S4() + S4();
|
|
};
|
|
|
|
this.getTextMesh = function (text, position) {
|
|
const sprite = new SpriteText(text, 32, "#000000");
|
|
sprite.padding = 2;
|
|
sprite.fontSize = 32;
|
|
sprite.strokeWidth = 2;
|
|
sprite.renderOrder = 100;
|
|
sprite.fontWeight = "500";
|
|
sprite.material.transparent = true;
|
|
sprite.material.alphaTest = 0.1;
|
|
sprite.material.sizeAttenuation = false;
|
|
sprite.position.set(position.x, position.y, position.z + 24);
|
|
return sprite;
|
|
};
|
|
};
|
|
//////////////////////////////-------------------------------------------配置 UtilFun
|
|
/**
|
|
* 地图主类,入口 初始化设备点位
|
|
*/
|
|
var MainMap_QM = function (callBack, options) {
|
|
this.util = new QMUtil();
|
|
this.callBackLoadOver = callBack;
|
|
this.ele = document.getElementById(options.containerId || "mapContainer");
|
|
this.w = parseInt(this.ele.clientWidth) || parseInt(window.getComputedStyle(this.ele, null).getPropertyValue("width"));
|
|
this.h = parseInt(this.ele.clientHeight) ||parseInt(window.getComputedStyle(this.ele, null).getPropertyValue("height"));
|
|
this.backObj = { code: 200, msg: "加载成功", data: [] };
|
|
this.scene = new THREE.Scene();
|
|
this.scene.name = "scene";
|
|
//this.scene.fog = new THREE.Fog(0xe5e5e5,this.util.options.maxDis,this.util.options.maxDis + 500);
|
|
this.aspect = this.w / this.h;
|
|
this.cameraPerspective = new THREE.PerspectiveCamera(45,this.aspect,10,10000);
|
|
this.cameraPerspective.position.set(this.util.sceneGap.cameraX,this.util.sceneGap.cameraY,this.util.sceneGap.cameraZ); //x 水平 y 垂直旋转 z 展示大小
|
|
this.cameraPerspective.lookAt(new THREE.Vector3(0, 0, 0));
|
|
|
|
this.cameraOrtho = new THREE.OrthographicCamera(-150 * this.aspect, 150 * this.aspect, 150, -150, 10, 10000)
|
|
this.cameraOrtho.position.set(this.util.sceneGap.cameraX, this.util.sceneGap.cameraY, this.util.sceneGap.cameraZ)
|
|
this.cameraOrtho.lookAt(new THREE.Vector3(0, 0, 0))
|
|
this.camera = this.cameraPerspective;
|
|
//
|
|
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); // preserveDrawingBuffer 是否可以截图
|
|
//this.renderer.outputEncoding = THREE.sRGBEncoding;
|
|
this.renderer.setSize(this.w, this.h);
|
|
this.renderer.setPixelRatio(window.devicePixelRatio);
|
|
this.renderer.shadowMap.enabled = this.util.options.shadow;
|
|
// 阴影类型
|
|
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
this.ele.appendChild(this.renderer.domElement);
|
|
this.util.showHouseNumberAndName = options.showHouseNumberAndName;
|
|
this.labelRenderer = new THREE.CSS2DRenderer();
|
|
//弹窗的偏移百分比 或者像素
|
|
this.labelRenderer.setSize(this.w, this.h, options.perc_H || "-50%");
|
|
this.labelRenderer.domElement.style.position = "absolute";
|
|
this.labelRenderer.domElement.style.top = 0;
|
|
this.ele.appendChild(this.labelRenderer.domElement);
|
|
|
|
let light = new THREE.AmbientLight(0xffffff, 0.4);
|
|
light.name = "light";
|
|
this.scene.add(light);
|
|
this.hemiLight = new THREE.HemisphereLight(this.util.lightOptions.s_col,this.util.lightOptions.g_col,this.util.lightOptions.a_int);
|
|
this.hemiLight.name = "light";
|
|
this.hemiLight.position.set(0, 1, 0);
|
|
this.scene.add(this.hemiLight);
|
|
|
|
this.shawLight = new THREE.DirectionalLight(this.util.lightOptions.d_col,this.util.lightOptions.d_int);
|
|
this.shawLight.name = "light";
|
|
this.shawLight.position.set(280, 400, -300);
|
|
this.scene.add(this.shawLight);
|
|
|
|
this.controls = new THREE.OrbitControls(this.camera, this.ele);
|
|
this.controls.minZoom = 0.8;
|
|
this.controls.maxZoom = 2;
|
|
//设置相机距离原点的最远距离
|
|
this.controls.minDistance = this.util.options.minDis;
|
|
//设置相机距离原点的最远距离
|
|
this.controls.maxDistance = this.util.options.maxDis;
|
|
this.controls.minPolarAngle = 0; // 0是为了兼容2D模式
|
|
this.controls.maxPolarAngle = Math.PI / 2 - 0.2; // radians
|
|
|
|
this.ele.addEventListener("touchmove", this.mouseMove);
|
|
this.ele.addEventListener("touchend", this.mouseUp);
|
|
this.ele.addEventListener("click", this.onMouseClickBox); //地图点击
|
|
document.addEventListener("resize", this.changeDocmentResize); //窗口变化
|
|
this.mapArr = [];
|
|
this.selectShop;
|
|
this.selectEle = null; //当前使用的电梯
|
|
this.overShop; //终点店铺
|
|
this.shape = new THREE.Shape();
|
|
this.shape.moveTo(-10, -10);
|
|
this.shape.lineTo(10, -10);
|
|
this.shape.lineTo(10, 10);
|
|
this.shape.lineTo(-10, 10);
|
|
this.dtLineGroup = new THREE.Group();
|
|
this.dtLineGroup.name = "dtLine";
|
|
|
|
if (document.getElementById("moveFloorBG")) {
|
|
document.getElementById("moveFloorBG").style.zIndex = 500;
|
|
this.moveFloorbg = new THREE.CSS2DObject(
|
|
document.getElementById("moveFloorBG")
|
|
);
|
|
this.moveFloorbg.userData.isShow = false;
|
|
}
|
|
this.mixers = [];
|
|
this.man_3d = null;
|
|
this.man_2d = null;
|
|
this.guide = null;
|
|
this.devModel = null;
|
|
this.sceneGap = new THREE.Group();
|
|
this.outModelGap = new THREE.Group(); //全局外立面模型
|
|
this.scene.add(this.outModelGap);
|
|
this.peripheryGap = new THREE.Group(); //周边模型
|
|
this.scene.add(this.peripheryGap);
|
|
this.outObject = new THREE.Object3D();
|
|
this.outObject.userData.type = "moveFloor";
|
|
this.perObject = new THREE.Object3D();
|
|
this.perObject.userData.type = "moveFloor";
|
|
this.buildObj = new THREE.Group();
|
|
this.qiModel = null; //起点
|
|
this.qiIcon = null; //起点Icon
|
|
this.endIcon = null; //终点Icon
|
|
this.endModel = null;
|
|
this.forShopArr = []; //途径数据
|
|
this.getInstance(options);
|
|
if (this.util.options.northShow) {
|
|
this.util.img = document.createElement("img");
|
|
this.util.img.src = "./static/img/noth.png";
|
|
this.util.img.classList.add("north");
|
|
this.ele.appendChild(this.util.img);
|
|
}
|
|
};
|
|
MainMap_QM.prototype = {
|
|
resetModel: function () {
|
|
if (mapState == "mall") {
|
|
Map_QM.buildObj.visible = true;
|
|
Map_QM.controls.reset();
|
|
startRotate = false;
|
|
Map_QM.controls.setDistance(Map_QM.util.changeDist.inner - 25);
|
|
} else if (mapState == "out") {
|
|
Map_QM.controls.reset();
|
|
Map_QM.controls.setDistance(Map_QM.util.changeDist.inner + 30);
|
|
Map_QM.outModelGap.rotateY(-1 * Map_QM.outModelGap.rotation.y);
|
|
startRotate = true;
|
|
} else {
|
|
Map_QM.controls.reset();
|
|
Map_QM.controls.setDistance(Map_QM.util.changeDist.outner + 25);
|
|
startRotate = false;
|
|
}
|
|
Map_QM.controls.update();
|
|
renderCount = 0;
|
|
},
|
|
//隐藏活动标签(万象定制)
|
|
mouseMove: function () {
|
|
Map_QM.CSSObject && Map_QM.CSSObject.traverse((obj) => {
|
|
if (obj.userData.type == "tip") {
|
|
obj.element.style.visibility = "hidden";
|
|
}
|
|
});
|
|
},
|
|
//显示活动标签(万象定制)
|
|
mouseUp: function () {
|
|
Map_QM.CSSObject && Map_QM.CSSObject.traverse((obj) => {
|
|
if (obj.userData.type == "tip") {
|
|
obj.element.style.visibility = parseInt(obj.userData.floor) == Map_QM.util.selectFloor ? "visible": "hidden";
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @api {方法} getPointByNode() 获取导航点位的坐标
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 获取导航点位的坐标
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} str 导航点位
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.getPointByNode("0_0_1");
|
|
*/
|
|
getPointByNode: function (str) {
|
|
let nodes = str.split("_");
|
|
if (nodes.length > 2 && !isNaN(parseInt(nodes[2])) && parseInt(nodes[2])>=0) {
|
|
Map_QM.util.allMap[nodes[0]].buildArr[nodes[1]].mapData.path.nodes.sort(Map_QM.util.sortNode);
|
|
return Map_QM.util.allMap[nodes[0]].buildArr[nodes[1]].mapData.path.nodes[nodes[2]];
|
|
}else{
|
|
return {x:-5000,y:-5000,msg:"未打点"};
|
|
}
|
|
},
|
|
getInstance: function (options) {
|
|
this.util.startObj.build = this.util.deviceObj.build = parseInt(options.build) || 0;
|
|
this.util.startObj.node = this.util.deviceObj.node = parseInt(options.navPoint) || 1;
|
|
this.util.deviceObj.angle = parseInt(options.angle) || 0;
|
|
this.util.selectBuild = this.util.deviceObj.build;
|
|
let _space = this;
|
|
if (options.mallCode) {
|
|
let tim = this.util.timeStamp();
|
|
this.util.requestNoJM({
|
|
method: "GET",
|
|
url: options.url + "/api/info/v1/web/getUploadUrl",
|
|
success: (res) => {
|
|
let resText = res.data;
|
|
if (typeof resText === "string" &&resText.search("https://") === -1) {
|
|
resText = JSON.parse(_space.util.decrypt(res.data));
|
|
}
|
|
_space.tomUrl = resText;
|
|
this.util.requestNoJM({
|
|
method: "GET",
|
|
url: _space.tomUrl + "/ar/" + options.mallCode +"/config.json?a=" +tim,
|
|
success: (res) => {
|
|
_space.util.shopServerInfo = res.shopUrl;
|
|
_space.util.mapServerInfo = res.mapUrl;
|
|
_space.initLoadMapFile(options);
|
|
},
|
|
fail: () => {
|
|
_space.backObj.code = 404;
|
|
_space.backObj.msg = "地图数据获取失败";
|
|
_space.callBackLoadOver(_space.backObj);
|
|
_space.callBackLoadOver = null;
|
|
},
|
|
});
|
|
},
|
|
fail: () => {
|
|
this.util.requestNoJM({
|
|
method: "GET",
|
|
url: _space.tomUrl +"/ar/" +options.mallCode +"/config.json?a=" +tim,
|
|
success: (res) => {
|
|
_space.util.shopServerInfo = res.shopUrl;
|
|
_space.util.mapServerInfo = res.mapUrl;
|
|
_space.initLoadMapFile(options);
|
|
},
|
|
fail: () => {
|
|
_space.backObj.code = 404;
|
|
_space.backObj.msg = "地图数据获取失败";
|
|
_space.callBackLoadOver(_space.backObj);
|
|
_space.callBackLoadOver = null;
|
|
},
|
|
});
|
|
},
|
|
});
|
|
} else {
|
|
if (options.mapData) {
|
|
try {
|
|
_space.util.allMap = JSON.parse(options.mapData.mapData);
|
|
console.log("地图数据更新时间: " + options.mapData.updateTime);
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
_space.backObj.code = 404;
|
|
_space.backObj.msg = "地图数据JSON格式错误";
|
|
_space.callBackLoadOver(_space.backObj);
|
|
return;
|
|
}
|
|
_space.util.shopData = options.shopData;
|
|
_space.initOptions(options);
|
|
} else {
|
|
_space.initLoadMapFile(options);
|
|
}
|
|
}
|
|
},
|
|
|
|
initLoadMapFile: function (options) {
|
|
let _space = this;
|
|
_space.util.readTextFile(_space.util.mapServerInfo, function (res) {
|
|
if (res) {
|
|
try {
|
|
if (Array.isArray(res.data)) {
|
|
for (let map of res.data) {
|
|
_space.util.allMap = JSON.parse(map.mapData);
|
|
}
|
|
} else {
|
|
_space.util.allMap = JSON.parse(res.data.mapData);
|
|
console.log("地图数据更新时间: " + res.data.updateTime);
|
|
}
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
_space.backObj.code = 404;
|
|
_space.backObj.msg = "地图数据JSON格式错误";
|
|
_space.callBackLoadOver(_space.backObj);
|
|
_space.callBackLoadOver = null;
|
|
return;
|
|
}
|
|
_space.util.readTextFile(_space.util.shopServerInfo, function (res) {
|
|
_space.util.shopData = [];
|
|
if (res) {
|
|
console.log("shopData: ",res.data);
|
|
res.data.forEach((item) => {
|
|
for (let shop of item) {
|
|
_space.util.shopData.push(...shop.shopList);
|
|
}
|
|
});
|
|
}
|
|
_space.initOptions(options);
|
|
});
|
|
} else {
|
|
_space.backObj.code = 404;
|
|
_space.backObj.msg = "地图数据JSON格式错误";
|
|
_space.callBackLoadOver(_space.backObj);
|
|
_space.callBackLoadOver = null;
|
|
return;
|
|
}
|
|
});
|
|
},
|
|
|
|
initOptions: function (options) {
|
|
//初始化参数
|
|
if (this.util.allMap[this.util.selectBuild].playSpeed) {
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("scale") && (this.util.options.mapScale = parseInt(this.util.allMap[this.util.selectBuild].scale));
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("playSpeed") && (this.util.options.playSpeed = parseInt( this.util.allMap[this.util.selectBuild].playSpeed));
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("collision") && (this.util.options.collision = this.util.allMap[this.util.selectBuild].collision);
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("navColor") && (this.util.options.navColor = this.util.allMap[this.util.selectBuild].navColor);
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("aRadius") && (this.util.options.aRadius = parseInt( this.util.allMap[this.util.selectBuild].aRadius));
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("boxShop") && (this.util.options.boxShop = this.util.allMap[this.util.selectBuild].boxShop.split(","));
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("shopStyle") && (this.util.options.shopStyle = this.util.allMap[this.util.selectBuild].shopStyle);
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("modelIcon") && (this.util.options.modelIcon = this.util.allMap[this.util.selectBuild].modelIcon);
|
|
this.util.allMap[this.util.selectBuild].hasOwnProperty("facSize") && (this.util.options.facSize = this.util.allMap[this.util.selectBuild].facSize);
|
|
//this.util.allMap[this.util.selectBuild].hasOwnProperty("m_scale") && (this.util.sceneGap.scale = this.util.allMap[this.util.selectBuild].m_scale);
|
|
//根据地图大小同步修改字体大小
|
|
spriteScale = 0.2-(this.util.sceneGap.scale-0.08);
|
|
|
|
this.hemiLight.color = new THREE.Color(this.util.allMap[this.util.selectBuild].s_col || "#fffff0");
|
|
this.hemiLight.groundColor = new THREE.Color(this.util.allMap[this.util.selectBuild].g_col || "#ffffff");
|
|
this.hemiLight.intensity = this.util.allMap[this.util.selectBuild].a_int || 0.6;
|
|
this.shawLight.color = new THREE.Color( this.util.allMap[this.util.selectBuild].d_col || "#ffffff");
|
|
this.shawLight.intensity = this.util.allMap[this.util.selectBuild].d_int || 0.3;
|
|
|
|
// if (this.util.allMap[this.util.selectBuild].c_site && this.util.allMap[this.util.selectBuild].c_site.split(",")) {
|
|
// this.util.sceneGap.cameraX = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[0]) || this.util.sceneGap.cameraX;
|
|
// this.util.sceneGap.cameraY = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[1]) || this.util.sceneGap.cameraY;
|
|
// this.util.sceneGap.cameraZ = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[2]) || this.util.sceneGap.cameraZ;
|
|
// }
|
|
// if (this.util.allMap[this.util.selectBuild].m_site && this.util.allMap[this.util.selectBuild].m_site.split(",")) {
|
|
// this.util.sceneGap.x = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[0]) || this.util.sceneGap.x;
|
|
// this.util.sceneGap.y = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[1]) || this.util.sceneGap.y;
|
|
// this.util.sceneGap.z = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[2]) || this.util.sceneGap.z;
|
|
// }
|
|
if (this.util.allMap[this.util.selectBuild].m_zoom) {
|
|
this.util.m_zoom = this.util.allMap[this.util.selectBuild].m_zoom;
|
|
}
|
|
}
|
|
let { playSpeed, collision, modelIcon, shopStyle, shadow, otherPath, navColor, iconUrl, iconName, inArea, pathColor, pathStyle} = options;
|
|
|
|
this.util.options.playSpeed = playSpeed != undefined ? playSpeed : this.util.options.playSpeed;
|
|
this.util.options.collision = collision != undefined ? collision : this.util.options.collision;
|
|
this.util.options.modelIcon = modelIcon != undefined ? modelIcon : this.util.options.modelIcon;
|
|
this.util.options.shopStyle = shopStyle != undefined ? shopStyle : this.util.options.shopStyle;
|
|
this.util.options.otherPath = otherPath != undefined ? otherPath : this.util.options.otherPath;
|
|
this.util.options.navColor = navColor != undefined ? navColor : this.util.options.navColor;
|
|
this.util.options.iconName = iconName != undefined ? iconName : this.util.options.iconName;
|
|
this.util.options.inArea = inArea != undefined ? inArea : this.util.options.inArea;
|
|
this.util.options.pathColor = pathColor != undefined ? pathColor : this.util.options.pathColor;
|
|
this.util.options.pathStyle = pathStyle != undefined ? pathStyle : this.util.options.pathStyle;
|
|
this.util.iconUrl = iconUrl != undefined ? iconUrl : [];
|
|
|
|
if (!isNaN(Number(options.floor))) {
|
|
this.util.startObj.floor = this.util.deviceObj.floor = parseInt(options.floor) || 0;
|
|
} else {
|
|
if (Array.isArray(this.util.allMap)) {
|
|
for (var iii = 0; iii < this.util.allMap[this.util.startObj.build].buildArr.length; iii++) {
|
|
if (this.util.allMap[this.util.startObj.build].buildArr[iii].name == options.floor) {
|
|
this.util.startObj.floor = this.util.deviceObj.floor = this.util.allMap[this.util.startObj.build].buildArr[iii].order;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//
|
|
for (let k = 0; k < this.util.allMap.length; k++) {
|
|
for (let kk = 0; kk < this.util.allMap[k].buildArr.length; kk++) {
|
|
let floor = this.util.allMap[k].buildArr[kk].mapData;
|
|
if (floor.models) {
|
|
for (let t = 0; t < floor.models.length; t++) {
|
|
for (let i = 0; i < this.util.modelStr.length; i++) {
|
|
if (floor.models[t].type == this.util.modelStr[i].key) {
|
|
this.util.modelStr[i].load = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
this.initOutModel();
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
this.callBackLoadOver({ code: 404, msg: "地图数据解析失败" });
|
|
this.callBackLoadOver = null;
|
|
}
|
|
},
|
|
//加载全局模型
|
|
initOutModel: function () {
|
|
let _this = this;
|
|
if (this.util.initModelArr && this.util.initModelArr.length > 0) {
|
|
for (let i = 0; i < _this.util.initModelArr.length; i++) {
|
|
let loader = new THREE.GLTFLoader();
|
|
loader.load( _this.util.beforPath + _this.util.initModelArr[i].url,
|
|
function (collada) {
|
|
collada.scene.scale.x = collada.scene.scale.y =collada.scene.scale.z = _this.util.initModelArr[i].scale;
|
|
collada.scene.position.set( _this.util.initModelArr[i].site.x, _this.util.initModelArr[i].site.y,_this.util.initModelArr[i].site.z);
|
|
collada.scene.rotation.set((_this.util.initModelArr[i].rot.x * Math.PI) / 180, (_this.util.initModelArr[i].rot.y * Math.PI) / 180,(_this.util.initModelArr[i].rot.z * Math.PI) / 180);
|
|
collada.scene.userData.type = _this.util.initModelArr[i].type;
|
|
for (let k = 0; k < collada.animations.length; k++) {
|
|
let mixer = new THREE.AnimationMixer(collada.scene);
|
|
mixer.clipAction(collada.animations[k]).play();
|
|
_this.mixers.push(mixer);
|
|
}
|
|
//////////////////////////////////////////////
|
|
collada.scene.traverse(function (child) {
|
|
if (child.type === "Mesh") {
|
|
child.userData.opacity = child.material.opacity;
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
}
|
|
});
|
|
collada.scene.name = "model"; //删除其它元素时过滤
|
|
if (_this.util.initModelArr[i].type == "out") {
|
|
_this.outModelGap.add(collada.scene);
|
|
} else if (_this.util.initModelArr[i].type == "periphery") {
|
|
_this.peripheryGap.add(collada.scene);
|
|
}
|
|
}
|
|
);
|
|
if (i == _this.util.initModelArr.length - 1) {
|
|
for (let u = 0; u < _this.util.tipArr.length; u++) {
|
|
let prite = document.createElement("div");
|
|
prite.style.zIndex = _this.util.tipArr[u].zIndex || 20;
|
|
prite.innerHTML = _this.util.tipArr[u].htmlUrl;
|
|
if (!_this.util.tipArr[u].click) {
|
|
prite.style.pointerEvents = "none";
|
|
}
|
|
let pointLabel2 = new THREE.CSS2DObject(prite);
|
|
pointLabel2.position.set(_this.util.tipArr[u].x, _this.util.tipArr[u].z, _this.util.tipArr[u].y);
|
|
pointLabel2.userData.type = "2d_IP";
|
|
pointLabel2.userData.show = _this.util.tipArr[u].show;
|
|
pointLabel2.userData.name = _this.util.tipArr[u].name || "";
|
|
if (pointLabel2.userData.show == language) {
|
|
pointLabel2.element.style.visibility = "visible";
|
|
} else {
|
|
pointLabel2.element.style.visibility = "hidden";
|
|
}
|
|
if (_this.util.tipArr[u].type == "out") {
|
|
_this.outObject.add(pointLabel2);
|
|
} else if (_this.util.tipArr[u].type == "periphery") {
|
|
_this.perObject.add(pointLabel2);
|
|
}
|
|
}
|
|
_this.initBuild();
|
|
}
|
|
}
|
|
} else {
|
|
_this.util.changeDist.inner = _this.util.options.maxDis;
|
|
_this.initBuild();
|
|
}
|
|
},
|
|
changePerTag: function (str) {
|
|
if (mapState == "periphery") {
|
|
Map_QM.perObject.traverse(function (child) {
|
|
if (child.userData && child.userData.show) {
|
|
if (child.userData.show.includes(str)) {
|
|
child.element.style.visibility = "visible";
|
|
} else {
|
|
child.element.style.visibility = "hidden";
|
|
}
|
|
}
|
|
});
|
|
Map_QM.peripheryGap.children[0].traverse(function (obj) {
|
|
if (obj.name == "road") {
|
|
obj.traverse(function (child) {
|
|
if (child.type === "Mesh" && child.name.search("road_") != -1) {
|
|
child.visible = false;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
initBuild: function () {
|
|
this.util.pathStateObj.elevator = null;
|
|
this.util.pathStateObj.straight = null;
|
|
this.util.pathStateObj.elevatorDown = null;
|
|
let loader2 = new THREE.GLTFLoader();
|
|
let _this = this;
|
|
loader2.load(this.util.beforPath + "static/img/zhong.glb",
|
|
function (collada2) {
|
|
collada2.scene.scale.x = collada2.scene.scale.y = collada2.scene.scale.z = 100;
|
|
collada2.scene.applyMatrix4(_this.sceneGap.matrix);
|
|
collada2.scene.renderOrder = 200;
|
|
collada2.scene.traverse(function (child) {
|
|
if (child.type === "Mesh") {
|
|
child.userData.opacity = child.material.opacity;
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
}
|
|
});
|
|
collada2.scene.name = "Z-model";
|
|
for (let k = 0; k < collada2.animations.length; k++) {
|
|
let mixer = new THREE.AnimationMixer(collada2.scene);
|
|
mixer.clipAction(collada2.animations[k]).play();
|
|
Map_QM.mixers.push(mixer);
|
|
}
|
|
_this.endModel = collada2.scene;
|
|
_this.scene.add(collada2.scene);
|
|
_this.endModel.visible = false;
|
|
}
|
|
);
|
|
|
|
let spriteMap = new THREE.TextureLoader().load(
|
|
_this.util.beforPath + "static/img/Z.png"
|
|
);
|
|
let spriteMaterial = new THREE.SpriteMaterial({
|
|
//sizeAttenuation: false 禁止跟随鼠标缩放
|
|
map: spriteMap,
|
|
depthTest: true,
|
|
transparent: true,
|
|
alphaTest: 0.5,
|
|
});
|
|
_this.endIcon = new MySprite_QM(spriteMaterial);
|
|
_this.endIcon.scale.set(100, 120, 1);
|
|
_this.endIcon.center = new THREE.Vector2(0.5, 0);
|
|
_this.endIcon.position.set(0, 55, 0);
|
|
_this.endIcon.applyMatrix4(_this.sceneGap.matrix);
|
|
_this.endIcon.renderOrder = 300;
|
|
_this.endIcon.visible = false;
|
|
_this.endIcon.name = "Z-model";
|
|
_this.scene.add(_this.endIcon);
|
|
if (_this.util.options.modelIcon) {
|
|
let loader = new THREE.GLTFLoader();
|
|
loader.load(_this.util.beforPath + "static/img/elevator.gltf",
|
|
function (collada) {
|
|
collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = _this.util.options.facSize || 20;
|
|
collada.scene.rotation.x = (-90 * Math.PI) / -180;
|
|
collada.scene.renderOrder = 300;
|
|
_this.util.pathStateObj.elevator = collada.scene;
|
|
|
|
new THREE.GLTFLoader().load(_this.util.beforPath + "static/img/elevatorDown.gltf",
|
|
function (collada) {
|
|
collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = _this.util.options.facSize || 20;
|
|
collada.scene.rotation.x = (-90 * Math.PI) / -180;
|
|
collada.scene.renderOrder = 300;
|
|
_this.util.pathStateObj.elevatorDown = collada.scene;
|
|
|
|
new THREE.GLTFLoader().load(_this.util.beforPath + "static/img/dt.gltf",
|
|
function (collada) {
|
|
collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = _this.util.options.facSize || 20;
|
|
collada.scene.rotation.x = (-90 * Math.PI) / -180;
|
|
collada.scene.renderOrder = 300;
|
|
_this.util.pathStateObj.straight = collada.scene;
|
|
_this.index = 0;
|
|
_this.initTreeModel();
|
|
}
|
|
);
|
|
}
|
|
);
|
|
}
|
|
);
|
|
} else {
|
|
_this.index = 0;
|
|
_this.initTreeModel();
|
|
}
|
|
},
|
|
loaderOver: function () {
|
|
this.sceneGap = new THREE.Group();
|
|
this.sceneGap.scale.set(this.util.sceneGap.scale, this.util.sceneGap.scale, this.util.sceneGap.scale);
|
|
this.scene.add(this.sceneGap);
|
|
this.buildObj = new THREE.Group();
|
|
this.sceneGap.add(this.buildObj);
|
|
this.CSSObject = new THREE.Object3D();
|
|
if (this.moveFloorbg) {
|
|
this.moveFloorbg.userData.type = "moveFloor";
|
|
this.CSSObject.add(this.moveFloorbg);
|
|
}
|
|
this.CSSObject.add(this.outObject);
|
|
this.CSSObject.add(this.perObject);
|
|
this.buildObj.add(this.CSSObject);
|
|
this.buildObj.add(this.dtLineGroup);
|
|
this.initGuide();
|
|
if (!this.util.options.deviceAng) {
|
|
this.cameraPerspective.position.set(this.util.sceneGap.cameraX, this.util.sceneGap.cameraY, this.util.sceneGap.cameraZ );
|
|
this.cameraPerspective.updateProjectionMatrix(); //必须update
|
|
this.cameraOrtho.position.set(this.util.sceneGap.cameraX, this.util.sceneGap.cameraY, this.util.sceneGap.cameraZ);
|
|
this.cameraOrtho.updateProjectionMatrix();
|
|
this.controls.target.set(this.util.sceneGap.x, this.util.sceneGap.y, this.util.sceneGap.z);
|
|
}
|
|
let pathData = this.util.allMap[parseInt(this.util.deviceObj.build)].buildArr[parseInt(this.util.deviceObj.floor)].mapData.path;
|
|
pathData && pathData.nodes.sort(this.util.sortNode);
|
|
if (parseInt(this.util.deviceObj.node) != -1) {
|
|
if (pathData &&pathData.nodes.length > parseInt(this.util.deviceObj.node)) {
|
|
this.util.deviceObj.xaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].x;
|
|
this.util.deviceObj.yaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].y;
|
|
}
|
|
}
|
|
this.util.pathStateObj.facAllArr = [];
|
|
this.mapArr.length = 0;
|
|
this.util.pathStateObj.basePath = "{";
|
|
for (let bd = 0; bd < this.util.allMap.length; bd++) {
|
|
for (let i = 0; i < this.util.allMap[bd].buildArr.length; i++) {
|
|
this.convertPath(bd, i);
|
|
}
|
|
}
|
|
if (this.util.pathStateObj.basePath.length > 1) {
|
|
this.util.pathStateObj.basePath = this.util.pathStateObj.basePath.substr(0,this.util.pathStateObj.basePath.length - 1);
|
|
}
|
|
this.util.pathStateObj.basePath += "}";
|
|
let bjP = JSON.parse(this.util.pathStateObj.basePath);
|
|
if (this.util.options.otherPath) {
|
|
//如果多楼栋需要配置楼栋之间通行路径
|
|
for (let item of this.util.options.otherPath) {
|
|
bjP[item.f][item.s] = item.d;
|
|
bjP[item.s][item.f] = item.d;
|
|
}
|
|
}
|
|
//初始化基础路径;
|
|
let jcStr = JSON.stringify(bjP);
|
|
let graphPathObj = JSON.parse(jcStr);
|
|
let ftPathObj = JSON.parse(jcStr);
|
|
let dtPathObj = JSON.parse(jcStr);
|
|
let basePathObj = JSON.parse(jcStr);
|
|
try {
|
|
for (let j = 0; j < this.util.pathStateObj.facAllArr.length; j++) {
|
|
for (let k = 0; k < this.util.pathStateObj.facAllArr[j].length; k++) {
|
|
let facP =this.util.pathStateObj.facAllArr[j][k].buildOrder +"_" + this.util.pathStateObj.facAllArr[j][k].floorOrder +"_" +this.util.pathStateObj.facAllArr[j][k].navCode;
|
|
for (let h = 0; h < this.util.pathStateObj.facAllArr[j].length; h++) {
|
|
if (h != k && this.util.pathStateObj.facAllArr[j][k].buildOrder ==this.util.pathStateObj.facAllArr[j][h].buildOrder) {
|
|
let nP =this.util.pathStateObj.facAllArr[j][h].buildOrder +"_" +this.util.pathStateObj.facAllArr[j][h].floorOrder +"_" + this.util.pathStateObj.facAllArr[j][h].navCode;
|
|
if (this.util.pathStateObj.facAllArr[j][h].facCode == "dt") {
|
|
ftPathObj[facP][nP] =200000 +2000 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder)-parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
if (this.util.pathStateObj.seldtFacNo.type == "dt" &&this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.seldtFacNo.no) {
|
|
graphPathObj[facP][nP] =2000 +300 *Math.abs(parseInt( this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
} else {
|
|
graphPathObj[facP][nP] =5000 +600 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
}
|
|
dtPathObj[facP][nP] = 5000 +800 *Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder)-parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
basePathObj[facP][nP] = 600 +200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder ));
|
|
} else if (
|
|
this.util.pathStateObj.facAllArr[j][h].facCode == "td"
|
|
) {
|
|
graphPathObj[facP][nP] =4000 +800 * Math.abs( parseInt( this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
ftPathObj[facP][nP] = 4000 +800 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder ));
|
|
dtPathObj[facP][nP] = 4000 + 800 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
basePathObj[facP][nP] = 800 *Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt( this.util.pathStateObj.facAllArr[j][k].floorOrder ));
|
|
} else {
|
|
dtPathObj[facP][nP] =200000 +2000 * Math.abs(parseInt( this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder) );
|
|
if (this.util.pathStateObj.seldtFacNo.type == "ft" &&this.util.pathStateObj.seldtFacNo.no.search(this.util.pathStateObj.facAllArr[j][k].no + ",") != -1) {
|
|
graphPathObj[facP][nP] = 2000 + 300 *Math.abs( parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
} else {
|
|
graphPathObj[facP][nP] = 5000 +600 * Math.abs( parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder) );
|
|
}
|
|
ftPathObj[facP][nP] = 5000 + 800 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
basePathObj[facP][nP] = 100 + 400 *Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder)-parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log("交通设施点位问题: " + e);
|
|
}
|
|
|
|
this.util.pathStateObj.graphPath = graphPathObj;
|
|
this.util.pathStateObj.ftPath = ftPathObj;
|
|
this.util.pathStateObj.dtPath = dtPathObj;
|
|
this.util.pathStateObj.basePath = basePathObj;
|
|
var fIndex = 0, bIndex = 0;
|
|
this.mapArr[bIndex] = [];
|
|
intTimer = setInterval(() => {
|
|
if (!Map_QM.util.allMap[bIndex].buildArr[fIndex]) {
|
|
clearInterval(intTimer);
|
|
this.initFloor();
|
|
return;
|
|
}
|
|
let floor = new FloorMap_QM(bIndex, fIndex, Map_QM.util.allMap[bIndex].buildArr[fIndex].name );
|
|
floor.floorName = Map_QM.util.allMap[bIndex].buildArr[fIndex].name;
|
|
floor.initDraw();
|
|
floor.allObj.position.set(bIndex * Map_QM.util.options.bSpace, 0, 0);
|
|
if (fIndex != parseInt(Map_QM.util.deviceObj.floor)) {
|
|
floor.allObj.visible = false;
|
|
}
|
|
this.buildObj.add(floor.allObj);
|
|
this.mapArr[bIndex].push(floor);
|
|
fIndex++;
|
|
if (fIndex >= Map_QM.util.allMap[bIndex].buildArr.length) {
|
|
if (bIndex == Map_QM.util.allMap.length - 1) {
|
|
clearInterval(intTimer);
|
|
let pathData = Map_QM.util.allMap[parseInt(Map_QM.util.deviceObj.build)].buildArr[parseInt(Map_QM.util.deviceObj.floor)].mapData.path;
|
|
if (Map_QM.util.deviceObj.xaxis) {
|
|
Map_QM.mapArr[parseInt(Map_QM.util.deviceObj.build)][parseInt(Map_QM.util.deviceObj.floor)].setStartSite(Map_QM.util.deviceObj.xaxis,Map_QM.util.deviceObj.yaxis, parseInt(Map_QM.util.shopHeight) + 20);
|
|
} else {
|
|
if (parseInt(Map_QM.util.deviceObj.node) != -1) {
|
|
pathData && pathData.nodes.sort(Map_QM.util.sortNode);
|
|
if (pathData &&!Map_QM.util.deviceObj.xaxis && pathData.nodes.length > parseInt(Map_QM.util.deviceObj.node) && parseInt(Map_QM.util.deviceObj.node) >= 0) {
|
|
Map_QM.util.deviceObj.xaxis = pathData.nodes[parseInt(Map_QM.util.deviceObj.node)].x;
|
|
Map_QM.util.deviceObj.yaxis = pathData.nodes[parseInt(Map_QM.util.deviceObj.node)].y;
|
|
} else {
|
|
console.warn("初始化点位失败");
|
|
}
|
|
Map_QM.mapArr[parseInt(Map_QM.util.deviceObj.build)][parseInt(Map_QM.util.deviceObj.floor)].setStartSite(Map_QM.util.deviceObj.xaxis,Map_QM.util.deviceObj.yaxis,parseInt(Map_QM.util.shopHeight) + 20);
|
|
}
|
|
}
|
|
this.initFloor();
|
|
} else {
|
|
bIndex++;
|
|
fIndex = 0;
|
|
this.mapArr[bIndex] = [];
|
|
}
|
|
}
|
|
}, 0);
|
|
},
|
|
beforeDestroy: function () {
|
|
if (this.scene) {
|
|
this.controls && this.controls.dispose();
|
|
this.renderer.renderLists && this.renderer.renderLists.dispose();
|
|
this.renderer.dispose && this.renderer.dispose();
|
|
this.renderer.forceContextLoss();
|
|
let gl = this.renderer.domElement.getContext('webgl');
|
|
gl && gl.getExtension('WEBGL_lose_context').loseContext();
|
|
this.util.pathStateObj.basePath = null;
|
|
this.ele.removeEventListener("touchmove", this.mouseMove);
|
|
this.ele.removeEventListener("click", this.onMouseClickBox); //地图点击
|
|
this.ele.removeEventListener("touchend", this.mouseUp);
|
|
this.controls.removeEventListener("change", this.controlsChock);
|
|
document.removeEventListener("resize", this.changeDocmentResize); //窗口变化
|
|
this.remove_child(this.sceneGap);
|
|
this.scene.remove(this.sceneGap);
|
|
while (this.ele.firstChild) {
|
|
this.ele.firstChild.remove();
|
|
}
|
|
this.renderer.domElement = null;
|
|
this.renderer.content = null;
|
|
this.renderer = null;
|
|
this.scene.clear();
|
|
this.scene = null;
|
|
this.camera = null;
|
|
this.controls = null;
|
|
this.util.spriteMaterialArr = [];
|
|
this.util.lineBasicMaterialArr = [];
|
|
this.util.meshMaterialArr = [];
|
|
this.util.parkMaterialArr = [];
|
|
this.util.shopData = []; //店铺数据
|
|
this.util.iconUrl = [];
|
|
this.util.allMap = [];
|
|
this.util = null;
|
|
Map_QM = null;
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} changeLanguage() 切换中英文
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 切换中英文 zh en
|
|
* @apiVersion 1.0.0
|
|
* @apiParam {String} str 显示语言
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.changeLanguage("en");
|
|
*
|
|
*/
|
|
changeLanguage: function (lang = "zh") {
|
|
language = lang;
|
|
for (let t = 0; t < Map_QM.mapArr.length; t++) {
|
|
for (let i = 0; i < Map_QM.mapArr[t].length; i++) {
|
|
Map_QM.mapArr[t][i].labelObj.traverse((obj) => {
|
|
if (obj.element) {
|
|
obj.element.innerText = lang == "en"? obj.element.dataset.nameEn : obj.element.dataset.name;
|
|
}
|
|
});
|
|
Map_QM.mapArr[t][i].showTagObj.traverse((obj) => {
|
|
if (obj.element) {
|
|
obj.element.style.opacity = obj.userData.show != lang ? 0 : 1;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
Map_QM.outObject.traverse((obj) => {
|
|
if (obj.element && mapState == "out") {
|
|
obj.element.style.visibility = obj.userData.show == lang ? "visible" : "hidden";
|
|
}
|
|
});
|
|
Map_QM.perObject.traverse((obj) => {
|
|
if (obj.element && mapState == "periphery") {
|
|
obj.element.style.visibility = obj.userData.show == lang ? "visible" : "hidden";
|
|
}
|
|
});
|
|
Map_QM.controlsChock();
|
|
},
|
|
initTreeModel: function () {
|
|
if (this.index < this.util.modelStr.length - 1) {
|
|
if (this.util.modelStr[this.index].load) {
|
|
this.gltfLoad(this.util.beforPath + this.util.modelStr[this.index].url);
|
|
} else {
|
|
this.index++;
|
|
this.initTreeModel();
|
|
}
|
|
} else {
|
|
if (this.util.allMap && this.util.allMap.length > 0) {
|
|
this.loaderOver();
|
|
}
|
|
}
|
|
},
|
|
gltfLoad: function (url) {
|
|
let sopce = this;
|
|
new THREE.GLTFLoader().load(url, function (object) {
|
|
//加载路径fbx文件
|
|
object.scene.traverse(function (child) {
|
|
if (child.type === "Mesh") {
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
if (sopce.util.modelStr[sopce.index].colorModel === "gama") {
|
|
child.material.color.convertGammaToLinear(0.6);
|
|
}
|
|
}
|
|
});
|
|
object.scene.children[0].scale.set(
|
|
sopce.util.modelStr[sopce.index].size.x,
|
|
sopce.util.modelStr[sopce.index].size.y,
|
|
sopce.util.modelStr[sopce.index].size.z
|
|
);
|
|
sopce.util.fbxModels.push({key: sopce.util.modelStr[sopce.index].key,obj: object, operation: sopce.util.modelStr[sopce.index],});
|
|
if (sopce.index < sopce.util.modelStr.length - 1) {
|
|
sopce.index++;
|
|
sopce.initTreeModel();
|
|
} else {
|
|
if (sopce.util.allMap && sopce.util.allMap.length > 0) {
|
|
sopce.loaderOver();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
initGuide: function () {
|
|
let _this = this;
|
|
new THREE.GLTFLoader().load(
|
|
this.util.beforPath + "static/img/runman.gltf",
|
|
function (obj) {
|
|
obj.scene.scale.x = obj.scene.scale.y =obj.scene.scale.z = _this.util.options.facSize || 20;
|
|
obj.scene.children[0].children[1].children[0].material.color = new THREE.Color(0xfe9219);
|
|
_this.sceneGap.add(obj.scene);
|
|
obj.scene.traverse(function (child) {
|
|
if (child.type === "SkinnedMesh") {
|
|
child.material.map && (child.material.map.encoding = THREE.LinearEncoding); //贴图需要转换成 线性编码
|
|
}
|
|
});
|
|
obj.scene.visible = false;
|
|
obj.scene.children[0].rotation.x = Math.PI / 2;
|
|
obj.scene.children[0].rotation.y = Math.PI;
|
|
// obj作为参数创建一个混合器,解析播放obj及其子对象包含的动画数据
|
|
let mixer = new THREE.AnimationMixer(obj.scene);
|
|
let AnimationAction = mixer.clipAction(obj.animations[0]);
|
|
AnimationAction.timeScale = 2;
|
|
AnimationAction.play();
|
|
_this.mixers.push(mixer);
|
|
_this.man_3d = obj.scene;
|
|
_this.guide = _this.man_3d;
|
|
}
|
|
);
|
|
|
|
new THREE.GLTFLoader().load(
|
|
this.util.beforPath + "static/img/guide.glb",
|
|
function (obj) {
|
|
obj.scene.scale.x =obj.scene.scale.y = obj.scene.scale.z = _this.util.options.facSize * 5 || 100;
|
|
obj.scene.visible = false;
|
|
obj.scene.children[0].rotation.x = Math.PI / 2;
|
|
obj.scene.traverse(function (child) {
|
|
if (child.type === "Mesh") {
|
|
child.userData.opacity = child.material.opacity;
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
}
|
|
});
|
|
for (let k = 0; k < obj.animations.length; k++) {
|
|
let mixer = new THREE.AnimationMixer(obj.scene);
|
|
mixer.clipAction(obj.animations[k]).play();
|
|
_this.mixers.push(mixer);
|
|
}
|
|
_this.man_2d = obj.scene;
|
|
_this.man_2d.renderOrder = 160;
|
|
_this.sceneGap.add(_this.man_2d);
|
|
}
|
|
);
|
|
},
|
|
initFloor: function () {
|
|
this.controls.saveState();
|
|
this.changeBuild(this.util.deviceObj.build, this.util.deviceObj.floor);
|
|
//初始化方向为第一人称方向
|
|
this.util.options.deviceAng && this.rotationAngle(this.util.deviceObj.angle);
|
|
this.startRender();
|
|
|
|
setTimeout(() => {
|
|
Map_QM.controls.addEventListener("change", Map_QM.controlsChock); //控制器变化
|
|
Map_QM.util.fbxModels = [];
|
|
let boundBox = new THREE.Box3();
|
|
boundBox.setFromObject(Map_QM.sceneGap);
|
|
if (isNaN(boundBox.min.x) || isNaN(boundBox.min.y)) {
|
|
Map_QM.controls.minPan = new THREE.Vector3(Map_QM.w / -8,0,Map_QM.h / -8);
|
|
Map_QM.controls.maxPan = new THREE.Vector3(Map_QM.w / 8, 0,Map_QM.h / 8);
|
|
} else {
|
|
boundBox.min.x < -400 && (boundBox.min.x = boundBox.min.z);
|
|
boundBox.max.x > 400 && (boundBox.max.x = boundBox.max.z);
|
|
boundBox.min.z < -400 && (boundBox.min.z = boundBox.min.x);
|
|
boundBox.max.z > 400 && (boundBox.max.z = boundBox.max.x);
|
|
Map_QM.controls.minPan = boundBox.min;
|
|
Map_QM.controls.maxPan = boundBox.max;
|
|
}
|
|
console.log("Number of Triangles :", Map_QM.renderer.info.render.triangles);
|
|
if (Map_QM.util.initModelArr.length > 0) {
|
|
Map_QM.toOutModel();
|
|
setTimeout(() => {
|
|
Map_QM.toOutModelInner();
|
|
}, 1000);
|
|
}
|
|
}, 200);
|
|
},
|
|
calcFov: function (d, w, r) {
|
|
let f;
|
|
let vertical = w;
|
|
if (r < 1) {
|
|
vertical = vertical / r;
|
|
}
|
|
f = Math.atan(vertical / d / 2) * 2 * (180 / Math.PI);
|
|
return f;
|
|
},
|
|
/**
|
|
* 解析路径
|
|
*/
|
|
convertPath: function (buildOrder, floorOrder) {
|
|
let mapDataA = this.util.allMap[buildOrder].buildArr[floorOrder].mapData;
|
|
let pathData = mapDataA.path;
|
|
if (!pathData) {
|
|
return;
|
|
}
|
|
if (pathData.nodes.length > 0) {
|
|
pathData.nodes.sort(this.util.sortNode);
|
|
for (let i = 0; i < pathData.nodes.length; i++) {
|
|
let a = pathData.nodes[i].id;
|
|
this.util.pathStateObj.basePath += '"' + buildOrder + "_" + floorOrder + "_" + a + '":{';
|
|
for (let n = 0; n < pathData.nodes[i]["list"].length; n++) {
|
|
let b;
|
|
if (pathData.nodes[i]["list"][n].id ||pathData.nodes[i]["list"][n].id == "0") {
|
|
b = pathData.nodes[i]["list"][n].id;
|
|
} else {
|
|
b = a == pathData.nodes[i]["list"][n].selfNode.id ? pathData.nodes[i]["list"][n].nextNode.id : pathData.nodes[i]["list"][n].selfNode.id;
|
|
}
|
|
this.util.pathStateObj.basePath +='"'+buildOrder+"_" +floorOrder +"_" +b +'":'+pathData.nodes[i]["list"][n].cost +",";
|
|
}
|
|
if (pathData.nodes[i]["list"].length > 0) {
|
|
this.util.pathStateObj.basePath = this.util.pathStateObj.basePath.substr(0,this.util.pathStateObj.basePath.length - 1);
|
|
}
|
|
this.util.pathStateObj.basePath += "},";
|
|
}
|
|
}
|
|
let mindt = 10000, minupft = -1, mindownft = -1, seldtNo, seldownftNo, selupftNo;
|
|
|
|
if (buildOrder == this.util.deviceObj.build &&floorOrder == this.util.deviceObj.floor &&parseInt(this.util.deviceObj.node) >= 0) {
|
|
if (pathData &&!this.util.deviceObj.xaxis &&pathData.nodes.length > parseInt(this.util.deviceObj.node) && parseInt(this.util.deviceObj.node) > 0 ) {
|
|
this.util.deviceObj.xaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].x;
|
|
this.util.deviceObj.yaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].y;
|
|
}
|
|
//获取本楼层最近的电梯
|
|
for (let n = 0; n < mapDataA.stairs.length; n++) {
|
|
if ( mapDataA.stairs[n].state && mapDataA.stairs[n].no != "" && parseInt(mapDataA.stairs[n].navCode) > 0 ) {
|
|
let ms = Math.abs( parseInt(mapDataA.stairs[n].x) - parseInt(this.util.deviceObj.xaxis) ) + Math.abs( parseInt(mapDataA.stairs[n].y) - parseInt(this.util.deviceObj.yaxis) );
|
|
if ( mindt > ms && (mapDataA.stairs[n].facCode == "ft" ||
|
|
mapDataA.stairs[n].facCode == "upft" ||
|
|
mapDataA.stairs[n].facCode == "downft" ||
|
|
mapDataA.stairs[n].facCode == "dt")
|
|
) {
|
|
mindt = ms;
|
|
let fac = mapDataA.stairs[n].facCode == "dt" ? "dt" : "ft";
|
|
this.util.pathStateObj.seldtFacNo.type = fac;
|
|
if (mapDataA.stairs[n].facCode == "dt") {
|
|
seldtNo = mapDataA.stairs[n].no;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.util.pathStateObj.seldtFacNo.type == "dt") {
|
|
this.util.pathStateObj.seldtFacNo.no = seldtNo;
|
|
} else {
|
|
for (let t = 0; t < this.util.allMap[buildOrder].buildArr.length; t++) {
|
|
let mapData = this.util.allMap[buildOrder].buildArr[t].mapData;
|
|
minupft = 100000;
|
|
mindownft = 100000;
|
|
selupftNo = "";
|
|
seldownftNo = "";
|
|
for (let h = 0; h < mapData.stairs.length; h++) {
|
|
if (mapData.stairs[h].state && mapData.stairs[h].no != "" && parseInt(mapData.stairs[h].navCode) > 0) {
|
|
let ms = Math.abs(parseInt(mapData.stairs[h].x) - parseInt(this.util.deviceObj.xaxis)) +
|
|
Math.abs(parseInt(mapData.stairs[h].y) - parseInt(this.util.deviceObj.yaxis));
|
|
if (mapData.stairs[h].facCode == "upft" || mapData.stairs[h].downState) {
|
|
//上扶
|
|
if (minupft > ms) {
|
|
minupft = ms;
|
|
selupftNo = mapData.stairs[h].no;
|
|
}
|
|
} else if (mapData.stairs[h].facCode == "downft" || mapData.stairs[h].upState) {
|
|
if (mindownft > ms) {
|
|
mindownft = ms;
|
|
seldownftNo = mapData.stairs[h].no;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//扶梯距离最小
|
|
selupftNo != "" && (this.util.pathStateObj.seldtFacNo.no += selupftNo + ",");
|
|
seldownftNo != "" && (this.util.pathStateObj.seldtFacNo.no += seldownftNo + ",");
|
|
}
|
|
}
|
|
//console.log(this.util.pathStateObj.seldtFacNo);
|
|
}
|
|
|
|
let noHas;
|
|
for (let j = 0; j < mapDataA.stairs.length; j++) {
|
|
if ( parseInt(mapDataA.stairs[j].navCode) > 0 && mapDataA.stairs[j].state) {
|
|
//排除禁用的设施
|
|
noHas = true;
|
|
for (let k = 0; k < this.util.pathStateObj.facAllArr.length; k++) {
|
|
//Map_QM.util.pathStateObj.facAllArr 记录遍历结果
|
|
if (this.util.pathStateObj.facAllArr[k][0].no != "" &&
|
|
this.util.pathStateObj.facAllArr[k][0].navCode != "" &&
|
|
parseInt(this.util.pathStateObj.facAllArr[k][0].navCode) > 0 &&
|
|
this.util.pathStateObj.facAllArr[k][0].no == mapDataA.stairs[j].no
|
|
) {
|
|
if (this.util.pathStateObj.facAllArr[k][0].facCode == mapDataA.stairs[j].facCode ||
|
|
(this.util.pathStateObj.facAllArr[k][0].facCode.search("ft") != -1 && mapDataA.stairs[j].facCode.search("ft") != -1)
|
|
) {
|
|
noHas = false;
|
|
mapDataA.stairs[j].floorOrder = floorOrder;
|
|
mapDataA.stairs[j].buildOrder = buildOrder;
|
|
this.util.pathStateObj.facAllArr[k].push(mapDataA.stairs[j]);
|
|
}
|
|
}
|
|
}
|
|
if (noHas) {
|
|
mapDataA.stairs[j].buildOrder = buildOrder;
|
|
mapDataA.stairs[j].floorOrder = floorOrder;
|
|
let array = [mapDataA.stairs[j]];
|
|
this.util.pathStateObj.facAllArr.push(array);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} changeMapState("3d") 地图状态切换
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 地图展示状态切换
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {string} state 地图状态
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.changeMapState("2d");
|
|
*
|
|
*/
|
|
changeMapState: function (state) {
|
|
Map_QM.controls.reset();
|
|
Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
|
|
if (state === "3d") {
|
|
Map_QM.camera = Map_QM.cameraPerspective;
|
|
Map_QM.controls.object = Map_QM.camera;
|
|
Map_QM.shawLight.castShadow = Map_QM.util.options.shadow;
|
|
Map_QM.controls.maxPolarAngle = Math.PI / 2 - 0.2;
|
|
Map_QM.controls.setZoom(1);
|
|
Map_QM.changeIconState(state);
|
|
} else {
|
|
Map_QM.camera = Map_QM.cameraOrtho;
|
|
Map_QM.controls.object = Map_QM.camera;
|
|
Map_QM.shawLight.castShadow = false;
|
|
Map_QM.controls.setZoom(Map_QM.util.m_zoom);
|
|
Map_QM.controls.maxPolarAngle = 0;
|
|
Map_QM.changeIconState(state);
|
|
}
|
|
},
|
|
|
|
changeIconState: function (state, fIndex = -1) {
|
|
iconState = state;
|
|
fIndex = fIndex === -1 ? Map_QM.util.selectFloor : fIndex;
|
|
try{
|
|
if(!Map_QM.mapArr || !Map_QM.mapArr[Map_QM.util.selectBuild]) {
|
|
return
|
|
}
|
|
for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) {
|
|
if (i == fIndex && Map_QM.buildObj.visible) {
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][i].serObj.traverse((obj) => {
|
|
if (obj.userData && obj.userData.use) {
|
|
if (obj.userData.use != "all" && obj.userData.use != state) {
|
|
obj.visible = false;
|
|
obj.element && (obj.element.style.display = "none");
|
|
} else {
|
|
obj.visible = true;
|
|
obj.element && (obj.element.style.display = "");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}catch(e){
|
|
window.captureException && window.captureException(e);
|
|
}
|
|
if (Map_QM.qiModel) {
|
|
Map_QM.qiModel.visible = state == "3d" ? true : false;
|
|
}
|
|
if (Map_QM.devModel) {
|
|
Map_QM.devModel.visible = state == "2d" && !Map_QM.util.pathStateObj.isPathState ? true : false;
|
|
}
|
|
if (Map_QM.qiIcon) {
|
|
Map_QM.qiIcon.visible = state == "2d" && Map_QM.util.pathStateObj.isPathState ? true : false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} changeBuild(buildOrder,floorOrder) 楼栋切换
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 楼栋切换 传入楼栋编号,楼层编号
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {int} buildOrder 传入楼栋编号(默认 0)
|
|
* @apiParam {int} floorOrder 传入楼栋编号(默认 0)
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {int, int} 请求示例
|
|
*
|
|
* Map_QM.changeBuild(0, 0);
|
|
*
|
|
*/
|
|
changeBuild: function (buildOrder = 0, floorOrder = 0) {
|
|
Map_QM.changeMapModel("3D");
|
|
Map_QM.resetFloorState();
|
|
Map_QM.controls.reset();
|
|
Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
|
|
Map_QM.clearFloor(Map_QM.util.selectFloor);
|
|
this.changeBuildInner(buildOrder, floorOrder);
|
|
},
|
|
|
|
changeBuildInner: function (build = -1, fIndex = -1) {
|
|
fIndex = fIndex == -1 ? parseInt(Map_QM.util.deviceObj.floor) : fIndex;
|
|
build = build == -1 ? parseInt(Map_QM.util.deviceObj.build) : build;
|
|
Map_QM.util.selectBuild = build;
|
|
Map_QM.buildObj.position.x = -1 * build * Map_QM.util.options.bSpace;
|
|
Map_QM.changeFloorInner(build, fIndex); //结束后切换楼层
|
|
renderCount = 0;
|
|
},
|
|
|
|
resetFloorState: function () {
|
|
TweenMax.killAll(true);
|
|
Map_QM.util.pathStateObj.isPathState = false;
|
|
Map_QM.controls.maxDistance = Map_QM.util.options.maxDis;
|
|
clearTimeout(Map_QM.util.timeObj.collTime);
|
|
Map_QM.controls.enabled = true;
|
|
Map_QM.controls.enableRotate = true;
|
|
Map_QM.controls.minAzimuthAngle = -Infinity;
|
|
Map_QM.controls.maxAzimuthAngle = Infinity;
|
|
Map_QM.util.pathStateObj.forShopArr = { direction: "", wayList: [] };
|
|
if (Map_QM.guide && Map_QM.guide.visible) {
|
|
Map_QM.guide.visible = false;
|
|
}
|
|
if (Map_QM.endModel && Map_QM.endModel.visible) {
|
|
Map_QM.endModel.visible = false;
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} showFloor(floorOrder) 通过楼层编号切换楼层
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 楼层切换,传入楼层编号,编号从下到上排序,最下面是0
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {int} floorOrder 楼层编号
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {int} 请求示例
|
|
*
|
|
* Map_QM.showFloor(1);
|
|
*
|
|
*/
|
|
showFloor: function (fIndex = -1, callBack = undefined) {
|
|
if (!Map_QM.buildObj.visible) {
|
|
return;
|
|
}
|
|
Map_QM.util.isMorePath = false;
|
|
Map_QM.util.pathStateObj.isPathState = false;
|
|
// Map_QM.changeStartPoint();
|
|
isShowElement = true;
|
|
allJU = true;
|
|
Map_QM.changeMapModel("3D");
|
|
Map_QM.resetFloorState();
|
|
Map_QM.controls.reset();
|
|
if (Map_QM.util.initModelArr.length > 0) {
|
|
Map_QM.controls.setDistance(Map_QM.util.changeDist.inner - 25);
|
|
Map_QM.controls.update();
|
|
}
|
|
Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
|
|
Map_QM.clearFloor(fIndex);
|
|
Map_QM.elementDestroy("all");
|
|
Map_QM.elementDestroy("go", true);
|
|
if (fIndex != -1) {
|
|
Map_QM.changeFloorInner(-1, fIndex, callBack);
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} bindingShop(mesh,shop,isBinding) 绑定或解绑店铺
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 给3D对象绑定数据
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {Object3D} mesh 3D对象
|
|
* @apiParam {Object} shop 要绑定的数据对象(houseNumber是必需属性)。解绑可以不传
|
|
* @apiParam {Boolean} isBinding 默认true。 true是绑定,false是解绑
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.bindingShop(mesh, {shopName:"shop",houseNumber:"L101",color:"", ...},true);
|
|
*/
|
|
bindingShop: function (mesh, shop, isBinding = true) {
|
|
if (!isBinding || (shop && shop.houseNumber)) {
|
|
for (let i = 0; i < Map_QM.util.allMap.length; i) {
|
|
for (let j = 0; j < Map_QM.util.allMap[i].buildArr.length; j++) {
|
|
let shopArea = Map_QM.util.allMap[i].buildArr[j].mapData.shopArea;
|
|
for (let k = 0; k < shopArea.length; k++) {
|
|
if (shopArea[k].id === mesh.userData.id) {
|
|
if (isBinding) {
|
|
shopArea[k].name = shop.houseNumber; //修改地图原始数据的box名称
|
|
mesh.userData.shopData = shop;
|
|
mesh.name = shop.houseNumber;
|
|
if (shop.color) {
|
|
// 替换材质
|
|
mesh.userData.initMaterial = mesh.material;
|
|
let meshMat = new THREE.MeshPhongMaterial({
|
|
color: shop.color,
|
|
transparent: true,
|
|
opacity: mesh.material.opacity,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
Map_QM.util.meshMaterialArr.push(meshMat);
|
|
mesh.material = meshMat;
|
|
}
|
|
//添加名称标签
|
|
let shopLabel = Map_QM.util.addMapLabel(
|
|
shop.shopName,
|
|
shop.shopName,
|
|
shop.houseNumber
|
|
);
|
|
shopLabel.position.set(
|
|
mesh.xaxis >> 0,
|
|
(-1 * mesh.yaxis) >> 0,
|
|
mesh.zaxis
|
|
);
|
|
Map_QM.mapArr[mesh.userData.build][mesh.userData.floor].labelObj.add(shopLabel);
|
|
Map_QM.updateRender();
|
|
Map_QM.collLabel();
|
|
} else {
|
|
shopArea[k].name = "shop";
|
|
mesh.userData.shopData = {};
|
|
if (mesh.userData.initMaterial) {
|
|
mesh.material = mesh.userData.initMaterial;
|
|
}
|
|
//删除文本标签
|
|
let labObj = Map_QM.mapArr[mesh.userData.build][mesh.userData.floor].labelObj.children;
|
|
for (let j = 0; j < labObj.length; j++) {
|
|
if (labObj[j].name == mesh.name) {
|
|
if (labObj[j].element.parentNode !== null) {
|
|
labObj[j].element.parentNode.removeChild(labObj[j].element);
|
|
}
|
|
Map_QM.mapArr[mesh.userData.build][mesh.userData.floor].labelObj.remove(labObj[j]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} getAllIcon() 获取所有Icon
|
|
* @apiGroup 地图数据
|
|
* @apiDescription 获取所有Icon
|
|
* @apiVersion 2.0.0
|
|
* @apiParam {int} floorOrder 楼层编号(默认 所有)
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
*/
|
|
getAllIcon: function (floorOrder = -1, buildOrder = -1) {
|
|
let icons = []
|
|
if (floorOrder != -1) {
|
|
let bd = buildOrder == -1 ? Map_QM.util.selectBuild : buildOrder
|
|
let sers = Map_QM.mapArr[bd][floorOrder].serObj.children //服务图标
|
|
for (let n = 0; n < sers.length; n++) {
|
|
if (sers[n].type == 'Object3D') {
|
|
let title = sers[n].userData.title || Map_QM.util.getFacName(sers[n].facCode)
|
|
let titleEn = sers[n].userData.titleEn || title;
|
|
let type = sers[n].userData.facCode;
|
|
let imgUrl = sers[n].userData.src;
|
|
if (sers[n].facCode == 'upft' || sers[n].facCode == 'downft' || sers[n].facCode == 'ft') {
|
|
if (title == '上扶梯' || title == '下扶梯') {
|
|
title = '扶梯'
|
|
}
|
|
type = 'ft'
|
|
}
|
|
let icon = { type: type, floor: floorOrder, imgUrl: imgUrl, title: title, titleEn: titleEn }
|
|
icons.push(icon)
|
|
}
|
|
}
|
|
return icons
|
|
}
|
|
|
|
for (let j = 0; j < Map_QM.mapArr.length; j++) {
|
|
let iconBuild = []
|
|
for (let i = 0; i < Map_QM.mapArr[j].length; i++) {
|
|
let iconArr = []
|
|
if (Map_QM.mapArr[j][i].serObj) {
|
|
let sers = Map_QM.mapArr[j][i].serObj.children //服务图标
|
|
for (let n = 0; n < sers.length; n++) {
|
|
if (sers[n].type == 'Object3D') {
|
|
let title = sers[n].userData.title || Map_QM.util.getFacName(sers[n].facCode)
|
|
let titleEn = sers[n].userData.titleEn || title;
|
|
let type = sers[n].userData.facCode;
|
|
let imgUrl = sers[n].userData.src;
|
|
if (sers[n].facCode == 'upft' || sers[n].facCode == 'downft' || sers[n].facCode == 'ft') {
|
|
title = '扶梯'
|
|
type = 'ft'
|
|
}
|
|
let icon = { type: type, floor: i, imgUrl: imgUrl, title: title, titleEn: titleEn }
|
|
iconArr.push(icon)
|
|
}
|
|
}
|
|
}
|
|
iconBuild.push(iconArr)
|
|
}
|
|
icons.push(iconBuild)
|
|
}
|
|
return icons
|
|
},
|
|
/**
|
|
* @api {方法} queryAllMapData() 获取地图原始数据
|
|
* @apiGroup 地图数据
|
|
* @apiDescription 获取地图接口数据
|
|
* @apiVersion 4.0.1
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.queryAllMapData();
|
|
*/
|
|
queryAllMapData: function () {
|
|
return JSON.stringify({
|
|
mallCode: Map_QM.util.mallCode,
|
|
MapInfo: Map_QM.util.allMap,
|
|
key: "Aeditor",
|
|
});
|
|
},
|
|
/**
|
|
* @api {方法} changeFloorByName(floorOrder) 通过楼层名称切换楼层
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 楼层切换,传入楼层名称,
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {String} floorName 楼层名称
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.changeFloorByName("L1");
|
|
*/
|
|
changeFloorByName: function (floorName) {
|
|
let floors = Map_QM.mapArr[Map_QM.util.selectBuild];
|
|
for (let i = 0; i < floors.length; i++) {
|
|
if (floors[i].floorName == floorName) {
|
|
Map_QM.showFloor(floors[i].floorOrder);
|
|
return;
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} changeFloorByCode(floorCode) 通过楼层code切换楼层
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 楼层切换,传入楼层code,
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {String} floorCode 楼层code
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.changeFloorByCode("Ek_MaiuKLPjakB1uB0uQV");
|
|
*/
|
|
changeFloorByCode: function (floorCode) {
|
|
for (let kk = 0; kk < Map_QM.util.allMap.length; kk++) {
|
|
for (var iii = 0; iii < Map_QM.util.allMap[kk].buildArr.length; iii++) {
|
|
if (Map_QM.util.allMap[kk].buildArr[iii].code == floorCode) {
|
|
Map_QM.changeBuild(kk, iii);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
changeFloorInner: function (build = -1,fIndex = -1,callBack = undefined) {
|
|
fIndex = fIndex != -1 ? fIndex : Map_QM.util.deviceObj.floor;
|
|
build = build != -1 ? build : Map_QM.util.deviceObj.build;
|
|
for (let t = 0; t < Map_QM.mapArr.length; t++) {
|
|
for (let i = 0; i < Map_QM.mapArr[t].length; i++) {
|
|
Map_QM.mapArr[t][i].allObj.visible = t == build ? true : false;
|
|
Map_QM.mapArr[t][i].CSSObj.traverse((obj) => {
|
|
obj.element && (obj.element.style.display = "none");
|
|
});
|
|
}
|
|
}
|
|
if (Map_QM.mapArr[build] && Map_QM.mapArr[build][fIndex]) {
|
|
Map_QM.mapArr[build][fIndex].allObj.visible = true;
|
|
} else {
|
|
return;
|
|
}
|
|
for (let i = 0; i < Map_QM.mapArr[build].length; i++) {
|
|
if (i == fIndex) {
|
|
Map_QM.mapArr[build][i].allObj.visible = true;
|
|
Map_QM.mapArr[build][i].CSSObj.traverse((obj) => {
|
|
obj.element && obj.userData.isShow && obj.userData.type == "icon" && (obj.element.style.display = "");
|
|
});
|
|
Map_QM.changeIconState(iconState, fIndex);
|
|
} else {
|
|
Map_QM.mapArr[build][i].allObj.visible = false;
|
|
}
|
|
if (i == Map_QM.mapArr[build].length - 1) {
|
|
if (build == Map_QM.util.selectBuild && fIndex == Map_QM.util.selectFloor ) {
|
|
if (callBack) callBack();
|
|
Map_QM.timeOutInit();
|
|
} else {
|
|
Map_QM.util.selectBuild = build;
|
|
Map_QM.util.selectFloor = fIndex;
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.z = 0;
|
|
Map_QM.timeOutInit();
|
|
if (callBack) callBack();
|
|
}
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} onShowMeDir() 我的方向
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 我的方向
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.onShowMeDir();
|
|
*
|
|
*/
|
|
onShowMeDir: function () {
|
|
if (this.util.selectBuild != this.util.deviceObj.build || this.util.selectFloor != this.util.deviceObj.floor) {
|
|
this.changeFloorInner(this.util.deviceObj.build, this.util.deviceObj.floor);
|
|
}
|
|
this.onInnerMeDir();
|
|
},
|
|
onInnerMeDir: function () {
|
|
TweenMax.killAll(true);
|
|
this.changeMapModel("2D");
|
|
Map_QM.controls.reset();
|
|
clearTimeout(shopTime);
|
|
isJUZ = false;
|
|
Map_QM.controls.minPolarAngle = 0;
|
|
if (Map_QM.util.deviceObj.xaxis || Map_QM.util.deviceObj.yaxis) {
|
|
Map_QM.mapToPoint(Map_QM.util.deviceObj.xaxis, Map_QM.util.deviceObj.yaxis, 0 );
|
|
} else {
|
|
Map_QM.mapToPoint(0, 0, 0);
|
|
}
|
|
Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
|
|
Map_QM.controls.enableRotate = false;
|
|
Map_QM.controls.setDistance(150); //放大
|
|
Map_QM.updateRender();
|
|
Map_QM.collLabel();
|
|
},
|
|
changeMapModel: function (model) {
|
|
if (model == '2D') {
|
|
Map_QM.changeIconState("2d");
|
|
Map_QM.controls.maxPolarAngle = 0
|
|
Map_QM.camera = Map_QM.cameraOrtho
|
|
Map_QM.controls.object = Map_QM.camera
|
|
Map_QM.camera.updateProjectionMatrix()
|
|
Map_QM.shawLight.castShadow = false;
|
|
} else {
|
|
Map_QM.changeIconState("3d");
|
|
Map_QM.camera = Map_QM.cameraPerspective
|
|
Map_QM.controls.object = Map_QM.camera
|
|
Map_QM.controls.maxPolarAngle = Math.PI / 2 - 0.02
|
|
Map_QM.camera.updateProjectionMatrix()
|
|
Map_QM.shawLight.castShadow = Map_QM.util.options.shadow;
|
|
}
|
|
Map_QM.updateRender();
|
|
},
|
|
|
|
/**
|
|
* @api {方法} toOutModel() 显示外立面模型
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 显示外立面模型
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.toOutModel();
|
|
*/
|
|
toOutModel: function () {
|
|
TweenMax.killAll(true);
|
|
Map_QM.controls.setDistance(Map_QM.util.changeDist.inner + 25);
|
|
Map_QM.controls.update();
|
|
Map_QM.disPlayEvent();
|
|
renderCount = 0;
|
|
Map_QM.resetModel();
|
|
},
|
|
toOutModelInner: function () {
|
|
TweenMax.killAll(true);
|
|
Map_QM.emitChangeMap("out");
|
|
Map_QM.hideFloor();
|
|
Map_QM.buildObj.visible = false;
|
|
TweenMax.to(Map_QM.peripheryGap.scale, 0.3, {
|
|
y: 0.01,
|
|
ease: Quad.easeIn,
|
|
onComplete: function () {
|
|
Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏外立面
|
|
Map_QM.hideObjecrGap(Map_QM.perObject, false);
|
|
},
|
|
});
|
|
if (!Map_QM.outModelGap.visible) {
|
|
Map_QM.hideObjecrGap(Map_QM.outModelGap, true);
|
|
Map_QM.hideObjecrGap(Map_QM.outObject, true);
|
|
TweenMax.to(Map_QM.outModelGap.scale, 0.6, {
|
|
y: 1,
|
|
ease: Quad.easeIn,
|
|
onComplete: function () { },
|
|
});
|
|
} else {
|
|
mapState = "out";
|
|
}
|
|
Map_QM.rotateAngle(70);
|
|
startRotate = true;
|
|
},
|
|
hideFloor: function () {
|
|
Map_QM.changeMapModel("3D");
|
|
Map_QM.resetFloorState();
|
|
Map_QM.clearFloor();
|
|
Map_QM.hideInnerFloorElement();
|
|
},
|
|
/**
|
|
* @api {方法} toPeriphery() 显示周边模型
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 显示周边模型
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.toPeriphery();
|
|
*/
|
|
toPeriphery: function () {
|
|
TweenMax.killAll(true);
|
|
Map_QM.controls.setDistance(Map_QM.util.changeDist.outner + 25);
|
|
Map_QM.controls.update();
|
|
Map_QM.disPlayEvent();
|
|
renderCount = 0;
|
|
},
|
|
|
|
toPeripheryInner: function () {
|
|
TweenMax.killAll(true);
|
|
Map_QM.emitChangeMap("periphery");
|
|
startRotate = false;
|
|
Map_QM.outModelGap.rotateY(-1 * Map_QM.outModelGap.rotation.y);
|
|
Map_QM.hideFloor();
|
|
TweenMax.to(Map_QM.outModelGap.scale, 0.3, {
|
|
y: 0.01,
|
|
ease: Quad.easeIn,
|
|
onComplete: function () {
|
|
Map_QM.buildObj.visible = false;
|
|
Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面
|
|
Map_QM.hideObjecrGap(Map_QM.outObject, false);
|
|
},
|
|
});
|
|
if (!Map_QM.peripheryGap.visible) {
|
|
Map_QM.hideObjecrGap(Map_QM.peripheryGap, true);
|
|
TweenMax.to(Map_QM.peripheryGap.scale, 0.6, {
|
|
y: 1,
|
|
ease: Quad.easeIn,
|
|
onComplete: function () {
|
|
Map_QM.changePerTag("mark");
|
|
},
|
|
});
|
|
} else {
|
|
mapState = "periphery";
|
|
}
|
|
Map_QM.rotateAngle(45);
|
|
},
|
|
/**
|
|
* @api {方法} hideInnerFloorElement() 隐藏室内楼层元素
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 隐藏室内楼层元素
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.hideInnerFloorElement();
|
|
*/
|
|
hideInnerFloorElement: function () {
|
|
isShowElement = false;
|
|
for (let t = 0; t < Map_QM.mapArr.length; t++) {
|
|
for (let i = 0; i < Map_QM.mapArr[t].length; i++) {
|
|
Map_QM.mapArr[t][i].CSSObj.traverse((obj) => {
|
|
obj.element && (obj.element.style.display = "none");
|
|
if (obj.children && obj.children.length > 0) {
|
|
obj.traverse((item) => {
|
|
item.element && (item.element.style.display = "none");
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} toMall() 显示室内模型
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 显示室内模型
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.toMall();
|
|
*/
|
|
toMall: function () {
|
|
Map_QM.controls.setDistance(Map_QM.util.changeDist.inner - 25);
|
|
Map_QM.controls.update();
|
|
Map_QM.disPlayEvent();
|
|
renderCount = 0;
|
|
},
|
|
toMallInner: function () {
|
|
isShowElement = true;
|
|
TweenMax.killAll(true);
|
|
Map_QM.emitChangeMap("mall");
|
|
startRotate = false;
|
|
Map_QM.outModelGap.rotateY(-1 * Map_QM.outModelGap.rotation.y);
|
|
if (Map_QM.outModelGap.visible) {
|
|
TweenMax.to(Map_QM.outModelGap.scale, 0.5, {
|
|
y: 0.01,
|
|
ease: Quad.easeIn,
|
|
onComplete: function () {
|
|
Map_QM.buildObj.visible = true;
|
|
Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面
|
|
Map_QM.hideObjecrGap(Map_QM.outObject, false);
|
|
Map_QM.onShowDeviceSite();
|
|
},
|
|
});
|
|
} else {
|
|
if (Map_QM.peripheryGap.visible) {
|
|
TweenMax.to(Map_QM.peripheryGap.scale, 0.5, {
|
|
y: 0.01,
|
|
ease: Quad.easeIn,
|
|
onComplete: function () {
|
|
Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏外立面
|
|
Map_QM.hideObjecrGap(Map_QM.perObject, false);
|
|
Map_QM.buildObj.visible = true;
|
|
Map_QM.onShowDeviceSite();
|
|
},
|
|
});
|
|
} else {
|
|
Map_QM.buildObj.visible = true;
|
|
Map_QM.onShowDeviceSite();
|
|
}
|
|
}
|
|
},
|
|
//设置地图状态为室内状态
|
|
setMall: function () {
|
|
isShowElement = true;
|
|
TweenMax.killAll(true);
|
|
Map_QM.emitChangeMap("mall");
|
|
startRotate = false;
|
|
Map_QM.outModelGap.rotateY(-1 * Map_QM.outModelGap.rotation.y);
|
|
Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面
|
|
Map_QM.hideObjecrGap(Map_QM.outObject, false);
|
|
Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏外立面
|
|
Map_QM.hideObjecrGap(Map_QM.perObject, false);
|
|
Map_QM.buildObj.visible = true;
|
|
Map_QM.onShowDeviceSite();
|
|
renderCount = 0;
|
|
},
|
|
|
|
emitChangeMap: function (state) {
|
|
if (mapState != state) {
|
|
mapState = state;
|
|
Map_QM.dispatchEvent({
|
|
type: "mapShowChange",
|
|
data: mapState,
|
|
});
|
|
}
|
|
},
|
|
hideObjecrGap: function (gap, isShow) {
|
|
gap.visible = isShow;
|
|
gap.traverse((obj) => {
|
|
if (obj.userData && obj.userData.type == "2d_IP") {
|
|
if (obj.element) {
|
|
if (isShow) {
|
|
obj.element.style.visibility =
|
|
obj.userData.show == language ? "visible" : "hidden";
|
|
} else {
|
|
obj.element.style.visibility = "hidden";
|
|
}
|
|
}
|
|
}
|
|
});
|
|
},
|
|
/**
|
|
* @api {方法} onShowLocalSite(0) 局部显示放大
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 局部显示放大 point 传入放大目标点,zoom放大级别 1-5
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Object} point 放大的地图位置
|
|
* @apiParam {int} zoom 放大倍数(默认 1)
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {Object} 请求示例
|
|
*
|
|
* Map_QM.onShowLocalSite({x:0,y:0},1);
|
|
*
|
|
*/
|
|
onShowLocalSite: function (centerPoint, juZ = true) {
|
|
Map_QM.controls.reset();
|
|
if (Map_QM.util.initModelArr.length > 0 && Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) {
|
|
Map_QM.controls.maxDistance = Map_QM.util.changeDist.inner;
|
|
}
|
|
Map_QM.mapToPoint(centerPoint.x, centerPoint.y, 0);
|
|
if (!juZ) {
|
|
allJU = false;
|
|
}
|
|
isJUZ = juZ;
|
|
Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
|
|
Map_QM.updateRender();
|
|
Map_QM.collLabel();
|
|
},
|
|
/**
|
|
* @api {方法} mapToPoint() 镜头聚焦特定点
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 镜头聚焦特定点
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {int} x x坐标
|
|
* @apiParam {int} y y坐标
|
|
* @apiParam {int} z z坐标
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {Object} 请求示例
|
|
*
|
|
* Map_QM.mapToPoint(0,0,1);
|
|
*
|
|
*/
|
|
mapToPoint: function (mapX, mapY, mapZ) {
|
|
let tag0 = Map_QM.controls.target;
|
|
let pos0 = Map_QM.controls.object.position;
|
|
let vct = new THREE.Vector3(mapX, -1 * mapY, mapZ);
|
|
vct.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix);
|
|
vct.applyMatrix4(Map_QM.sceneGap.matrix);
|
|
Map_QM.controls.target = new THREE.Vector3(vct.x, vct.y, vct.z);
|
|
Map_QM.controls.object.position.set(pos0.x + (vct.x - tag0.x), pos0.y + (vct.y - tag0.y), pos0.z + (vct.z - tag0.z));
|
|
return vct;
|
|
},
|
|
/**
|
|
* @api {方法} onShowDeviceSite() 地图方向复位
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 地图方向复位
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.onShowDeviceSite();
|
|
*
|
|
*/
|
|
onShowDeviceSite: function () {
|
|
this.showFloor(this.util.deviceObj.floor);
|
|
},
|
|
/**
|
|
* 在2D 状态下平移镜头
|
|
*/
|
|
moveCameraBy2D: function (obj) {
|
|
if (pathCameraState == "2D" && Map_QM.camera == Map_QM.cameraOrtho) {
|
|
Map_QM.controls.minAzimuthAngle = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
|
|
Map_QM.controls.maxAzimuthAngle = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
|
|
Map_QM.mapToPoint(obj.x, obj.y, 0);
|
|
Map_QM.controls.update();
|
|
}
|
|
},
|
|
/**
|
|
* 方向复位
|
|
*/
|
|
resetMeDir: function () {
|
|
this.changeMapState("3d");
|
|
this.controls.minAzimuthAngle = -Infinity;
|
|
this.controls.maxAzimuthAngle = Infinity;
|
|
this.shawLight.castShadow = this.util.options.shadow;
|
|
this.controls.reset();
|
|
this.util.options.deviceAng && this.rotationAngle(this.util.deviceObj.angle);
|
|
},
|
|
/**
|
|
* @api {方法} changePathDir(pathState) 切换导航方向
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 切换导航方向
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {String} pathState 地图导航方向(默认 3D)
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.changePathDir("2D");
|
|
*
|
|
*/
|
|
changePathDir: function (pathState = "3D") {
|
|
if (Map_QM.util.pathStateObj.isPathState) {
|
|
//导航状态
|
|
let initVis = false;
|
|
if (Map_QM.endModel && Map_QM.endIcon) {
|
|
initVis = pathCameraState == "2D" ? Map_QM.endIcon.visible : Map_QM.endModel.visible;
|
|
}
|
|
pathCameraState = pathState;
|
|
if (Map_QM.endModel && Map_QM.endIcon) {
|
|
Map_QM.endModel.visible = pathCameraState == "2D" ? false : initVis;
|
|
Map_QM.endIcon.visible = pathCameraState == "2D" ? initVis : false;
|
|
}
|
|
Map_QM.reSetGuide();
|
|
Map_QM.pathRePlay();
|
|
}
|
|
},
|
|
reSetGuide: function () {
|
|
if (pathCameraState == "2D") {
|
|
//2D导航
|
|
Map_QM.onShowMeDir();
|
|
Map_QM.guide.visible = false;
|
|
let pos = Map_QM.guide.position;
|
|
Map_QM.guide = Map_QM.man_2d;
|
|
Map_QM.guide.position.x = pos.x;
|
|
Map_QM.guide.position.y = pos.y;
|
|
Map_QM.guide.visible = true;
|
|
Map_QM.controls.enabled = false;
|
|
} else {
|
|
Map_QM.resetMeDir();
|
|
Map_QM.controls.enabled = true;
|
|
Map_QM.controls.enableRotate = true;
|
|
Map_QM.guide.visible = false;
|
|
let pos = Map_QM.guide.position;
|
|
Map_QM.guide = Map_QM.man_3d;
|
|
Map_QM.guide.position.x = pos.x;
|
|
Map_QM.guide.position.y = pos.y;
|
|
Map_QM.guide.visible = true;
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} queryObject3DByShopNum(ipName) 获取3D对象
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 获取3D对象
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {string} ipName POI名称
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.queryObject3DByShopNum("L1001");
|
|
*
|
|
*/
|
|
queryObject3DByShopNum: function (ipName) {
|
|
for (let b = 0; b < Map_QM.mapArr.length; b++) {
|
|
for (let i = 0; i < Map_QM.mapArr[b].length; i++) {
|
|
let shopArr = Map_QM.mapArr[b][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (shopArr[k].name == ipName) {
|
|
return shopArr[k];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
/**
|
|
* @api {方法} parseSelectShop() 设置选中店铺弹跳
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 设置选中店铺弹跳
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {object3D} selObject 传入3D对象
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.parseSelectShop(object);
|
|
*
|
|
*/
|
|
parseSelectShop: function (selObject) {
|
|
if (selObject) {
|
|
Map_QM.selectShop = selObject;
|
|
TweenMax.to(Map_QM.selectShop.scale, 0.5, {
|
|
z: 3, repeat: 4, yoyo: true, ease: Cubic.easeIn,
|
|
onComplete: function () {
|
|
if (Map_QM.selectShop) {
|
|
TweenMax.to(Map_QM.selectShop.scale, 0.5, { z: 1 });
|
|
}
|
|
},
|
|
});
|
|
if (Map_QM.util.options.inArea && Map_QM.camera != Map_QM.cameraOrtho) {
|
|
Map_QM.onShowLocalSite(new Map_QM.util.Point(Map_QM.selectShop.xaxis, Map_QM.selectShop.yaxis));
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} cancelSelectShop() 取消店铺弹跳
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 取消店铺弹跳效果
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.cancelSelectShop();
|
|
*
|
|
*/
|
|
cancelSelectShop: function () {
|
|
TweenMax.killAll(true);
|
|
if (Map_QM.selectShop) {
|
|
Map_QM.selectShop.scale.z = 1;
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} changeStateShopPro(isShow) 店铺促销标签
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 店铺促销标签展示/隐藏
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {boolean} isShow 店铺促销标签是否显示(默认 false)
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {boolean} 请求示例
|
|
*
|
|
* Map_QM.changeStateShopPro(true);
|
|
*
|
|
*/
|
|
changeStateShopPro: function (isShow = false) {
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild]) {
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].tagObj.traverse((obj) => {
|
|
obj.element && (obj.element.style.display = isShow ? "block" : "none");
|
|
});
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} changeShowTagObjState(isShow) 自定义标签
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 自定义标签展示/隐藏
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {boolean} isShow 自定义标签是否显示(默认 false)
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {boolean} 请求示例
|
|
*
|
|
* Map_QM.changeShowTagObjState(true);
|
|
*
|
|
*/
|
|
changeShowTagObjState: function (isShow = false) {
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].showTagObj.traverse((obj) => {
|
|
obj.visible = isShow;
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @api {方法} queryShopList() 获取店铺列表信息
|
|
* @apiGroup 地图数据
|
|
* @apiDescription 店铺列表
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.queryShopList()
|
|
*
|
|
*/
|
|
queryShopList: function () {
|
|
return JSON.parse(JSON.stringify(Map_QM.util.shopData));
|
|
},
|
|
/**
|
|
* @api {方法} drawCurveLine(startShop,endShop,color) 绘制引导线
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 绘制引导线
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {string/Array} startShop 起始店铺编号或编号数组
|
|
* @apiParam {string/Array} endShop 终点店铺编号或编号数组
|
|
* @apiParam {string} color 绘制颜色 (默认 "#0099ff")
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* //绘制一到多
|
|
* Map_QM.drawCurveLine("L125",["L117","L127","L130"],"#2246d8")
|
|
* //绘制多到一
|
|
* Map_QM.drawCurveLine(["L117","L127","L130"],"L125","#66ffff")
|
|
*
|
|
*/
|
|
drawCurveLine: function (startShop, endShop, color = "#3969f7") {
|
|
let sp, ep, cp1, cp2;
|
|
hasLine = true;
|
|
if (Array.isArray(startShop) && Array.isArray(endShop)) {
|
|
return { msg: "只能有一个数组" };
|
|
}
|
|
if (Array.isArray(startShop)) {
|
|
//如果是数组
|
|
endShop = Map_QM.shopNumToNavPoint({ houseNumber: endShop }, "shop");
|
|
for (let i = 0; i < startShop.length; i++) {
|
|
startShop[i] = Map_QM.shopNumToNavPoint(
|
|
{ houseNumber: startShop[i] },
|
|
"shop"
|
|
);
|
|
sp = new THREE.Vector3(
|
|
startShop[i].xaxis,
|
|
-1 * startShop[i].yaxis,
|
|
Map_QM.util.shopHeight
|
|
);
|
|
ep = new THREE.Vector3(
|
|
endShop.xaxis,
|
|
-1 * endShop.yaxis,
|
|
Map_QM.util.shopHeight
|
|
);
|
|
let s = Math.sqrt(
|
|
(endShop.xaxis - startShop[i].xaxis) *
|
|
(endShop.xaxis - startShop[i].xaxis) +
|
|
(endShop.yaxis - startShop[i].yaxis) *
|
|
(endShop.yaxis - startShop[i].yaxis)
|
|
);
|
|
cp1 = new THREE.Vector3(
|
|
startShop[i].xaxis + (endShop.xaxis - startShop[i].xaxis) / 3,
|
|
-1 * startShop[i].yaxis - (endShop.yaxis - startShop[i].yaxis) / 3,
|
|
Map_QM.util.shopHeight + s / 5
|
|
);
|
|
cp2 = new THREE.Vector3(
|
|
endShop.xaxis,
|
|
-1 * endShop.yaxis,
|
|
Map_QM.util.shopHeight + s / 3
|
|
);
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][
|
|
Map_QM.util.selectFloor
|
|
].lineObj.add(Map_QM.drawToLine(sp, ep, s / 10, color, cp1, cp2));
|
|
}
|
|
} else {
|
|
startShop = Map_QM.shopNumToNavPoint({ houseNumber: startShop }, "shop");
|
|
if (Array.isArray(endShop)) {
|
|
//如果是数组
|
|
for (let i = 0; i < endShop.length; i++) {
|
|
endShop[i] = Map_QM.shopNumToNavPoint({ houseNumber: endShop[i] }, "shop");
|
|
sp = new THREE.Vector3(startShop.xaxis, -1 * startShop.yaxis, Map_QM.util.shopHeight);
|
|
ep = new THREE.Vector3( endShop[i].xaxis, -1 * endShop[i].yaxis, Map_QM.util.shopHeight);
|
|
let s = Math.sqrt((endShop[i].xaxis - startShop.xaxis) *(endShop[i].xaxis - startShop.xaxis) +(endShop[i].yaxis - startShop.yaxis) *(endShop[i].yaxis - startShop.yaxis));
|
|
cp1 = new THREE.Vector3(startShop.xaxis+(endShop[i].xaxis-startShop.xaxis)/3, -1*startShop.yaxis-(endShop[i].yaxis-startShop.yaxis)/3, Map_QM.util.shopHeight+s/5);
|
|
cp2 = new THREE.Vector3(endShop[i].xaxis, -1*endShop[i].yaxis, Map_QM.util.shopHeight+s/3);
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.drawToLine(sp, ep, s / 10, color, cp1, cp2));
|
|
}
|
|
} else {
|
|
endShop = Map_QM.shopNumToNavPoint({ houseNumber: endShop }, "shop");
|
|
sp = new THREE.Vector3(startShop.xaxis,-1 * startShop.yaxis, Map_QM.util.shopHeight);
|
|
ep = new THREE.Vector3( endShop.xaxis, -1 * endShop.yaxis, Map_QM.util.shopHeight);
|
|
let s = Math.sqrt((endShop.xaxis - startShop.xaxis) *(endShop.xaxis - startShop.xaxis) +(endShop.yaxis-startShop.yaxis) *(endShop.yaxis - startShop.yaxis));
|
|
cp1 = new THREE.Vector3(startShop.xaxis+(endShop.xaxis - startShop.xaxis)/3, -1*startShop.yaxis-(endShop.yaxis-startShop.yaxis)/3, Map_QM.util.shopHeight+s/5);
|
|
cp2 = new THREE.Vector3(endShop.xaxis, -1*endShop.yaxis, Map_QM.util.shopHeight + s/3 );
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.drawToLine(sp, ep, s / 10, color, cp1, cp2));
|
|
}
|
|
}
|
|
},
|
|
|
|
drawToLine: function (startPoint, endPoint, dash = 50, color = 0x2269dd, ctrlPoint1 = null, ctrlPoint2 = null) {
|
|
let curve = new THREE.CubicBezierCurve3(startPoint,ctrlPoint1,ctrlPoint2,endPoint);
|
|
let points = curve.getPoints(dash);
|
|
let colorChange = [];
|
|
for (let i = 1; i < 7; i += 2) {
|
|
colorChange.push(parseInt("0x" + color.slice(i, i + 2)) / 255);
|
|
}
|
|
let flyLine = createFlyCurve(points, new THREE.Vector3(colorChange[0], colorChange[1], colorChange[2]), false);
|
|
flyLine.userData.type = "toLine";
|
|
return flyLine;
|
|
},
|
|
/**
|
|
* @api {方法} drawColumnar(source,property) 绘制柱状图
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 绘制柱状图
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam source 起始店铺编号或编号数组
|
|
* @apiParam property 控制参数对象
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* //绘制多个
|
|
* Map_QM.drawColumnar(["L117","L127","L130"],{"height":200,"width":20,"color":"#2246d8"})
|
|
* //绘制单个
|
|
* Map_QM.drawColumnar("L125",{"height":200,"width":20,"color":"#2246d8"})
|
|
*/
|
|
drawColumnar: function (source, property) {
|
|
if (Array.isArray(source)) {
|
|
if (source.length == 0) {
|
|
return { msg: "不能解析空数组" };
|
|
}
|
|
for (let i = 0; i < source.length; i++) {
|
|
Map_QM.drawOnlyColumer(source[i], property);
|
|
}
|
|
} else {
|
|
Map_QM.drawOnlyColumer(source, property);
|
|
}
|
|
},
|
|
drawOnlyColumer: function (houseNumber, property) {
|
|
if (houseNumber.trim() != "" && property) {
|
|
let endShop = Map_QM.shopNumToNavPoint({ houseNumber: houseNumber }, "shop");
|
|
let geometry = new THREE.BoxGeometry(
|
|
property.width * 2,
|
|
property.width * 2,
|
|
property.width * 2
|
|
);
|
|
let c = new THREE.Color(property.color);
|
|
let material;
|
|
let color2 = new THREE.Color(property.color);
|
|
for (let k = 0; k < Map_QM.util.meshMaterialArr.length; k++) {
|
|
if (Map_QM.util.meshMaterialArr[k].color && Map_QM.util.meshMaterialArr[k].color.equals(color2) && Map_QM.util.meshMaterialArr[k].isShaderMaterial) {
|
|
material = Map_QM.util.meshMaterialArr[k];
|
|
}
|
|
}
|
|
if (!material) {
|
|
material = new THREE.ShaderMaterial({
|
|
uniforms: {
|
|
targetColor: { value: new THREE.Vector3(c.r, c.g, c.b) },
|
|
height: { value: property.height / 5 },
|
|
},
|
|
transparent: true,
|
|
//depthTest:false,
|
|
vertexShader: [
|
|
"varying vec3 modelPos;",
|
|
"void main() {",
|
|
" modelPos = position;",
|
|
" gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
|
"}",
|
|
].join("\n"),
|
|
fragmentShader: [
|
|
"uniform vec3 targetColor;",
|
|
"uniform float height;",
|
|
"varying vec3 modelPos;",
|
|
"void main() {",
|
|
" gl_FragColor = vec4(targetColor.xyz,(0.9 - modelPos.y/height)*(0.9 - modelPos.y/height));",
|
|
"}",
|
|
].join("\n"),
|
|
});
|
|
Map_QM.util.meshMaterialArr.push(material);
|
|
}
|
|
|
|
let mesh = new THREE.Mesh(geometry, material);
|
|
mesh.position.set(endShop.xaxis, -1 * endShop.yaxis, property.height);
|
|
mesh.rotation.x = Math.PI / -2;
|
|
mesh.scale.setY(property.height / property.width);
|
|
let cubeEdges = new THREE.EdgesGeometry(geometry, 60);
|
|
mesh.add(new THREE.LineSegments(cubeEdges, material));
|
|
mesh.userData.type = "columer";
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(mesh);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} removeDrawEle(type) 删除绘制元素
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 删除绘制元素
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam type 传入删除的类型(默认 all) toLine--引导线 columer--柱状样式 all---所有
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.removeDrawEle("toLine")
|
|
*
|
|
*/
|
|
removeDrawEle: function (type = "all") {
|
|
if (type == "all" || type == "toLine") {
|
|
hasLine = false;
|
|
}
|
|
for (let i = 0; i < Map_QM.mapArr.length; i++) {
|
|
for (let k = 0; k < Map_QM.mapArr[i].length; k++) {
|
|
let lineObj = Map_QM.mapArr[i][k].lineObj;
|
|
for (let j = lineObj.children.length - 1; j >= 0; j--) {
|
|
if (type == "all" || lineObj.children[j].userData.type == type) {
|
|
lineObj.remove(lineObj.children[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
setHeatMapData: function () {
|
|
let points = [];
|
|
let max = 0;
|
|
let childRen = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].shopObj.children;
|
|
for (let i = 0; i < childRen.length; i++) {
|
|
let val = Math.random() * 100;
|
|
max = Math.max(max, val);
|
|
var point = {
|
|
x: parseInt(childRen[i].xaxis),
|
|
y: parseInt(childRen[i].yaxis),
|
|
value: val,
|
|
};
|
|
points.push(point);
|
|
}
|
|
// 准备 heatmap 的数据
|
|
const data = {max: max, data: points};
|
|
Map_QM.heatMap(data);
|
|
Map_QM.hideInnerFloorElement();
|
|
},
|
|
/**
|
|
* @api {方法} heatMap(data) 热力图
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 绘制热力图
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {object} data 热力图的绘制数据
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.heatMap({max: 100, data: [{x:0,y:0,value:50},...]})
|
|
*/
|
|
heatMap: function (data) {
|
|
let heatMap = document.getElementById("heatmap");
|
|
Map_QM.removeHeatMap();
|
|
heatMap.style.pointerEvents = "none";
|
|
let mapW = Map_QM.util.allMap[Map_QM.util.selectBuild].mapW || 5000;
|
|
let mapH = Map_QM.util.allMap[Map_QM.util.selectBuild].mapH || 5000;
|
|
heatMap.style.width = mapW + "px";
|
|
heatMap.style.height = mapH + "px";
|
|
|
|
if (!heatmapInstance) {
|
|
heatmapInstance = h337.create({
|
|
container: heatMap,
|
|
gradient: {
|
|
1.0: "#f00",
|
|
0.9: "#e2fa00",
|
|
0.6: "#33f900",
|
|
0.3: "#0349df",
|
|
0.0: "#0f00ff",
|
|
},
|
|
radius: 120,
|
|
maxOpacity: 1,
|
|
minOpacity: 0,
|
|
});
|
|
}
|
|
if (data.data && data.data.length > 0) {
|
|
data.data.map((item) => {
|
|
item.x += mapW / 2;
|
|
item.y += mapH / 2;
|
|
});
|
|
}
|
|
heatmapInstance.setData(data);
|
|
// 获取 heatmap
|
|
let texture = new THREE.Texture(heatmapInstance._renderer.canvas);
|
|
const material = new THREE.MeshLambertMaterial({
|
|
map: texture,
|
|
transparent: true,
|
|
opacity: 1,
|
|
});
|
|
|
|
let mesh = new THREE.Mesh(new THREE.PlaneGeometry(mapW, mapH, 10),material);
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].otherObj.add(mesh);
|
|
mesh.renderOrder = 800;
|
|
mesh.position.set(0, 0, 60);
|
|
// 更新图片
|
|
if (texture) {
|
|
texture.needsUpdate = true;
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} removeHeatMap() 清除外加图层
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 清除外加图层
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.removeHeatMap()
|
|
*/
|
|
removeHeatMap: function () {
|
|
for (let i = 0; i < Map_QM.mapArr.length; i++) {
|
|
for (let j = 0; j < Map_QM.mapArr[i].length; j++) {
|
|
Map_QM.remove_child(Map_QM.mapArr[i][j].otherObj);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} rotationAngle(angle) 改变水平角度
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 改变地图水平角度 angle>-180 && angle<180 逆时针旋转
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {int} angle 旋转角度
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {int} 请求示例
|
|
*
|
|
* Map_QM.rotationAngle(90);
|
|
*
|
|
*/
|
|
rotationAngle: function (angle) {
|
|
Map_QM.controls.setRotateHorizontal(Map_QM.controls.getRotateHorizontal());
|
|
Map_QM.controls.setRotateHorizontal((angle / 180) * Math.PI);
|
|
},
|
|
/**
|
|
* @api {方法} rotateAngle(angle) 改变垂直角度
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 改变地图垂直角度 angle>-90 && angle<90
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {int} angle 旋转角度
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {int} 请求示例
|
|
*
|
|
* Map_QM.rotateAngle(-45);
|
|
*
|
|
*/
|
|
rotateAngle: function (angle) {
|
|
let r0 = Map_QM.controls.getRotate();
|
|
Map_QM.controls.rotate(r0);
|
|
Map_QM.controls.rotate((angle / -180) * Math.PI);
|
|
},
|
|
/**
|
|
* @api {方法} setCameraDist(cDist) 调整地图大小
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 调整地图大小(值越小地图越大) Map_QM.util.options.minDis ~ Map_QM.util.options.maxDis
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {int} cDist 摄像头距离
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {int} 请求示例
|
|
*
|
|
* Map_QM.setCameraDist(150);
|
|
*
|
|
*/
|
|
setCameraDist: function (cDist) {
|
|
if (Map_QM.util.options.minDis < parseInt(cDist) && parseInt(cDist) < Map_QM.util.options.maxDis) {
|
|
let oldObj = { dis: Map_QM.controls.getDistance() };
|
|
TweenMax.killAll(true);
|
|
TweenMax.to(oldObj, 0.5, {
|
|
dis: cDist,
|
|
onUpdate: function () {
|
|
Map_QM.controls.setDistance(oldObj.dis);
|
|
Map_QM.controlsChock();
|
|
},
|
|
});
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} startRender() 启动地图渲染
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 启动地图渲染 与 cancelRender 配合使用可节约资源
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.startRender();
|
|
*
|
|
*/
|
|
startRender: function () {
|
|
Map_QM.cancelRender();
|
|
let T = Map_QM.util._clock.getDelta();
|
|
Map_QM.controls.update();
|
|
Map_QM.renderer.render(Map_QM.scene, Map_QM.camera);
|
|
Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera);
|
|
if (renderCount < 3) {
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
|
|
Map_QM.labelRenderer.renderObject(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene, Map_QM.camera);
|
|
}
|
|
renderCount++;
|
|
}
|
|
Map_QM.CSSObject && Map_QM.labelRenderer.renderObject(Map_QM.CSSObject, Map_QM.scene, Map_QM.camera);
|
|
for (let item of Map_QM.mixers) {
|
|
item.update(T);
|
|
}
|
|
if (hasLine) {
|
|
const elapsed = Map_QM.util._clock.getElapsedTime();
|
|
uniforms.u_time.value = elapsed;
|
|
}
|
|
if (startRotate) {
|
|
let y0 = Map_QM.outModelGap.rotation.y;
|
|
Map_QM.outModelGap.rotateY(0.002);
|
|
let ay = Map_QM.outModelGap.rotation.y - y0; //>0 +
|
|
let ang = -1 * Map_QM.outModelGap.rotation.y;
|
|
if (ay > 0) {
|
|
if (Map_QM.outModelGap.rotation.y > 0) {
|
|
ang = Map_QM.outModelGap.rotation.y - Math.PI;
|
|
} else {
|
|
ang = Map_QM.outModelGap.rotation.y + Math.PI;
|
|
}
|
|
}
|
|
ang -= Map_QM.controls.getRotateHorizontal() - Math.PI;
|
|
ang = ang > Math.PI ? ang - 2 * Math.PI : ang;
|
|
ang = ang < -1 * Math.PI ? ang + 2 * Math.PI : ang;
|
|
if (Map_QM.util.options.northShow) {
|
|
Map_QM.util.img.style.transform = "rotate(" + ((Math.PI - ang) * 180) / Math.PI + "deg)";
|
|
}
|
|
} else if (Map_QM.util.options.northShow) {
|
|
let a = Map_QM.controls.getRotateHorizontal();
|
|
if (Map_QM.outModelGap.visible) {
|
|
Map_QM.util.img.style.transform = "rotate(" +((Math.PI - (Map_QM.outModelGap.rotation.y - a)) * 180) / Math.PI +"deg)";
|
|
} else {
|
|
Map_QM.util.img.style.transform = "rotate(" + (a * 180) / Math.PI + "deg)";
|
|
}
|
|
}
|
|
renderFrame = requestAnimationFrame(Map_QM.startRender);
|
|
},
|
|
/**
|
|
* @api {方法} cancelRender() 取消地图渲染
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 取消地图渲染 与 startRender 配合使用可节约资源
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.cancelRender();
|
|
*
|
|
*/
|
|
cancelRender: function () {
|
|
window.cancelAnimationFrame(renderFrame);
|
|
renderFrame = -1;
|
|
},
|
|
|
|
/**
|
|
* @api {方法} addElementLabel() 地图html标签
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 地图显示Html标签,返回3d标签对象
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {Element} divObj div对象
|
|
* @apiParam {int} x 显示X坐标
|
|
* @apiParam {int} y 显示Y坐标
|
|
* @apiParam {int} z 显示高度坐标(默认 50)
|
|
* @apiParam {String} type docment元素自定义标识(默认 "shopInfo")
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
* Map_QM.addElementLabel(divObj,x,y);
|
|
*/
|
|
addElementLabel: function (divObj, x, y, z = 50, type = "shopInfo") {
|
|
divObj.style.opacity = 0;
|
|
let shopInfo = new THREE.CSS2DObject(divObj);
|
|
shopInfo.position.set(x, -1 * y, z);
|
|
shopInfo.applyMatrix4(
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix
|
|
);
|
|
shopInfo.userData.type = type;
|
|
shopInfo.userData.isShow = false;
|
|
shopInfo.userData.floor = parseInt(Map_QM.util.selectFloor);
|
|
Map_QM.CSSObject.add(shopInfo);
|
|
TweenMax.to(divObj.style, 0.2, { opacity: 1, delay: 0.1 });
|
|
return shopInfo;
|
|
},
|
|
|
|
/**
|
|
* @api {方法} updateElementPosition() 修改标签位置
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 修改标签位置
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Object} obj 对象
|
|
* @apiParam {int} x 新的X坐标
|
|
* @apiParam {int} y 新的Y坐标
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {Object} 请求示例
|
|
*
|
|
* Map_QM.updateElementPosition(obj,x,y);
|
|
*
|
|
*/
|
|
updateElementPosition: function (obj, x, y) {
|
|
if (obj.hasOwnProperty("position")) {
|
|
let h = obj.position.z;
|
|
obj.position.set(x, -1 * y, h);
|
|
obj.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix);
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} elementDestroy(type) 销毁地图标签
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 销毁地图上的html标签
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} type docment元素自定义标识(默认 "shopInfo")
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {Object} 请求示例
|
|
*
|
|
* Map_QM.elementDestroy();
|
|
*
|
|
*/
|
|
elementDestroy: function (type = "shopInfo", isRemove = false) {
|
|
if (!Map_QM.CSSObject) {
|
|
return;
|
|
}
|
|
for (let i = Map_QM.CSSObject.children.length - 1; i >= 0; i--) {
|
|
if (Map_QM.CSSObject.children[i].userData.type != "moveFloor") {
|
|
if (type == "all") {
|
|
Map_QM.CSSObject.children[i].element.style.visibility = "hidden";
|
|
} else {
|
|
if (
|
|
Map_QM.CSSObject.children[i].userData &&
|
|
Map_QM.CSSObject.children[i].userData.type == type
|
|
) {
|
|
let node = Map_QM.CSSObject.children[i];
|
|
node.element.style.visibility = "hidden";
|
|
if (isRemove && node.element.parentNode) {
|
|
node.element.parentNode.removeChild(node.element);
|
|
}
|
|
Map_QM.CSSObject.remove(node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} addElementByNode() 显示地图活动标签
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 地图显示活动标签,返回3d标签对象
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {Element} divObj div对象
|
|
* @apiParam {int} node 显示导航点位
|
|
* @apiParam {String} type docment元素自定义标识(默认 "tip")
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
* Map_QM.addElementByNode(divObj,node,type);
|
|
*/
|
|
addElementByNode: function (divObj, node, type = "tip") {
|
|
let pathData =
|
|
Map_QM.util.allMap[Map_QM.util.selectBuild].buildArr[parseInt(Map_QM.util.selectFloor)].mapData.path;
|
|
if (!pathData || !divObj) {
|
|
return;
|
|
}
|
|
if (pathData.nodes.length > 0) {
|
|
pathData.nodes.sort(Map_QM.util.sortNode);
|
|
} else {
|
|
return;
|
|
}
|
|
divObj.style.visibility = "visible";
|
|
divObj.style.opacity = "0";
|
|
let shopInfo = new THREE.CSS2DObject(divObj);
|
|
shopInfo.position.set(
|
|
pathData.nodes[parseInt(node)].x,
|
|
-1 * pathData.nodes[parseInt(node)].y,
|
|
60
|
|
);
|
|
shopInfo.applyMatrix4(
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.util.selectFloor)]
|
|
.allObj.matrix
|
|
);
|
|
shopInfo.userData.type = type;
|
|
shopInfo.userData.isShow = false;
|
|
shopInfo.userData.floor = parseInt(Map_QM.util.selectFloor);
|
|
Map_QM.CSSObject.add(shopInfo);
|
|
TweenMax.to(divObj.style, 0.2, { opacity: 1, delay: 0.2 });
|
|
return shopInfo;
|
|
},
|
|
|
|
/**
|
|
* @api {方法} changeShowShopName() 修改店铺显示名称
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 通过店铺编号修改店铺显示名称
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Array} houseNumber 店铺编号
|
|
* @apiParam {Array} nameStr 字符串
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
* Map_QM.changeShowShopName(["L104"],['<p style="color:red;">肯德基</p>'])
|
|
*/
|
|
changeShowShopName: function (shopNums, elements) {
|
|
if (shopNums.length === elements.length) {
|
|
let labObj = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children;
|
|
for (let i = 0; i < shopNums.length; i++) {
|
|
for (let j = 0; j < labObj.length; j++) {
|
|
if (labObj[j].name == shopNums[i]) {
|
|
labObj[j].element.innerHTML = elements[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} showAreaAnimate() 区域定位
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 通过区域名称凸显区域
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} aName 区域名称,不传则复位
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
* Map_QM.showAreaAnimate("A");
|
|
*/
|
|
showAreaAnimate: function (aName = "") {
|
|
//在我的方向状态,恢复
|
|
Map_QM.changeMapModel("3D");
|
|
Map_QM.resetFloorState();
|
|
Map_QM.controls.reset();
|
|
Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
|
|
TweenMax.killAll(true);
|
|
if (!aName) {
|
|
isJUZ = false;
|
|
allJU = true;
|
|
return;
|
|
}
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.traverse((obj) => {
|
|
if (obj.userData && obj.userData.type == "build") {
|
|
if (obj.name == aName) {
|
|
Map_QM.onShowLocalSite({ x: obj.userData.xaxis, y: obj.userData.yaxis }, false);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @api {方法} unionShop() 店铺合并
|
|
* @apiGroup 地图显示
|
|
* @apiDescription 通过店铺编号合并店铺 合铺
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Array} shops 店铺编号数组
|
|
* @apiParam {Object} data 新的店铺数据(默认 空数据)
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
* Map_QM.unionShop(["L105","L106","L107","L108"],{name:"新店",houseNumber:"L104-L108",color:"#F4A460"})
|
|
*/
|
|
unionShop: function (
|
|
shops,
|
|
data = { name: "", houseNumber: "shop", color: "#F4A460" }
|
|
) {
|
|
let shopObj = [],
|
|
xAll = 0,
|
|
yAll = 0;
|
|
if (Array.isArray(shops) && shops.length > 1) {
|
|
//删除店铺box
|
|
let shopArea =
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].shopObj
|
|
.children;
|
|
for (let i = 0; i < shops.length; i++) {
|
|
for (let k = 0; k < shopArea.length; k++) {
|
|
if (shopArea[k].name == shops[i]) {
|
|
xAll += shopArea[k].xaxis;
|
|
yAll += shopArea[k].yaxis;
|
|
shopObj.push(shopArea[k]);
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][
|
|
Map_QM.util.selectFloor
|
|
].shopObj.remove(shopArea[k]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//删除文本标签
|
|
let labObj = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children;
|
|
for (let i = 0; i < shops.length; i++) {
|
|
for (let j = 0; j < labObj.length; j++) {
|
|
if (labObj[j].name == shops[i]) {
|
|
if (labObj[j].element && labObj[j].element.parentNode) {
|
|
labObj[j].element.parentNode.removeChild(labObj[j].element);
|
|
}
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.remove(labObj[j]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
let point = {
|
|
x: xAll / shopObj.length,
|
|
y: yAll / shopObj.length,
|
|
};
|
|
let baseShop;
|
|
for (let l = 0; l < shopObj.length; l++) {
|
|
if (l == 0) {
|
|
baseShop = new ThreeBSP(shopObj[0]);
|
|
} else {
|
|
baseShop = baseShop.union(new ThreeBSP(shopObj[l]));
|
|
}
|
|
}
|
|
//ThreeBSP对象转化为网格模型对象
|
|
let mesh = baseShop.toMesh();
|
|
mesh.userData = data;
|
|
mesh.userData.shopData = { formatColor: data.color };
|
|
mesh.userData.xaxis = point.x >> 0;
|
|
mesh.userData.yaxis = point.y >> 0;
|
|
mesh.userData.houseNumber = data.houseNumber;
|
|
mesh.userData.entColor = data.color;
|
|
mesh.userData.type = "shop";
|
|
if (data.name) {
|
|
mesh.name = data.name;
|
|
let shopDiv = document.createElement("div");
|
|
shopDiv.className = "map_label";
|
|
if (window.innerWidth > 2000) {
|
|
shopDiv.style.fontSize = "18px";
|
|
}
|
|
shopDiv.innerHTML = data.name;
|
|
shopDiv.dataset.name = data.name;
|
|
shopDiv.dataset.nameEn = data.nameEn || data.name;
|
|
let shopLabel = new THREE.CSS2DObject(shopDiv);
|
|
shopLabel.position.set(point.x >> 0, (-1 * point.y) >> 0, 30);
|
|
shopLabel.name = data.houseNumber || "";
|
|
shopLabel.userData.mapShow = true; //是否永久显示
|
|
shopLabel.userData.isShow = true;
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.add(shopLabel);
|
|
}
|
|
mesh.material = new THREE.MeshPhongMaterial({
|
|
color: data.color || 0xf4a460,
|
|
transparent: true,
|
|
opacity: 0.9,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][
|
|
Map_QM.util.selectFloor
|
|
].allObj.add(mesh);
|
|
}
|
|
renderCount = 0;
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* @param {Object} e
|
|
* 地图BOX点击
|
|
*/
|
|
onMouseClickBox: function (event) {
|
|
startRotate = false;
|
|
let mouse = new THREE.Vector2();
|
|
mouse.x = (event.offsetX / Map_QM.w) * 2 - 1;
|
|
mouse.y = -(event.offsetY / Map_QM.h) * 2 + 1;
|
|
Map_QM.onCallTouchORMouse(mouse);
|
|
},
|
|
onCallTouchORMouse: function (mouse) {
|
|
if ((Map_QM.mapArr && !Map_QM.mapArr[Map_QM.util.selectBuild] &&!Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) || !Map_QM.buildObj.visible || Map_QM.util.pathStateObj.isPathState) {
|
|
return;
|
|
}
|
|
let raycaster = new THREE.Raycaster();
|
|
raycaster.setFromCamera(mouse, Map_QM.camera);
|
|
let intersects = raycaster.intersectObjects(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.children, true);
|
|
let clickShop = false,
|
|
clickOnly = false,
|
|
onlyData = null;
|
|
for (let i = 0; i < intersects.length; i++) {
|
|
//店铺BOX点击
|
|
if (intersects[i].object.userData && intersects[i].object.userData.type == "shop") {
|
|
if (intersects[i].object.name != "") {
|
|
if (Map_QM.endModel && Map_QM.endModel.visible) {
|
|
Map_QM.endModel.visible = false;
|
|
}
|
|
clickShop = true;
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.clearPath();
|
|
Map_QM.setSelectShopMat(intersects[i].object);
|
|
break;
|
|
} else {
|
|
//空店铺有编号
|
|
if (intersects[i].object.userData.houseNumber && intersects[i].object.userData.houseNumber != "shop") {
|
|
clickOnly = true;
|
|
onlyData = intersects[i].object.userData;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @api {事件} shop 点击已绑定品牌的店铺
|
|
* @apiGroup 地图事件
|
|
* @apiDescription 用户点击店铺后触发自定义事件
|
|
* @apiVersion 4.0.0
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* Map_QM.addEventListener("shop",onClickShop,false);
|
|
*/
|
|
if (clickShop && Map_QM.selectShop && Map_QM.selectShop.userData) {
|
|
if (Map_QM.selectShop.userData.shopData.hasOwnProperty("houseNumber")) {
|
|
Map_QM.dispatchEvent({
|
|
type: "shop",
|
|
data: Map_QM.selectShop.userData,
|
|
});
|
|
} else {
|
|
/**
|
|
* @api {事件} onlyShop 点击未绑定品牌的店铺
|
|
* @apiGroup 地图事件
|
|
* @apiDescription 用户点击空店铺后触发自定义事件
|
|
* @apiVersion 4.0.0
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* Map_QM.addEventListener("onlyShop",onClickShop,false);
|
|
*/
|
|
Map_QM.dispatchEvent({
|
|
type: "onlyShop",
|
|
data: Map_QM.selectShop.userData,
|
|
});
|
|
}
|
|
} else {
|
|
if (clickOnly) {
|
|
Map_QM.dispatchEvent({
|
|
type: "onlyShop",
|
|
data: onlyData,
|
|
});
|
|
} else {
|
|
Map_QM.dispatchEvent({
|
|
type: "shop",
|
|
data: null,
|
|
});
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} setSelectShopMatByName(houseNumber) 设置box 选中
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 地图box 选中
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} houseNumber POI编号
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.setSelectShopMatByName("L101");
|
|
*
|
|
*/
|
|
setSelectShopMatByName: function (ipName) {
|
|
for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) {
|
|
let shopArr = Map_QM.mapArr[Map_QM.util.selectBuild][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (shopArr[k].name == ipName) {
|
|
Map_QM.setSelectShopMat(shopArr[k]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
//改变选中店铺box
|
|
setSelectShopMat: function (selObject) {
|
|
TweenMax.killAll(true);
|
|
if (Map_QM.selectShop) {
|
|
Map_QM.selectShop.scale.z = 1;
|
|
}
|
|
Map_QM.parseSelectShop(selObject);
|
|
},
|
|
updateRender: function () {
|
|
Map_QM.controls.update();
|
|
Map_QM.renderer.render(Map_QM.scene, Map_QM.camera);
|
|
Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera);
|
|
|
|
Map_QM.labelRenderer.renderObject(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene, Map_QM.camera);
|
|
Map_QM.labelRenderer.zOrder(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj);
|
|
},
|
|
/**
|
|
* 初始化后调用
|
|
*/
|
|
timeOutInit: function () {
|
|
Map_QM.updateRender();
|
|
Map_QM.autoChangeEleAngle();
|
|
Map_QM.collLabel();
|
|
renderCount = 0;
|
|
if (Map_QM.callBackLoadOver) {
|
|
let floorData = [];
|
|
for (let i = 0; i < Map_QM.util.allMap.length; i++) {
|
|
let build = [];
|
|
for (let j = 0; j < Map_QM.util.allMap[i].buildArr.length; j++) {
|
|
if (Map_QM.util.allMap[i].buildArr[j]) {
|
|
build.push({
|
|
order: Map_QM.util.allMap[i].buildArr[j].order,
|
|
name: Map_QM.util.allMap[i].buildArr[j].name,
|
|
});
|
|
}
|
|
}
|
|
floorData.push(build);
|
|
}
|
|
if (Map_QM.backObj) {
|
|
Map_QM.controls.enabled = true;
|
|
Map_QM.backObj.data = floorData;
|
|
}
|
|
Map_QM.callBackLoadOver(Map_QM.backObj); //初始化完成后回调
|
|
Map_QM.callBackLoadOver = null;
|
|
Map_QM.backObj = null;
|
|
}
|
|
Map_QM.dispatchEvent({
|
|
type: "changeFloorOver",
|
|
data: Map_QM.selectFloor,
|
|
});
|
|
},
|
|
|
|
autoChangeEleAngle: function () {
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild]) {
|
|
for (let m = 0; m < Map_QM.mapArr[Map_QM.util.selectBuild].length; m++) {
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild][m].allObj.visible) {
|
|
let svgChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].svgObj.children;
|
|
let rat = Map_QM.controls.getRotateHorizontal();
|
|
svgChilds.forEach((item) => {
|
|
if (Math.abs(item.rotation.x) < 0.5) {
|
|
if (
|
|
rat - item.userData.rot > 1.7 ||
|
|
rat - item.userData.rot < -1.7
|
|
) {
|
|
item.rotation.z =
|
|
item.userData.rot < 0
|
|
? item.userData.rot + 3.1415926
|
|
: item.userData.rot - 3.1415926;
|
|
} else {
|
|
item.rotation.z = item.userData.rot;
|
|
}
|
|
}
|
|
});
|
|
let logoChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].shopObj.children;
|
|
logoChilds.forEach((item) => {
|
|
if (item.children.length > 0) {
|
|
item.children.forEach((obj) => {
|
|
if (obj.userData.type == "logo") {
|
|
if (
|
|
rat - obj.userData.rot > 1.7 ||
|
|
rat - obj.userData.rot < -1.7
|
|
) {
|
|
obj.rotation.z =
|
|
obj.userData.rot < 0
|
|
? obj.userData.rot + 3.1415926
|
|
: obj.userData.rot - 3.1415926;
|
|
} else {
|
|
obj.rotation.z = obj.userData.rot;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
disPlayEvent: function () {
|
|
renderCount = 0;
|
|
let distance = Map_QM.controls.getDistance();
|
|
if (distance > Map_QM.util.changeDist.outner + 20 && mapState != "periphery") {
|
|
Map_QM.toPeripheryInner();
|
|
} else if (distance > Map_QM.util.changeDist.inner + 20 && distance < Map_QM.util.changeDist.outner - 20 && mapState != "out") {
|
|
Map_QM.toOutModelInner();
|
|
} else if (distance < Map_QM.util.changeDist.inner - 20 && mapState != "mall") {
|
|
Map_QM.toMallInner();
|
|
}
|
|
},
|
|
/**
|
|
* 碰撞检测
|
|
* @param {Object} 传入检测楼层下标
|
|
*/
|
|
controlsChock: function () {
|
|
Map_QM.autoChangeEleAngle();
|
|
renderCount = 0;
|
|
/**
|
|
* @api {事件} MapAngleChange 地图的方向改变
|
|
* @apiGroup 地图事件
|
|
* @apiDescription 用户操作地图时触发
|
|
* @apiVersion 4.0.0
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* Map_QM.addEventListener("MapAngleChange",onMapAngleChange,false);
|
|
*/
|
|
Map_QM.dispatchEvent({
|
|
type: "MapAngleChange",
|
|
data: {
|
|
hAngle: Map_QM.controls.getRotateHorizontal(),
|
|
vAngle: Map_QM.controls.getRotate(),
|
|
},
|
|
});
|
|
|
|
if (Map_QM.util.options.inArea && isJUZ && allJU) {
|
|
clearTimeout(shopTime);
|
|
shopTime = setTimeout(() => {
|
|
clearTimeout(shopTime);
|
|
isJUZ = false;
|
|
Map_QM.controls.reset();
|
|
Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
|
|
}, 10000);
|
|
}
|
|
},
|
|
|
|
//内部碰撞检测
|
|
collLabel: function () {
|
|
if (!Map_QM || !isShowElement) {
|
|
return;
|
|
}
|
|
if(window.requestIdleCallback){
|
|
requestIdleCallback(Map_QM.runTaskQueue, { timeout: 300 });
|
|
}else{
|
|
clearTimeout(allTime);
|
|
allTime = setTimeout(() => {
|
|
clearTimeout(allTime);
|
|
Map_QM.runTaskQueue();
|
|
}, 300);
|
|
}
|
|
},
|
|
runTaskQueue: function (){
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.buildObj.visible && Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.visible && (!Map_QM.buildObj.userData.hasOwnProperty("visible") || Map_QM.buildObj.userData.visible)) {
|
|
let childs = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children;
|
|
let len = childs.length;
|
|
|
|
for (let i = 0; i < len; i++) {
|
|
if (!childs[i].userData.isShow) {
|
|
//是否可见
|
|
continue;
|
|
}
|
|
if (!Map_QM.util.options.collision) {
|
|
childs[i].element.style.display = "";
|
|
continue;
|
|
}
|
|
let obj = childs[i].element;
|
|
obj.style.display = "";
|
|
let labP = obj.getBoundingClientRect();
|
|
for (let j = 0; j < i; j++) {
|
|
if (childs[j].element.style.display == "") {
|
|
let pb = childs[j].element.getBoundingClientRect();
|
|
let isCol = Map_QM.util.isCollision(labP, pb);
|
|
if (isCol) {
|
|
if (!childs[i].userData.mapShow) {
|
|
childs[i].element.style.display = "none";
|
|
break;
|
|
} else if (!childs[j].userData.mapShow) {
|
|
childs[j].element.style.display = "none";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 寻路----------------------------------------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* @api {方法} bounceIcon("xsj") 图标弹跳
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 地图图标弹跳效果
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} iconType 设施缩写
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.bounceIcon("xsj");
|
|
*
|
|
*/
|
|
bounceIcon: function (iconType) {
|
|
TweenMax.killAll(true);
|
|
let facs =
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.util.selectFloor)]
|
|
.serObj.children; //交通图标
|
|
for (let i = 0; i < facs.length; i++) {
|
|
if (facs[i].type == "Object3D") {
|
|
if (facs[i].userData.facCode == iconType) {
|
|
facs[i].element.style.zIndex = 200;
|
|
let oldZ = facs[i].userData.site + 5;
|
|
TweenMax.fromTo(
|
|
facs[i].position,
|
|
0.5,
|
|
{ z: oldZ },
|
|
{
|
|
z: oldZ + 80,
|
|
repeat: 1,
|
|
onUpdate: function () {
|
|
Map_QM.labelRenderer.renderObject(
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene, Map_QM.camera);
|
|
},
|
|
onComplete: function () {
|
|
TweenMax.to(facs[i].position, 0.2, {
|
|
z: oldZ,
|
|
onUpdate: function () {
|
|
Map_QM.labelRenderer.renderObject(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene, Map_QM.camera);
|
|
},
|
|
});
|
|
},
|
|
}
|
|
);
|
|
} else {
|
|
facs[i].element.style.zIndex = 100;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} countPath() 方向算法
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 计算设施、店铺的导航方向, toObj,pathType 不能同时为空
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Object} toObj {build,floor,node} //终点 设施寻路可以为空
|
|
* @apiParam {String} pathType 公共设施名称或编号(点位寻路此参数为空字符串)
|
|
* @apiParam {String} countType 8--八方向(默认) 12--十二方向
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.countPath({build:0,floor:0,node:0},"xsj","8");
|
|
*
|
|
*/
|
|
countPath: function (toObj, pathType = "", _countType = "8") {
|
|
direction = { code: 500, dir: "", cost: 0, gap: 0 };
|
|
countType = _countType;
|
|
Map_QM.util.overObj = null;
|
|
if (pathType == "") {
|
|
//传入终点导航点
|
|
Map_QM.util.overObj = toObj;
|
|
if (
|
|
Map_QM.util.startObj.node != "" &&
|
|
Map_QM.util.startObj.node != "-1" &&
|
|
Map_QM.util.overObj.node != ""
|
|
) {
|
|
this.forShopArr.length = 0;
|
|
return this.forDirPath();
|
|
} else {
|
|
direction.code = "404";
|
|
return direction;
|
|
}
|
|
} else {
|
|
//
|
|
let iconPath = this.pathIcon({ type: pathType });
|
|
Map_QM.util.overObj = iconPath;
|
|
if (
|
|
Map_QM.util.startObj.node != "" &&
|
|
Map_QM.util.startObj.node != "-1" &&
|
|
Map_QM.util.overObj.node != ""
|
|
) {
|
|
this.forShopArr.length = 0;
|
|
return this.forDirPath();
|
|
}
|
|
}
|
|
return (direction = { code: 404, dir: "", cost: 0, gap: 0 });
|
|
},
|
|
forDirPath: function () {
|
|
let startNade = Map_QM.util.startObj.build +"_" +Map_QM.util.startObj.floor +"_" +Map_QM.util.startObj.node;
|
|
let toNade = Map_QM.util.overObj.build +"_" +Map_QM.util.overObj.floor +"_" +Map_QM.util.overObj.node;
|
|
let PathPoint;
|
|
direction = { code: 500, dir: "", cost: 0, gap: 0 };
|
|
try {
|
|
let obj = dijkstra.find_path(Map_QM.util.pathStateObj.graphPath,startNade,toNade);
|
|
PathPoint = obj.nodes;
|
|
direction.cost = Math.floor((obj.cost / Map_QM.util.options.mapScale) * 0.9);
|
|
direction.gap = parseInt(obj.cost / Map_QM.util.options.mapScale);
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
direction.code = 404;
|
|
return direction;
|
|
}
|
|
let index = 0;
|
|
this.forShopArr = [];
|
|
if (PathPoint.length > 1) {
|
|
this.forShopArr.push({build: Map_QM.util.startObj.build,floor: Map_QM.util.startObj.floor,PathPoint: [],});
|
|
let pathData;
|
|
for (let j = 0; j < PathPoint.length; j++) {
|
|
let array = PathPoint[j].split("_");
|
|
pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path;
|
|
pathData.nodes.sort(Map_QM.util.sortNumber);
|
|
if (parseInt(array[1]) == this.forShopArr[index].floor) {
|
|
//同层
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
} else {
|
|
this.forShopArr.push({
|
|
build: parseInt(array[0]),
|
|
floor: parseInt(array[1]),
|
|
PathPoint: [],
|
|
});
|
|
index++;
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
}
|
|
}
|
|
} else {
|
|
this.forShopArr.length = 0;
|
|
}
|
|
if (this.forShopArr.length > 0) {
|
|
//--------------------------计算方向
|
|
direction.code = 200;
|
|
if (countType == "12") {
|
|
//16方向
|
|
Map_QM.countSixteenArrow();
|
|
} else {
|
|
Map_QM.countStartAndEndDire();
|
|
}
|
|
}
|
|
console.log(this.forShopArr);
|
|
if (this.forShopArr.length > 1) {
|
|
let facType;
|
|
if (this.forShopArr[0].floor > this.forShopArr[1].floor) {
|
|
//下
|
|
if (
|
|
Math.abs(
|
|
parseInt(this.forShopArr[0].floor) -
|
|
parseInt(this.forShopArr[1].floor)
|
|
) < 3
|
|
) {
|
|
//扶梯
|
|
facType = Map_QM.util.getFacType("downft");
|
|
} else {
|
|
facType = Map_QM.util.getFacType("dt");
|
|
}
|
|
} else {
|
|
if (
|
|
Math.abs(
|
|
parseInt(this.forShopArr[0].floor) -
|
|
parseInt(this.forShopArr[1].floor)
|
|
) < 3
|
|
) {
|
|
//扶梯
|
|
facType = Map_QM.util.getFacType("upft");
|
|
} else {
|
|
facType = Map_QM.util.getFacType("dt");
|
|
}
|
|
}
|
|
facType = facType + "";
|
|
if (facType.length === 1) {
|
|
direction.dir = "600" + facType;
|
|
} else if (facType.length === 2) {
|
|
direction.dir = "60" + facType;
|
|
} else if (facType.length === 3) {
|
|
direction.dir = "6" + facType;
|
|
}
|
|
}
|
|
return direction;
|
|
},
|
|
/**
|
|
* 计算十六方向箭头
|
|
*/
|
|
countSixteenArrow: function () {
|
|
if (this.forShopArr[0].PathPoint.length > 1) {
|
|
let keyPoints = [],
|
|
ishas = false,
|
|
allCount = 0;
|
|
for (let i = 1; i < this.forShopArr[0].PathPoint.length; i++) {
|
|
let s = Math.sqrt(Math.pow(this.forShopArr[0].PathPoint[i].x - this.forShopArr[0].PathPoint[i - 1].x,2) +
|
|
Math.pow(this.forShopArr[0].PathPoint[i].y -this.forShopArr[0].PathPoint[i - 1].y,2));
|
|
if (s < 20) {
|
|
continue;
|
|
}
|
|
ishas = false;
|
|
let dirObj = {
|
|
angleName: Map_QM.getPathAngle(this.forShopArr[0].PathPoint[i - 1],this.forShopArr[0].PathPoint[i]),
|
|
count: s,
|
|
};
|
|
allCount += s;
|
|
if (keyPoints.length > 0 &&keyPoints[keyPoints.length - 1].angleName == dirObj.angleName) {
|
|
keyPoints[keyPoints.length - 1].count += s;
|
|
ishas = true;
|
|
}
|
|
if (!ishas) {
|
|
keyPoints.push(dirObj);
|
|
}
|
|
}
|
|
if (allCount < 150) {
|
|
//总长度< 150 按8方向
|
|
Map_QM.countStartAndEndDire();
|
|
return;
|
|
}
|
|
if (keyPoints.length == 1) {
|
|
direction.dir = Map_QM.getDirByName(keyPoints[0].angleName);
|
|
return;
|
|
}
|
|
if (keyPoints.length == 0) {
|
|
//没有路径,按方向计算
|
|
direction.code = 404;
|
|
return;
|
|
}
|
|
let upCount = 0,
|
|
rightFrontCount = 0,
|
|
rightCount = 0,
|
|
leftFrontCount = 0;
|
|
for (let item of keyPoints) {
|
|
if (item.angleName == "up") {
|
|
upCount += item.count;
|
|
} else if (item.angleName == "down") {
|
|
upCount -= item.count;
|
|
} else if (item.angleName == "right") {
|
|
rightCount += item.count;
|
|
} else if (item.angleName == "left") {
|
|
rightCount -= item.count;
|
|
} else if (item.angleName == "rightFront") {
|
|
rightFrontCount += item.count;
|
|
} else if (item.angleName == "rightRear") {
|
|
leftFrontCount -= item.count;
|
|
} else if (item.angleName == "leftFront") {
|
|
leftFrontCount += item.count;
|
|
} else if (item.angleName == "leftRear") {
|
|
rightFrontCount -= item.count;
|
|
}
|
|
}
|
|
console.log(keyPoints);
|
|
//斜方向忽略
|
|
let dir1 = "";
|
|
let bjCount = Math.max(150, allCount / 10);
|
|
let onlyDir = "";
|
|
for (let item of keyPoints) {
|
|
if (
|
|
item.angleName != "rightFront" &&
|
|
item.angleName != "leftFront" &&
|
|
item.angleName != "rightRear" &&
|
|
item.angleName != "leftRear"
|
|
) {
|
|
onlyDir =
|
|
dir1.length > 0
|
|
? dir1.substring(dir1.length - 1, dir1.length)
|
|
: dir1;
|
|
if (
|
|
item.angleName == "down" &&
|
|
(item.count > bjCount || upCount < -1 * bjCount)
|
|
) {
|
|
if (onlyDir != "D") {
|
|
dir1 += "D";
|
|
}
|
|
} else if (
|
|
item.angleName == "up" &&
|
|
(item.count > bjCount || upCount > bjCount)
|
|
) {
|
|
if (onlyDir != "T") {
|
|
dir1 += "T";
|
|
}
|
|
} else if (
|
|
item.angleName == "right" &&
|
|
(item.count > bjCount || rightCount > bjCount)
|
|
) {
|
|
if (onlyDir != "R") {
|
|
dir1 += "R";
|
|
}
|
|
} else if (
|
|
item.angleName == "left" &&
|
|
(item.count > bjCount || rightCount < -1 * bjCount)
|
|
) {
|
|
if (onlyDir != "L") {
|
|
dir1 += "L";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//console.log(dir1)
|
|
if (dir1.length > 2) dir1 = dir1.substring(0, 2); //两个以上方向
|
|
direction.dir = Map_QM.getDirByName(dir1);
|
|
if (!direction.dir) Map_QM.countStartAndEndDire();
|
|
} else {
|
|
//没有路径,按方向计算
|
|
direction.code = 404;
|
|
}
|
|
},
|
|
|
|
getDirByName: function (dir) {
|
|
switch (dir) {
|
|
default:
|
|
return "";
|
|
case "T":
|
|
return "1201";
|
|
case "R":
|
|
return "1202";
|
|
case "D":
|
|
return "1203";
|
|
case "L":
|
|
return "1204";
|
|
case "TL":
|
|
return "1205";
|
|
case "TR":
|
|
return "1206";
|
|
case "RT":
|
|
return "1207";
|
|
case "RD":
|
|
return "1208";
|
|
case "DL":
|
|
return "1209";
|
|
case "DR":
|
|
return "1210";
|
|
case "LT":
|
|
return "1211";
|
|
case "LD":
|
|
return "1212";
|
|
case "up":
|
|
return "1201";
|
|
case "rightFront":
|
|
return "8002";
|
|
case "right":
|
|
return "1202";
|
|
case "rightRear":
|
|
return "8004";
|
|
case "down":
|
|
return "1203";
|
|
case "leftRear":
|
|
return "8006";
|
|
case "left":
|
|
return "1204";
|
|
case "leftFront":
|
|
return "8008";
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 计算八方向坐标
|
|
*/
|
|
countStartAndEndDire: function () {
|
|
let sPoint = new Map_QM.util.Point(
|
|
this.forShopArr[0].PathPoint[0].x,
|
|
this.forShopArr[0].PathPoint[0].y
|
|
); //本层起始点坐标
|
|
let ePoint = new Map_QM.util.Point(
|
|
this.forShopArr[0].PathPoint[this.forShopArr[0].PathPoint.length - 1].x,
|
|
this.forShopArr[0].PathPoint[this.forShopArr[0].PathPoint.length - 1].y
|
|
); //本层结束点坐标
|
|
switch (Map_QM.getPathAngle(sPoint, ePoint)) {
|
|
default:
|
|
direction.dir = "8001";
|
|
case "up":
|
|
direction.dir = "8001";
|
|
break;
|
|
case "rightFront":
|
|
direction.dir = "8002";
|
|
break;
|
|
case "right":
|
|
direction.dir = "8003";
|
|
break;
|
|
case "rightRear":
|
|
direction.dir = "8004";
|
|
break;
|
|
case "down":
|
|
direction.dir = "8005";
|
|
break;
|
|
case "leftRear":
|
|
direction.dir = "8006";
|
|
break;
|
|
case "left":
|
|
direction.dir = "8007";
|
|
break;
|
|
case "leftFront":
|
|
direction.dir = "8008";
|
|
break;
|
|
}
|
|
},
|
|
|
|
getPathAngle: function (sPoint, ePoint) {
|
|
let x = Math.abs(sPoint.x - ePoint.x);
|
|
let y = Math.abs(sPoint.y - ePoint.y);
|
|
let tan = x / y;
|
|
let radina = Math.atan(tan); //用反三角函数求弧度
|
|
let angle = Math.floor(180 / (Math.PI / radina)) || 0; //将弧度转换成角度
|
|
|
|
if (ePoint.x > sPoint.x && ePoint.y > sPoint.y) {
|
|
// 右下方
|
|
angle = 180 - angle;
|
|
}
|
|
if (ePoint.x == sPoint.x && ePoint.y > sPoint.y) {
|
|
// 正下方
|
|
angle = 180;
|
|
}
|
|
if (ePoint.x < sPoint.x && ePoint.y > sPoint.y) {
|
|
//左下方
|
|
angle = angle - 180;
|
|
}
|
|
if (ePoint.x < sPoint.x && ePoint.y == sPoint.y) {
|
|
//左方
|
|
angle = -90;
|
|
}
|
|
if (ePoint.x < sPoint.x && ePoint.y < sPoint.y) {
|
|
// 左上方
|
|
angle = -1 * angle;
|
|
}
|
|
if (ePoint.x == sPoint.x && ePoint.y < sPoint.y) {
|
|
//上方
|
|
angle = 0;
|
|
}
|
|
if (ePoint.x > sPoint.x && ePoint.y < sPoint.y) {
|
|
//右上方
|
|
angle = angle;
|
|
}
|
|
if (ePoint.x > sPoint.x && ePoint.y == sPoint.y) {
|
|
//point在x轴正方向上
|
|
angle = 90;
|
|
}
|
|
angle -= Map_QM.util.deviceObj.angle;
|
|
angle = angle > 180 ? angle - 360 : angle;
|
|
angle = angle < -180 ? angle + 360 : angle;
|
|
|
|
if (angle > -22 && angle <= 22) {
|
|
//前
|
|
return "up";
|
|
} else if (angle > 22 && angle <= 67) {
|
|
//右前
|
|
return "rightFront";
|
|
} else if (angle > 67 && angle <= 112) {
|
|
//右
|
|
return "right";
|
|
} else if (angle > 112 && angle <= 158) {
|
|
//右后
|
|
return "rightRear";
|
|
} else if (angle > 158 || angle <= -158) {
|
|
//后
|
|
return "down";
|
|
} else if (angle > -158 && angle <= -112) {
|
|
//左后
|
|
return "leftRear";
|
|
} else if (angle > -112 && angle <= -67) {
|
|
//左
|
|
return "left";
|
|
} else {
|
|
//左前
|
|
return "leftFront";
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} pathIcon({type:"xsj"}) 获取最近设施
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 获取离当前楼层最近的设施
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {JSON} type 设施缩写
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.pathIcon({type:"xsj"});
|
|
*
|
|
* @apiSuccessExample 返回示例
|
|
* {
|
|
* "floor": 楼层编号, "node": 设施导航点,"typeCode":设施编号
|
|
* }
|
|
*
|
|
*/
|
|
pathIcon: function (iconType) {
|
|
let selIcon; //
|
|
let minS = -1;
|
|
if (
|
|
!Map_QM.util.startObj.build &&
|
|
parseInt(Map_QM.util.startObj.build) != 0
|
|
) {
|
|
Map_QM.util.startObj.build = parseInt(Map_QM.util.deviceObj.build);
|
|
}
|
|
try {
|
|
let startNade = Map_QM.util.startObj.build +"_" +Map_QM.util.startObj.floor +"_" +Map_QM.util.startObj.node;
|
|
const costAll = dijkstra.single_source_shortest_paths( Map_QM.util.pathStateObj.basePath,startNade,startNade).costs;
|
|
if (costAll) {
|
|
for (let i = 0;i < Map_QM.mapArr[parseInt(Map_QM.util.deviceObj.build)].length;i++) {
|
|
let sers =Map_QM.mapArr[parseInt(Map_QM.util.deviceObj.build)][i].serObj.children; //服务图标
|
|
for (let n = 0; n < sers.length; n++) {
|
|
if (sers[n].userData.facCode == iconType.type ||((iconType.type == "xsjn" || iconType.type == "xsjv") && sers[n].userData.facCode == "xsj")) {
|
|
let toNade =sers[n].userData.buildOrder +"_" +sers[n].userData.floorOrder +"_" +sers[n].userData.navCode;
|
|
if (!selIcon) {
|
|
minS = costAll[toNade];
|
|
if (minS) {
|
|
selIcon = sers[n];
|
|
}
|
|
} else {
|
|
let s1 = costAll[toNade];
|
|
if (s1 && s1 < minS) {
|
|
minS = s1;
|
|
selIcon = sers[n];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (selIcon) {
|
|
return {
|
|
build: parseInt(Map_QM.util.deviceObj.build),
|
|
floor: selIcon.userData.floorOrder,
|
|
site: { x: selIcon.position.x, y: selIcon.position.y },
|
|
node: selIcon.userData.navCode,
|
|
no: selIcon.userData.no,
|
|
typeCode: Map_QM.util.getFacType(iconType.type),
|
|
};
|
|
} else {
|
|
// 当前楼栋没有
|
|
for (let b = 0; b < Map_QM.mapArr.length; b++) {
|
|
if (b != parseInt(Map_QM.util.deviceObj.build)) {
|
|
for (let i = 0; i < Map_QM.mapArr[b].length; i++) {
|
|
let sers = Map_QM.mapArr[b][i].serObj.children; //服务图标
|
|
for (let n = 0; n < sers.length; n++) {
|
|
if (sers[n].userData.facCode == iconType.type) {
|
|
let toNade =b +"_" +sers[n].userData.floorOrder +"_" +sers[n].userData.navCode;
|
|
if (!selIcon) {
|
|
minS = costAll[toNade];
|
|
if (minS) {
|
|
selIcon = sers[n];
|
|
selIcon.build = b;
|
|
}
|
|
} else {
|
|
let s1 = costAll[toNade];
|
|
if (s1 && s1 < minS) {
|
|
minS = s1;
|
|
selIcon = sers[n];
|
|
selIcon.build = b;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (selIcon) {
|
|
return {
|
|
build: selIcon.userData.buildOrder,
|
|
floor: selIcon.userData.floorOrder,
|
|
node: selIcon.userData.navCode,
|
|
site: { x: selIcon.position.x, y: selIcon.position.y },
|
|
no: selIcon.userData.no,
|
|
typeCode: Map_QM.util.getFacType(iconType.type),
|
|
};
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
}
|
|
},
|
|
|
|
getIconIsNearFloor:function(iconType){
|
|
let selIcon,minS = -1;
|
|
try {
|
|
let startNade = Map_QM.util.startObj.build +"_" +Map_QM.util.startObj.floor +"_" +Map_QM.util.startObj.node;
|
|
const costAll = dijkstra.single_source_shortest_paths( Map_QM.util.pathStateObj.basePath,startNade,startNade).costs;
|
|
if (costAll) {
|
|
let buildArr = Map_QM.mapArr[Map_QM.util.selectBuild];
|
|
for(let i=0; i< buildArr.length; i++){
|
|
let sers = buildArr[i].serObj.children; //服务图标
|
|
for (let n = 0; n < sers.length; n++) {
|
|
if (sers[n].userData.facCode == iconType.type ||((iconType.type == "xsjn" || iconType.type == "xsjv") && sers[n].userData.facCode == "xsj")) {
|
|
let toNade =sers[n].userData.buildOrder +"_" +sers[n].userData.floorOrder +"_" +sers[n].userData.navCode;
|
|
if (!selIcon) {
|
|
minS = costAll[toNade];
|
|
if (minS) {
|
|
selIcon = sers[n];
|
|
}
|
|
} else {
|
|
let s1 = costAll[toNade];
|
|
if (s1 && s1 < minS) {
|
|
minS = s1;
|
|
selIcon = sers[n];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}catch(e){
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
}
|
|
return selIcon.userData.floorOrder;
|
|
},
|
|
|
|
showIconGo:function(iconType){
|
|
//删除go
|
|
Map_QM.elementDestroy("go", true);
|
|
let selIcon,minS = -1;
|
|
try {
|
|
let startNade = Map_QM.util.startObj.build +"_" +Map_QM.util.startObj.floor +"_" +Map_QM.util.startObj.node;
|
|
const costAll = dijkstra.single_source_shortest_paths( Map_QM.util.pathStateObj.basePath,startNade,startNade).costs;
|
|
if (costAll) {
|
|
let sers = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].serObj.children; //服务图标
|
|
for (let n = 0; n < sers.length; n++) {
|
|
if (sers[n].userData.facCode == iconType.type ||((iconType.type == "xsjn" || iconType.type == "xsjv") && sers[n].userData.facCode == "xsj")) {
|
|
let toNade =sers[n].userData.buildOrder +"_" +sers[n].userData.floorOrder +"_" +sers[n].userData.navCode;
|
|
if (!selIcon) {
|
|
minS = costAll[toNade];
|
|
if (minS) {
|
|
selIcon = sers[n];
|
|
}
|
|
} else {
|
|
let s1 = costAll[toNade];
|
|
if (s1 && s1 < minS) {
|
|
minS = s1;
|
|
selIcon = sers[n];
|
|
}
|
|
}
|
|
//加go弹窗
|
|
let imgDiv = document.createElement("div");
|
|
imgDiv.innerHTML = `<span class="map_go_text" style="border-radius: 5px; height: 40px; line-height: 40px;display: block;pointer-events:none;">GO</span>`;
|
|
imgDiv.className = "map_go";
|
|
imgDiv.style.zIndex = 400;
|
|
imgDiv.dataset.name = sers[n].userData.title;
|
|
imgDiv.dataset.src = sers[n].userData.src;
|
|
imgDiv.dataset.nameEn = (sers[n].element && sers[n].element.dataset.nameEn) || sers[n].userData.title;
|
|
imgDiv.dataset.buildOrder = sers[n].userData.buildOrder;
|
|
imgDiv.dataset.floorOrder = sers[n].userData.floorOrder;
|
|
imgDiv.dataset.facCode = sers[n].userData.facCode;
|
|
imgDiv.dataset.node = sers[n].userData.navCode;
|
|
imgDiv.addEventListener('click', (event) => {
|
|
Map_QM.dispatchEvent({
|
|
type: 'icon',
|
|
data: { "buildOrder": event.target.dataset.buildOrder, "floorOrder": event.target.dataset.floorOrder, "node": event.target.dataset.node, "src": event.target.dataset.src, "facCode": event.target.dataset.facCode, "title": event.target.dataset.name }
|
|
})
|
|
});
|
|
let shopInfo = new THREE.CSS2DObject(imgDiv);
|
|
shopInfo.center = new THREE.Vector2(0.5, 0);
|
|
shopInfo.position.set(sers[n].userData.x, -1*sers[n].userData.y, 120);
|
|
shopInfo.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.util.selectFloor)].allObj.matrix);
|
|
shopInfo.userData.type = "go";
|
|
shopInfo.userData.node = sers[n].userData.navCode;
|
|
shopInfo.userData.isShow = false;
|
|
Map_QM.CSSObject.add(shopInfo);
|
|
}
|
|
}
|
|
|
|
if (selIcon) {
|
|
Map_QM.CSSObject && Map_QM.CSSObject.traverse((obj) => {
|
|
if (obj.userData.type == "go" && obj.userData.node == selIcon.userData.navCode) {
|
|
obj.element.innerHTML = `<span class="best_jin">离我最近</span><span class="map_go_text" style="border-radius: 5px; height: 40px; line-height: 40px;display: block;pointer-events:none;">GO</span>`;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
renderCount = 0;
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @api {方法} pathByStartAndOver(startObj,toObj,callBackFun) 地图路径规划
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 根据传入的起、终点;直接导航
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} startObj.houseNumber 店铺编号/车位编号
|
|
* @apiParam {String} startObj.type "shop"/"park"
|
|
*
|
|
* @apiParam {String} toObj.houseNumber 店铺编号/车位编号
|
|
* @apiParam {String} toObj.type "shop"/"park"
|
|
*
|
|
* @apiParam {Function} callBackFun 回调函数
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.pathByStartAndOver({"houseNumber":"L102","type":"shop"},{"houseNumber":"L204","type":"shop"});
|
|
*
|
|
*/
|
|
pathByStartAndOver: function (startObj, toObj, callBackFun) {
|
|
try {
|
|
Map_QM.util.startObj = this.shopNumToNavPoint(startObj, startObj.type);
|
|
let overObj = this.shopNumToNavPoint(toObj, toObj.type);
|
|
this.pathNode(overObj, callBackFun);
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
return "传入点位无法导航";
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} changeStartPoint() 设置起始点位
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 设置起始点位
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {int} build 起点楼栋编号
|
|
* @apiParam {int} floor 起点楼层编号
|
|
* @apiParam {String} node 起点编号
|
|
* @apiParam {int} angle 起点角度
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* Map_QM.changeStartPoint({"build":0, "floor":3, "node":"20", "angle":0});
|
|
*
|
|
*/
|
|
changeStartPoint: function (toObj) {
|
|
this.clearFloor();
|
|
if (this.mapArr) {
|
|
for (let i = 0;i < this.mapArr[parseInt(this.util.startObj.build)].length;i++) {
|
|
for (let len =this.mapArr[parseInt(this.util.startObj.build)][i].allObj.children.length - 1;len >= 0;len--) {
|
|
let obj =this.mapArr[parseInt(this.util.startObj.build)][i].allObj.children[len];
|
|
if (obj.userData.type == "start") {
|
|
this.mapArr[parseInt(this.util.startObj.build)][i].allObj.remove(obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.util.startObj = {};
|
|
if (toObj && toObj.node) {
|
|
let pathData =this.util.allMap[parseInt(toObj.build)].buildArr[parseInt(toObj.floor)].mapData.path;
|
|
this.util.startObj.xaxis = pathData.nodes[parseInt(toObj.node)].x;
|
|
this.util.startObj.yaxis = pathData.nodes[parseInt(toObj.node)].y;
|
|
this.util.startObj.build = parseInt(toObj.build);
|
|
this.util.startObj.floor = parseInt(toObj.floor);
|
|
this.util.startObj.node = toObj.node;
|
|
this.util.startObj.angle = toObj.angle || 0;
|
|
} else {
|
|
this.util.startObj.xaxis = this.util.deviceObj.xaxis;
|
|
this.util.startObj.yaxis = this.util.deviceObj.yaxis;
|
|
this.util.startObj.build = parseInt(this.util.deviceObj.build);
|
|
this.util.startObj.floor = parseInt(this.util.deviceObj.floor);
|
|
this.util.startObj.node = this.util.deviceObj.node;
|
|
this.util.startObj.angle = this.util.deviceObj.angle;
|
|
this.util.startObj.xaxis = this.util.deviceObj.xaxis;
|
|
this.util.startObj.yaxis = this.util.deviceObj.yaxis;
|
|
}
|
|
this.mapArr[parseInt(this.util.startObj.build)][parseInt(this.util.startObj.floor)].setStartSite(
|
|
this.util.startObj.xaxis,
|
|
this.util.startObj.yaxis,
|
|
parseInt(this.util.shopHeight) + 20
|
|
);
|
|
},
|
|
|
|
/**
|
|
* @api {方法} changeMapIPState(ipName,color) 改变POI颜色
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 改变POI 颜色
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {string} ipName POI名称
|
|
* @apiParam {string} color 颜色字符串
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.changeMapIPState("L1001","#ffff00");
|
|
*
|
|
*/
|
|
changeMapIPState: function (ipName, color) {
|
|
// #775544 #AD8164
|
|
for (let i = 0; i < this.mapArr[this.util.selectBuild].length; i++) {
|
|
let shopArr = this.mapArr[this.util.selectBuild][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (shopArr[k].name == ipName ||(shopArr[k].userData && shopArr[k].userData.houseNumber == ipName)) {
|
|
shopArr[k].userData.initMaterial = shopArr[k].material;
|
|
shopArr[k].material = this.util.getMeshMaterial(color || 0xeab16e);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} resetMapIPState(ipName) 恢复POI颜色
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 恢复POI初始颜色
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {string} ipName POI名称
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.resetMapIPState("L101");
|
|
*
|
|
*/
|
|
resetMapIPState: function (ipName) {
|
|
for (let i = 0; i < this.mapArr[this.util.selectBuild].length; i++) {
|
|
let shopArr = this.mapArr[this.util.selectBuild][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (shopArr[k].name == ipName) {
|
|
shopArr[k].material = shopArr[k].userData.initMaterial;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} getMapIPData(ipName) 获取POI 基础数据
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 获取POI 基础数据
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {string} ipName POI名称
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.getMapIPData("L1001");
|
|
*
|
|
* @apiSuccessExample 返回示例
|
|
* {
|
|
* houseNumber:店铺编号, shopName:店铺名 node:导航点, floor:楼层编号, xaxis:中心点X坐标, yaxis:中心点Y坐标, borderColor:边框色, entColor:填充色
|
|
* }
|
|
*/
|
|
getMapIPData: function (ipName) {
|
|
for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) {
|
|
let shopArr = Map_QM.mapArr[Map_QM.util.selectBuild][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (shopArr[k].name == ipName ||(shopArr[k].userData && shopArr[k].userData.houseNumber == ipName)) {
|
|
return shopArr[k].userData;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} pathNode() 地图模拟导航
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 地图路径模拟导航
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {int} floor 楼层编号
|
|
* @apiParam {string} node 路径点位编号
|
|
* @apiParam {function} callBackFun 回调方法
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.pathNode({build:0, floor:2,node:"53"},callBackFun);
|
|
*
|
|
*/
|
|
pathNode: function (toObj, callBackFun) {
|
|
Map_QM.util.isMorePath = false;
|
|
if (!toObj) {
|
|
return { direction: "", wayList: [] };
|
|
}
|
|
pathCameraState = Map_QM.util.options.pathStyle;
|
|
Map_QM.reSetGuide();
|
|
Map_QM.onShowDeviceSite();
|
|
Map_QM.selectShop = null;
|
|
Map_QM.util.pathStateObj.isPathState = true;
|
|
Map_QM.elementDestroy("all");
|
|
if (
|
|
Map_QM.util.initModelArr &&
|
|
Map_QM.util.initModelArr.length > 0 &&
|
|
Map_QM.util.changeDist.inner > Map_QM.util.options.minDis
|
|
) {
|
|
Map_QM.controls.maxDistance = Map_QM.util.changeDist.inner;
|
|
}
|
|
if (!Map_QM.util.startObj.xaxis && !Map_QM.util.startObj.yaxis) {
|
|
Map_QM.changeStartPoint(null);
|
|
}
|
|
Map_QM.util.overObj = null;
|
|
Map_QM.util.overObj = {
|
|
build: toObj.build || 0,
|
|
floor: toObj.floor,
|
|
node: toObj.node,
|
|
houseNumber: toObj.houseNumber,
|
|
comeIn: toObj.comeIn || "",
|
|
};
|
|
if (Map_QM.util.overObj.node != "") {
|
|
Map_QM.cancelRender();
|
|
this.onFindPathModel();
|
|
if (callBackFun) {
|
|
Map_QM.parseForShopArr();
|
|
const data = JSON.parse(
|
|
JSON.stringify(Map_QM.util.pathStateObj.forShopArr)
|
|
);
|
|
callBackFun(data);
|
|
}
|
|
Map_QM.startRender();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} pathShopList() 指定路径导航
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 根据传入的店铺编号列表绘制导航路径
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Array} shopList 路径的店铺编号数组
|
|
* @apiParam {Function} callBackFun 回调函数
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.pathShopList(["L1-1","L1-5","L1-8","L1-10","LA-13"],()=>{});
|
|
*
|
|
*/
|
|
pathShopList: function (shopList, callBackFun) {
|
|
if (!shopList || shopList.length < 2) {
|
|
return { direction: "", wayList: [] };
|
|
}
|
|
let pathList = shopList.map(Map_QM.getPathNodeByHousenumber);
|
|
Map_QM.pathList(pathList, callBackFun);
|
|
},
|
|
/**
|
|
* 获取导航点
|
|
*/
|
|
getPathNodeByHousenumber: function (houseNumber) {
|
|
for (let h = 0; h < Map_QM.mapArr.length; h++) {
|
|
for (let i = 0; i < Map_QM.mapArr[h].length; i++) {
|
|
let shopArr = Map_QM.mapArr[h][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (
|
|
shopArr[k].name == houseNumber &&
|
|
parseInt(shopArr[k].node) >= 0
|
|
) {
|
|
return {
|
|
build: h,
|
|
floor: i,
|
|
path: h + "_" + i + "_" + shopArr[k].node,
|
|
node: shopArr[k].node,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
getPathNodeByNode: function (nodeObj) {
|
|
let build = nodeObj.buildOrder || 0;
|
|
let floor = nodeObj.floorOrder || 0;
|
|
let node = parseInt(nodeObj.node);
|
|
if (isNaN(node)) {
|
|
return null;
|
|
} else {
|
|
return {
|
|
build: build,
|
|
floor: floor,
|
|
path: build + "_" + floor + "_" + node,
|
|
node: node,
|
|
};
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} pathShopList() 指定路径导航
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 根据传入的店铺编号列表绘制导航路径
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Array} shopList 路径的店铺编号数组
|
|
* @apiParam {Function} callBackFun 回调函数
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* [{buildOrder:0,floorOrder:0,node:8},{buildOrder:0,floorOrder:0,node:13},{buildOrder:0,floorOrder:0,node:16},{buildOrder:0,floorOrder:0,node:20}],()=>{}
|
|
*/
|
|
pathNodeList: function (nodeList, callBackFun, isShowNo = true) {
|
|
Map_QM.elementDestroy("map_no", true);
|
|
if (!nodeList || nodeList.length < 2) {
|
|
return { direction: "", wayList: [] };
|
|
}
|
|
Map_QM.selectShop = null;
|
|
Map_QM.util.pathStateObj.isPathState = true;
|
|
let pathList = nodeList.map(Map_QM.getPathNodeByNode);
|
|
Map_QM.pathList(pathList, callBackFun, isShowNo);
|
|
},
|
|
pathList: function (pathList, callBackFun, isShowNo = false) {
|
|
Map_QM.util.isMorePath = true;
|
|
Map_QM.clearFloor(Map_QM.util.selectFloor || -1);
|
|
pathCameraState = Map_QM.util.options.pathStyle;
|
|
Map_QM.selectShop = null;
|
|
Map_QM.util.pathStateObj.isPathState = true;
|
|
Map_QM.cancelRender();
|
|
let startNode,
|
|
endNode,
|
|
isFrist = true,
|
|
PathPoint = [];
|
|
try {
|
|
let index = 0,
|
|
findIndex = 0,
|
|
pathNodes = [];
|
|
pathList.forEach((item, inx) => {
|
|
if (isShowNo) {
|
|
//显示序号
|
|
let pathN =Map_QM.util.allMap[parseInt(item.build)].buildArr[parseInt(item.floor)].mapData.path.nodes;
|
|
pathN.sort(Map_QM.util.sortNode);
|
|
let labelDiv = document.createElement("div");
|
|
labelDiv.className = "map_no";
|
|
labelDiv.innerText = inx + 1;
|
|
let img = document.createElement("img");
|
|
img.src = "../static/img/arrowBlack.svg";
|
|
labelDiv.appendChild(img);
|
|
let shopLabel = new THREE.CSS2DObject(labelDiv);
|
|
shopLabel.position.set(pathN[parseInt(item.node)].x,-1 * pathN[parseInt(item.node)].y,30);
|
|
shopLabel.applyMatrix4(Map_QM.mapArr[parseInt(item.build)][parseInt(item.floor)].allObj.matrix);
|
|
shopLabel.userData.type = "map_no";
|
|
shopLabel.userData.index = inx;
|
|
shopLabel.userData.mapShow = true;
|
|
shopLabel.userData.isShow = false; //切换楼层默认不显示,且不参与碰撞检测
|
|
Map_QM.CSSObject.add(shopLabel);
|
|
}
|
|
|
|
if (startNode && startNode.path) {
|
|
endNode = item;
|
|
if (endNode && endNode.path) {
|
|
let iNodes =
|
|
Map_QM.util.allMap[parseInt(endNode.build)].buildArr[parseInt(endNode.floor)].mapData.path.nodes;
|
|
iNodes.sort(Map_QM.util.sortNode);
|
|
Map_QM.util.overObj.build = endNode.build;
|
|
Map_QM.util.overObj.floor = endNode.floor;
|
|
Map_QM.util.overObj.node = endNode.node;
|
|
Map_QM.util.overObj.xaxis = iNodes[parseInt(endNode.node)].x;
|
|
Map_QM.util.overObj.yaxis = iNodes[parseInt(endNode.node)].y;
|
|
Map_QM.util.overObj.angle = 0;
|
|
let pathNode = dijkstra.find_path(Map_QM.util.pathStateObj.graphPath,startNode.path,endNode.path).nodes;
|
|
if (pathNode.length > 1) {
|
|
let pathData;
|
|
for (let j = 0; j < pathNode.length; j++) {
|
|
let array = pathNode[j].split("_");
|
|
if (j == 0 && isFrist) {
|
|
pathNodes.push({build: parseInt(array[0]),floor: parseInt(array[1]),pathNode: []});
|
|
}
|
|
pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path;
|
|
pathData.nodes.sort(Map_QM.util.sortNode);
|
|
if (array[0] == pathNodes[index].build) {
|
|
if (array[1] == pathNodes[index].floor) {
|
|
if (!pathNodes[index].pathNode[findIndex]) {
|
|
pathNodes[index].pathNode[findIndex] = [];
|
|
}
|
|
pathNodes[index].pathNode[findIndex].push(pathData.nodes[parseInt(array[2])]);
|
|
} else {
|
|
if (j > 0) {
|
|
pathNodes[index].Facilities = this.getFacilIcon(pathNode[j - 1].split("_"),parseInt(array[0]));
|
|
} else {
|
|
pathNodes[index].Facilities = null;
|
|
}
|
|
pathNodes.push({build: parseInt(array[0]),floor: parseInt(array[1]),pathNode: [],});
|
|
index++;
|
|
findIndex = 0;
|
|
if (!pathNodes[index].pathNode[findIndex]) {
|
|
pathNodes[index].pathNode[findIndex] = [];
|
|
}
|
|
pathNodes[index].pathNode[findIndex].push(pathData.nodes[parseInt(array[2])]);
|
|
}
|
|
} else {
|
|
pathNodes.push({ build: parseInt(array[0]),floor: parseInt(array[1]),pathNode: []});
|
|
index++;
|
|
findIndex = 0;
|
|
if (!pathNodes[index].pathNode[findIndex]) {
|
|
pathNodes[index].pathNode[findIndex] = [];
|
|
}
|
|
pathNodes[index].pathNode[findIndex].push(
|
|
pathData.nodes[parseInt(array[2])]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
if (isFrist) {
|
|
isFrist = false;
|
|
} else {
|
|
pathNode.shift();
|
|
}
|
|
PathPoint.push(...pathNode);
|
|
startNode = endNode;
|
|
findIndex++;
|
|
}
|
|
} else {
|
|
startNode = item;
|
|
Map_QM.changeStartPoint({
|
|
build: startNode.build,
|
|
floor: startNode.floor,
|
|
node: startNode.node,
|
|
angle: 0,
|
|
});
|
|
}
|
|
});
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
return;
|
|
}
|
|
Map_QM.forShopArr.length = 0;
|
|
Map_QM.util._indexPathFloor = 0;
|
|
Map_QM.util.pathStateObj.isPathPlay = true;
|
|
Map_QM.forShopListPath(PathPoint); //传入所有导航点
|
|
if (callBackFun) {
|
|
Map_QM.parseForShopArr();
|
|
const data = JSON.parse(
|
|
JSON.stringify(Map_QM.util.pathStateObj.forShopArr)
|
|
);
|
|
callBackFun(data);
|
|
}
|
|
Map_QM.startRender();
|
|
pathNodeList = null;
|
|
},
|
|
|
|
forShopListPath: function (PathPoint) {
|
|
let index = 0;
|
|
this.forShopArr = [];
|
|
if (PathPoint.length > 1) {
|
|
let pathData;
|
|
for (let j = 0; j < PathPoint.length; j++) {
|
|
let array = PathPoint[j].split("_");
|
|
if (j == 0) {
|
|
this.forShopArr.push({
|
|
build: parseInt(array[0]),
|
|
floor: parseInt(array[1]),
|
|
PathPoint: [],
|
|
});
|
|
}
|
|
pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path;
|
|
pathData.nodes.sort(Map_QM.util.sortNode);
|
|
if (array[0] == this.forShopArr[index].build) {
|
|
if (array[1] == this.forShopArr[index].floor) {
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
} else {
|
|
if (j > 0) {
|
|
this.forShopArr[index].Facilities = this.getFacilIcon(PathPoint[j - 1].split("_"),parseInt(array[0]));
|
|
} else {
|
|
this.forShopArr[index].Facilities = null;
|
|
}
|
|
this.forShopArr.push({build: parseInt(array[0]),floor: parseInt(array[1]),PathPoint: []});
|
|
index++;
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
}
|
|
} else {
|
|
this.forShopArr.push({ build: parseInt(array[0]), floor: parseInt(array[1]), PathPoint: []});
|
|
index++;
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
}
|
|
}
|
|
if (Map_QM.forShopArr.length > 0) {
|
|
// "floor" PathPoint Direction (Facilities)
|
|
for (let m = 0; m < Map_QM.forShopArr.length; m++) {
|
|
//查找经过店铺
|
|
Map_QM.forShopArr[m].wayShop = Map_QM.foreignShop(
|
|
Map_QM.forShopArr[m].PathPoint,
|
|
Map_QM.forShopArr[m].build,
|
|
Map_QM.forShopArr[m].floor,
|
|
m
|
|
);
|
|
if (Map_QM.util.overObj.build == Map_QM.forShopArr[m].build &&Map_QM.util.overObj.floor == Map_QM.forShopArr[m].floor) {
|
|
let len = Map_QM.forShopArr[m].wayShop.length;
|
|
if (Map_QM.forShopArr[m].wayShop[len - 1] && Map_QM.forShopArr[m].wayShop[len - 1].shop.yaxis == Map_QM.util.overObj.node) {
|
|
Map_QM.forShopArr[m].wayShop.pop();
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
console.error("无可行路径");
|
|
return;
|
|
}
|
|
this.onFindPathToObj();
|
|
}
|
|
pathNodeList = null;
|
|
},
|
|
|
|
parseForShopArr: function () {
|
|
Map_QM.util.pathStateObj.forShopArr = { direction: "", wayList: [] };
|
|
Map_QM.forShopArr.forEach((item, index) => {
|
|
if (item.hasOwnProperty("Direction")) {
|
|
Map_QM.util.pathStateObj.forShopArr.direction = item.Direction;
|
|
Map_QM.util.pathStateObj.forShopArr.directionEn = item.DirectionEn;
|
|
}
|
|
if (item.hasOwnProperty("wayShop") && item.wayShop) {
|
|
for (let i = 0; i < item.wayShop.length; i++) {
|
|
let enTlite = item.wayShop[i].shop.shopNameEn == "" ? item.wayShop[i].shop.shopName : item.wayShop[i].shop.shopNameEn;
|
|
Map_QM.util.pathStateObj.forShopArr.wayList.push({
|
|
isAddPrefix: false,
|
|
shopName: "经过 " + item.wayShop[i].shop.shopName || item.wayShop[i].shop.name,
|
|
shopNameEn: "PASS " + enTlite,
|
|
logoUrl: item.wayShop[i].shop.logoPath || item.wayShop[i].shop.logoUrl,
|
|
shopCode: item.wayShop[i].shop.shopCode,
|
|
houseNumber: item.wayShop[i].shop.houseNumber,
|
|
});
|
|
}
|
|
}
|
|
if (item.hasOwnProperty("Facilities") && item.Facilities) {
|
|
//设施
|
|
Map_QM.util.pathStateObj.forShopArr.wayList.push({
|
|
isAddPrefix: true,
|
|
shopName: "乘坐 " + item.Facilities.userData.title +"到 " + Map_QM.mapArr[parseInt(Map_QM.forShopArr[index + 1].build)][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName,
|
|
shopNameEn:"BY " +item.Facilities.userData.title +"TO " + Map_QM.mapArr[parseInt(Map_QM.forShopArr[index + 1].build)][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName,
|
|
logoUrl: item.Facilities.imgUrl,
|
|
shopCode: ((Math.random() * 0x1234567) | 0).toString(16).substring(0),
|
|
houseNumber:item.Facilities.userData.facCode + item.Facilities.userData.no,
|
|
});
|
|
}
|
|
});
|
|
},
|
|
/**
|
|
* @api {方法} getGapByPathNode() 获取实际距离
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 通过点位获取距离
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {int} floor 楼层编号
|
|
* @apiParam {string} node 路径点位编号
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.getGapByPathNode({floor:2,node:"53"});
|
|
*
|
|
* @apiSuccessExample {Object} dist 距离米数 time 步行时间
|
|
* {
|
|
* dis:200,time:4
|
|
* }
|
|
*/
|
|
getGapByPathNode: function (toObj) {
|
|
let startNade = Map_QM.util.deviceObj.build +"_" + Map_QM.util.deviceObj.floor + "_" + Map_QM.util.deviceObj.node;
|
|
let toNade = toObj.build + "_" + toObj.floor + "_" + toObj.node;
|
|
let path = { cost: -1 },
|
|
minTime = 1;
|
|
try {
|
|
path = dijkstra.find_path( Map_QM.util.pathStateObj.basePath,startNade,toNade);
|
|
minTime = parseInt(path.cost / Map_QM.util.options.mapScale / 50) < 0.5? 0.5 : parseInt(path.cost / Map_QM.util.options.mapScale / 50);
|
|
console.log(`距离目的地 ${parseInt(path.cost / Map_QM.util.options.mapScale)} 米,预计${minTime} 分钟`); // 21 是比例尺
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
}
|
|
return {
|
|
dis: parseInt(path.cost / Map_QM.util.options.mapScale),
|
|
time: minTime,
|
|
};
|
|
},
|
|
/**
|
|
* @api {方法} pathPark() 获取车位点位
|
|
* @apiGroup 地图数据
|
|
* @apiDescription 获取车位导航点
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} houseNumber 车位编号
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.pathPark({houseNumber:"B1002"});
|
|
*
|
|
* @apiSuccessExample 返回示例
|
|
* {
|
|
* houseNumber: 车位编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标
|
|
* }
|
|
*/
|
|
pathPark: function (toObj) {
|
|
return this.shopNumToNavPoint(toObj, "park");
|
|
},
|
|
|
|
/**
|
|
* @api {方法} pathShopByName() 获取店铺点位
|
|
* @apiGroup 地图数据
|
|
* @apiDescription 通过店铺名称获取点位
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} shopName 店铺名称
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.pathShopByName("金拱门");
|
|
*
|
|
* @apiSuccessExample 返回示例
|
|
* {
|
|
* houseNumber: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点
|
|
* }
|
|
*/
|
|
pathShopByName: function (shopName) {
|
|
for (let item of Map_QM.util.shopData) {
|
|
if (item.name === shopName) {
|
|
let toObj = { houseNumber: item.houseNumber, node: item.yaxis };
|
|
for (let h = 0; h < Map_QM.util.allMap.length; h++) {
|
|
let sArr = Map_QM.util.allMap[h].buildArr;
|
|
for (let i = 0; i < sArr.length; i++) {
|
|
let shops = Map_QM.util.allMap[h].buildArr[i].mapData.shopArea;
|
|
for (let k = 0; k < shops.length; k++) {
|
|
if (shops[k].name == toObj.houseNumber) {
|
|
toObj.floor = i;
|
|
toObj.build = h;
|
|
toObj.node = shops[k].shopNav;
|
|
toObj.xaxis = shops[k].xaxis;
|
|
toObj.yaxis = shops[k].yaxis;
|
|
if (shops[k].comeIn) {
|
|
toObj.comeIn = shops[k].comeIn;
|
|
}
|
|
return toObj;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return toObj;
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* @api {方法} changeBoxStateByFormat() 切换box显示状态
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 根据业态切换box显示状态
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} formatCode 业态Id
|
|
* @apiParam {Boolean} isShow 是否显示
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {Object} 请求示例
|
|
*
|
|
* Map_QM.changeBoxStateByFormat("X8f1sfGl0gfa_QwVcMy86",false);
|
|
*
|
|
*/
|
|
changeBoxStateByFormat: function (formatCode, isShow) {
|
|
for (let h = 0; h < Map_QM.mapArr.length; h++) {
|
|
for (let i = 0; i < Map_QM.mapArr[h].length; i++) {
|
|
let shopArr = Map_QM.mapArr[h][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (
|
|
shopArr[k].userData &&
|
|
shopArr[k].userData.formatCode == formatCode
|
|
) {
|
|
shopArr[k].visible = isShow;
|
|
}
|
|
}
|
|
Map_QM.mapArr[h][i].labelObj.traverse((obj) => {
|
|
if (obj.element && obj.userData.formatCode == formatCode) {
|
|
obj.element.style.display = isShow ? "" : "none";
|
|
obj.userData.isShow = isShow;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
Map_QM.updateRender();
|
|
Map_QM.collLabel();
|
|
},
|
|
/**
|
|
* @api {方法} changeBoxStateByName() 切换box显示状态
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 根据名称切换box显示状态
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {String} houseNumber box名称
|
|
* @apiParam {Boolean} isShow 是否显示
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample {Object} 请求示例
|
|
*
|
|
* Map_QM.changeBoxStateByName("L101", true);
|
|
*
|
|
*/
|
|
changeBoxStateByName: function (houseNumber, isShow) {
|
|
for (let h = 0; h < Map_QM.mapArr.length; h++) {
|
|
for (let i = 0; i < Map_QM.mapArr[h].length; i++) {
|
|
let shopArr = Map_QM.mapArr[h][i].shopObj.children;
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (shopArr[k].name == houseNumber) {
|
|
shopArr[k].visible = isShow;
|
|
}
|
|
}
|
|
Map_QM.mapArr[h][i].labelObj.traverse((obj) => {
|
|
if (obj.name == houseNumber) {
|
|
obj.element.style.display = isShow ? "" : "none";
|
|
obj.userData.isShow = isShow;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
Map_QM.updateRender();
|
|
Map_QM.collLabel();
|
|
},
|
|
/**
|
|
* @api {方法} shopNumToNavPoint() 获取导航点位
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 通过店铺编号或车位获取导航点位
|
|
* @apiVersion 4.0.0
|
|
* @apiParam {Object} object build,floor,houseNumber 楼栋编号,楼层编号,店铺或车位编号
|
|
* @apiParam {String} type 店铺或车位标识 "shop" "park"
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiSuccessExample 返回示例
|
|
* {
|
|
* houseNumber: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点
|
|
* }
|
|
*/
|
|
shopNumToNavPoint: function (obj, type) {
|
|
let shopArr;
|
|
let reObj = {
|
|
build: Map_QM.util.selectBuild,
|
|
node: "",
|
|
xaxis: "",
|
|
yaxis: "",
|
|
floor: "",
|
|
comeIn: "",
|
|
};
|
|
for (let h = 0; h < Map_QM.util.allMap.length; h++) {
|
|
let sArr = Map_QM.util.allMap[h].buildArr;
|
|
for (let i = 0; i < sArr.length; i++) {
|
|
if (type == "shop") {
|
|
shopArr = sArr[i].mapData.shopArea;
|
|
} else if (type == "park") {
|
|
shopArr = sArr[i].mapData.parkArea;
|
|
}
|
|
for (let k = 0; k < shopArr.length; k++) {
|
|
if (shopArr[k].name == obj.houseNumber) {
|
|
reObj.floor = i;
|
|
reObj.build = h;
|
|
reObj.xaxis = shopArr[k].xaxis;
|
|
reObj.yaxis = shopArr[k].yaxis;
|
|
reObj.node = shopArr[k].shopNav;
|
|
reObj.houseNumber = obj.houseNumber;
|
|
if (shopArr[k].comeIn) {
|
|
reObj.comeIn = shopArr[k].comeIn;
|
|
}
|
|
return reObj;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* 模拟导航获取路线
|
|
*/
|
|
onFindPathModel: function (usePath = null) {
|
|
Map_QM.forShopArr.length = 0;
|
|
Map_QM.util._indexPathFloor = 0;
|
|
Map_QM.util.pathStateObj.isPathPlay = true;
|
|
if (isNaN(parseInt(Map_QM.util.startObj.node)) ||parseInt(Map_QM.util.startObj.node) == -1) {
|
|
return;
|
|
}
|
|
try {
|
|
if (!Map_QM.util.startObj.xaxis) {
|
|
let pathData = Map_QM.util.allMap[parseInt(Map_QM.util.startObj.build)].buildArr[parseInt(Map_QM.util.startObj.floor)].mapData.path;
|
|
Map_QM.util.startObj.xaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].x;
|
|
Map_QM.util.startObj.yaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].y;
|
|
}
|
|
if (!usePath) {
|
|
usePath = Map_QM.util.pathStateObj.graphPath;
|
|
}
|
|
if (Map_QM.util.overObj.comeIn) {
|
|
const costall = dijkstra.single_source_shortest_paths( Map_QM.util.pathStateObj.graphPath, startNade,startNade).costs;
|
|
if (costall) {
|
|
let inArray = Map_QM.util.overObj.comeIn.split(",");
|
|
Map_QM.util.overObj.node = Map_QM.getMinCostByArray( Map_QM.util.overObj.floor,inArray, costall);
|
|
}
|
|
}
|
|
let startNade =
|
|
Map_QM.util.startObj.build + "_" + Map_QM.util.startObj.floor + "_" + Map_QM.util.startObj.node;
|
|
let toNade = Map_QM.util.overObj.build + "_" + Map_QM.util.overObj.floor + "_" + Map_QM.util.overObj.node;
|
|
let path = dijkstra.find_path(usePath, startNade, toNade);
|
|
Map_QM.forShopPath(path.nodes);
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log(e);
|
|
return;
|
|
}
|
|
},
|
|
forShopPath: function (PathPoint) {
|
|
let Dir = "向前出发",
|
|
index = 0;
|
|
let DirEn = "to forward";
|
|
this.forShopArr = [];
|
|
if (PathPoint.length > 1) {
|
|
this.forShopArr.push({
|
|
build: Map_QM.util.startObj.build,
|
|
floor: Map_QM.util.startObj.floor,
|
|
PathPoint: [],
|
|
});
|
|
let pathData;
|
|
for (let j = 0; j < PathPoint.length; j++) {
|
|
let array = PathPoint[j].split("_");
|
|
pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path;
|
|
if (array[0] == this.forShopArr[index].build) {
|
|
if (array[1] == this.forShopArr[index].floor) {
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
} else {
|
|
if (j > 0) {
|
|
this.forShopArr[index].Facilities = this.getFacilIcon( PathPoint[j - 1].split("_"),parseInt(array[0]));
|
|
} else {
|
|
this.forShopArr[index].Facilities = null;
|
|
}
|
|
this.forShopArr.push({
|
|
build: parseInt(array[0]),
|
|
floor: parseInt(array[1]),
|
|
PathPoint: []
|
|
});
|
|
index++;
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
}
|
|
} else {
|
|
this.forShopArr.push({
|
|
build: parseInt(array[0]),
|
|
floor: parseInt(array[1]),
|
|
PathPoint: []
|
|
});
|
|
index++;
|
|
this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
|
|
}
|
|
}
|
|
let dy = 0,
|
|
dx = 0,
|
|
ang = 0;
|
|
if (this.forShopArr[0].PathPoint.length > 1) {
|
|
if (this.forShopArr[0].PathPoint.length == 2) {
|
|
dy = this.forShopArr[0].PathPoint[1].y - this.forShopArr[0].PathPoint[0].y;
|
|
dx = this.forShopArr[0].PathPoint[1].x - this.forShopArr[0].PathPoint[0].x;
|
|
} else {
|
|
dy = this.forShopArr[0].PathPoint[2].y - this.forShopArr[0].PathPoint[1].y;
|
|
dx = this.forShopArr[0].PathPoint[2].x -this.forShopArr[0].PathPoint[1].x;
|
|
}
|
|
ang = (Math.atan2(dy, dx) * 180) / Math.PI - Map_QM.util.deviceObj.angle;
|
|
ang = ang > 180 ? ang - 360 : ang;
|
|
ang = ang < -180 ? ang + 360 : ang;
|
|
|
|
if (ang < -50 && ang >= -130) {
|
|
Dir = "向前出发";
|
|
DirEn = "to forward";
|
|
} else if (ang >= -50 && ang < 50) {
|
|
Dir = "向右出发";
|
|
DirEn = "to right";
|
|
} else if (ang >= 50 && ang < 130) {
|
|
Dir = "向后出发";
|
|
DirEn = "to back";
|
|
} else {
|
|
Dir = "向左出发";
|
|
DirEn = "to left";
|
|
}
|
|
}
|
|
let pLen = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint.length;
|
|
Map_QM.util.overObj.xaxis = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint[pLen - 1].x;
|
|
Map_QM.util.overObj.yaxis = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint[pLen - 1].y;
|
|
|
|
if (Map_QM.forShopArr.length > 0) {
|
|
// "floor" PathPoint Direction (Facilities)
|
|
Map_QM.forShopArr[0].Direction = Dir;
|
|
Map_QM.forShopArr[0].DirectionEn = DirEn;
|
|
|
|
for (let m = 0; m < Map_QM.forShopArr.length; m++) {
|
|
//查找经过店铺
|
|
Map_QM.forShopArr[m].wayShop = Map_QM.foreignShop(
|
|
Map_QM.forShopArr[m].PathPoint,
|
|
Map_QM.forShopArr[m].build,
|
|
Map_QM.forShopArr[m].floor,
|
|
m
|
|
);
|
|
if (Map_QM.util.overObj.build == Map_QM.forShopArr[m].build && Map_QM.util.overObj.floor == Map_QM.forShopArr[m].floor ) {
|
|
let len = Map_QM.forShopArr[m].wayShop.length;
|
|
if (Map_QM.forShopArr[m].wayShop[len - 1] &&Map_QM.forShopArr[m].wayShop[len - 1].shop.yaxis == Map_QM.util.overObj.node) {
|
|
Map_QM.forShopArr[m].wayShop.pop();
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* @api {事件} InitPathOver 地图导航状态完成
|
|
* @apiGroup 地图事件
|
|
* @apiDescription 地图开始导航时触发
|
|
* @apiVersion 4.0.0
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* Map_QM.addEventListener("InitPathOver",onInitPathOver,false);
|
|
*/
|
|
Map_QM.dispatchEvent({
|
|
type: "InitPathOver",
|
|
data: Map_QM.forShopArr,
|
|
});
|
|
} else {
|
|
console.error("无可行路径,请检查起、终点位");
|
|
return;
|
|
}
|
|
this.onFindPathToObj();
|
|
}
|
|
},
|
|
getMinCostByArray: function (floor, array, costall) {
|
|
if (!Map_QM.util.startObj) {
|
|
Map_QM.changeStartPoint();
|
|
}
|
|
if (!Map_QM.util.numBuild) {
|
|
Map_QM.util.numBuild = 0;
|
|
}
|
|
let mis = -1,
|
|
nodeP;
|
|
for (let i = 0; i < array.length; i++) {
|
|
let toNade = Map_QM.util.numBuild + "_" + floor + "_" + array[i];
|
|
let PathPoint = costall[toNade];
|
|
if (mis == -1) {
|
|
mis = PathPoint;
|
|
nodeP = array[i];
|
|
} else {
|
|
if (mis > PathPoint) {
|
|
mis = PathPoint;
|
|
nodeP = array[i];
|
|
}
|
|
}
|
|
}
|
|
return nodeP;
|
|
},
|
|
/**
|
|
* 途径店铺
|
|
*/
|
|
foreignShop: function (pathArr, build, cFloor, m) {
|
|
let shopList = [];
|
|
let shops =
|
|
Map_QM.mapArr[parseInt(build)][parseInt(cFloor)].shopObj.children;
|
|
for (let n = 0; n < pathArr.length; n++) {
|
|
for (let i = 0; i < shops.length; i++) {
|
|
if (shops[i].userData && shops[i].userData.type == "shop" && shops[i].userData.navRecommend) {
|
|
if (shops[i].userData.node == pathArr[n].id &&shops[i].userData.shopData) {
|
|
let data = {
|
|
pathArrIn: m,
|
|
pathIndex: n,
|
|
shop: shops[i].userData.shopData
|
|
};
|
|
shopList.push(data);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return shopList;
|
|
},
|
|
getFacilIcon: function (fromFArr, build = -1) {
|
|
if (build === -1) {
|
|
build = Map_QM.util.selectBuild;
|
|
}
|
|
let childs = this.mapArr[build][fromFArr[1]].serObj.children;
|
|
let selectEle;
|
|
for (let i = 0; i < childs.length; i++) {
|
|
if (childs[i].type == "Object3D" &&childs[i].userData.navCode == fromFArr[2] &&"dt,ft,upft,lt,downft".search(childs[i].userData.facCode) != -1 ) {
|
|
selectEle = {
|
|
imgUrl: childs[i].userData.src,
|
|
userData: childs[i].userData,
|
|
position: { x: childs[i].position.x, y: childs[i].position.y }
|
|
};
|
|
break;
|
|
}
|
|
}
|
|
return selectEle;
|
|
},
|
|
|
|
/**
|
|
* 寻路动画方法
|
|
*/
|
|
onFindPathToObj: function () {
|
|
Map_QM.util._indexPathFloor = 0;
|
|
Map_QM.callBackLoadOver = Map_QM.callBackForPathShop; //楼层初始化完成后回调
|
|
if (pathCameraState == "2D") {
|
|
Map_QM.onShowMeDir();
|
|
Map_QM.controls.enabled = false;
|
|
Map_QM.guide = Map_QM.man_2d;
|
|
}
|
|
Map_QM.changeBuildInner( Map_QM.forShopArr[Map_QM.util._indexPathFloor].build,Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor);
|
|
},
|
|
/**
|
|
* 播放楼层动画完成后
|
|
*/
|
|
callBackForPathShop: function () {
|
|
Map_QM.callBackLoadOver = null;
|
|
if (Map_QM.util.pathStateObj.isPathState) {
|
|
//如果是寻路状态,继续导航
|
|
Map_QM.onFindPath();
|
|
}
|
|
},
|
|
/**
|
|
* 寻路方法
|
|
* @param {Object} startN
|
|
* @param {Object} endN
|
|
*/
|
|
onFindPath: function () {
|
|
TweenMax.killAll(true);
|
|
if (Map_QM.util.overObj.floor == Map_QM.util.selectFloor && Map_QM.util.overObj.xaxis) {
|
|
Map_QM.mapArr[Map_QM.util.overObj.build][Map_QM.util.overObj.floor].setOverSite(Map_QM.util.overObj.xaxis, Map_QM.util.overObj.yaxis,parseInt(Map_QM.util.shopHeight));
|
|
} else {
|
|
Map_QM.endModel && (Map_QM.endModel.visible = false);
|
|
Map_QM.endIcon && (Map_QM.endIcon.visible = false);
|
|
}
|
|
if (Map_QM.forShopArr.length > 0) {
|
|
document.addEventListener("pathOver", Map_QM.onFindPathFloor, true);
|
|
if (Map_QM.util.isMorePath) {
|
|
Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.onFindPathAnimation(pathNodes[Map_QM.util._indexPathFloor].pathNode, Map_QM.util.isMorePath,pathNodes[Map_QM.util._indexPathFloor].floor); //传入数组
|
|
} else {
|
|
Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.clearPath();
|
|
Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.onFindPathAnimation(Map_QM.forShopArr[Map_QM.util._indexPathFloor].PathPoint,false ); //传入数组
|
|
}
|
|
Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.guidePathPlay(Map_QM.forShopArr[Map_QM.util._indexPathFloor]);
|
|
Map_QM.controlsChock();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 显示楼层
|
|
*/
|
|
showNavFloor: function (fromFloor, toFloor, build) {
|
|
let floorArr = [];
|
|
let min = Math.min(fromFloor, toFloor);
|
|
let max = Math.max(fromFloor, toFloor);
|
|
for (let i = min; i <= max; i++) {
|
|
floorArr.push(Map_QM.mapArr[build][i].floorName);
|
|
}
|
|
if (floorArr.length > 5) {
|
|
floorArr.splice(2, floorArr.length - 3);
|
|
floorArr[1] = "...";
|
|
}
|
|
return floorArr;
|
|
},
|
|
|
|
//导航完成事件
|
|
onFindPathFloor: function (event) {
|
|
document.removeEventListener("pathOver", Map_QM.onFindPathFloor);
|
|
if (Map_QM.forShopArr.length <= Map_QM.util._indexPathFloor) {
|
|
return;
|
|
}
|
|
if (Map_QM.util._indexPathFloor < Map_QM.forShopArr.length - 1) {
|
|
//楼层切换
|
|
if (Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities) {
|
|
let pathFloor = Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor;
|
|
let x0 =Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.position.x +64;
|
|
let y0 = Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.position.y;
|
|
let model = Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.model;
|
|
/**
|
|
* @api {事件} PathPlaying 地图导航的实时状态
|
|
* @apiGroup 地图事件
|
|
* @apiDescription 地图导航过程中实时触发
|
|
* @apiVersion 4.0.0
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* Map_QM.addEventListener("PathPlaying",onPathPlaying,false);
|
|
*/
|
|
Map_QM.dispatchEvent({
|
|
//寻路中返回小人当前所在点位
|
|
type: "PathPlaying",
|
|
data: {
|
|
houseNumber:Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.facCode + Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.no,
|
|
},
|
|
});
|
|
let box;
|
|
if (model && model.userData.name == "dt") {
|
|
model.traverse(function (child) {
|
|
if (child.isMesh && child.name == "zhitibox") {
|
|
box = child;
|
|
}
|
|
if (child.isMesh && (child.name == "zhitijiegou" || child.name == "zhitiboli")) {
|
|
child.scale.y = 3;
|
|
}
|
|
});
|
|
}
|
|
|
|
let zo = 2,
|
|
tz = 2,
|
|
boxT = 0,
|
|
boxZ = 0;
|
|
let add = window.innerWidth > 2000 ? 80 : 40;
|
|
let lft = window.innerWidth > 2000 ? 8 : 4;
|
|
Map_QM.util._indexPathFloor++;
|
|
let toFloor = parseInt(
|
|
Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor
|
|
);
|
|
Map_QM.util.selectFloor = toFloor;
|
|
let floorArr = Map_QM.showNavFloor(
|
|
pathFloor,
|
|
toFloor,
|
|
parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)
|
|
); //电梯旁显示的楼层名称
|
|
if (pathFloor < toFloor) {
|
|
tz = (floorArr.length - 1) * add;
|
|
boxT = 12;
|
|
} else {
|
|
zo = (floorArr.length - 1) * add;
|
|
boxZ = 12;
|
|
}
|
|
|
|
document.getElementById("moveFloor").style.bottom = zo + "px";
|
|
document.getElementById("moveFloor").style.width = add + "px";
|
|
document.getElementById("moveFloor").style.height = add + "px";
|
|
|
|
Map_QM.moveFloorbg.element.style.width = add + lft + "px";
|
|
Map_QM.moveFloorbg.element.style.height = floorArr.length * add + "px";
|
|
Map_QM.moveFloorbg.position.set(x0, y0, (floorArr.length * add) / -1);
|
|
Map_QM.moveFloorbg.applyMatrix4(
|
|
Map_QM.mapArr[
|
|
parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)
|
|
][pathFloor].allObj.matrix
|
|
);
|
|
let floorBox = document.getElementById("floorBox");
|
|
while (floorBox.hasChildNodes()) {
|
|
floorBox.removeChild(floorBox.firstChild);
|
|
}
|
|
for (let i = floorArr.length - 1; i >= 0; i--) {
|
|
let span2 = document.createElement("span");
|
|
span2.style.cssText = "display: block;color: #000000; text-align: center;";
|
|
span2.style.fontSize = "16px";
|
|
if (window.innerWidth > 2000) {
|
|
span2.style.fontSize = "24px";
|
|
}
|
|
span2.style.width = add + lft + "px";
|
|
span2.style.height = add + "px";
|
|
span2.style.lineHeight = add + "px";
|
|
span2.innerText = floorArr[i];
|
|
floorBox.appendChild(span2);
|
|
}
|
|
|
|
TweenMax.fromTo("#moveFloor",1.5,{ bottom: zo },
|
|
{
|
|
bottom: tz,
|
|
delay: 0.1,
|
|
onComplete: function () {
|
|
Map_QM.moveFloorbg.element.style.display = "none";
|
|
Map_QM.callBackLoadOver = Map_QM.callBackForPathShop; //楼层初始化完成后回调
|
|
Map_QM.changeFloorInner(
|
|
Map_QM.forShopArr[Map_QM.util._indexPathFloor].build,
|
|
Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor
|
|
);
|
|
},
|
|
}
|
|
);
|
|
Map_QM.moveFloorbg.element.style.display = "block";
|
|
if (box) {
|
|
TweenMax.fromTo(box.position, 1.2, { y: boxZ },
|
|
{ y: boxT, delay: 0.2,
|
|
onComplete: function () {
|
|
box.position.y = 0;
|
|
model.traverse(function (child) {
|
|
if (
|
|
child.isMesh &&
|
|
(child.name == "zhitijiegou" || child.name == "zhitiboli")
|
|
) {
|
|
child.scale.y = 1;
|
|
}
|
|
});
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
if (pathCameraState == "3D") {
|
|
let xt = Map_QM.guide.position.x + event.detail.dx * 10;
|
|
let yt = Map_QM.guide.position.y + event.detail.dy * 10;
|
|
if (model && model.userData.name == "upft") {
|
|
Map_QM.guide.visible = true;
|
|
TweenMax.to(Map_QM.guide.position, 1.3, { x: xt, y: yt, z: 50,
|
|
onComplete: function () {
|
|
Map_QM.guide.visible = false;
|
|
},
|
|
});
|
|
}
|
|
if (model && model.userData.name == "downft") {
|
|
Map_QM.guide.visible = true;
|
|
TweenMax.to(Map_QM.guide.position, 1.3, { x: xt, y: yt, z: -50,
|
|
onComplete: function () {
|
|
Map_QM.guide.visible = false;
|
|
},
|
|
});
|
|
}
|
|
}
|
|
} else {
|
|
//楼栋切换
|
|
Map_QM.util._indexPathFloor++;
|
|
Map_QM.callBackLoadOver = Map_QM.callBackForPathShop;
|
|
Map_QM.changeBuildInner(
|
|
Map_QM.forShopArr[Map_QM.util._indexPathFloor].build,
|
|
Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor
|
|
);
|
|
}
|
|
} else {
|
|
Map_QM.util.startObj = Map_QM.util.deviceObj;
|
|
/**
|
|
* @api {事件} PathPlayOver 地图导航完成
|
|
* @apiGroup 地图事件
|
|
* @apiDescription 地图导航到达目标点时触发
|
|
* @apiVersion 4.0.0
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
* Map_QM.addEventListener("PathPlayOver",onPathPlayOver,false);
|
|
*/
|
|
Map_QM.dispatchEvent({
|
|
//寻路完成
|
|
type: "PathPlayOver",
|
|
data: "PathPlayOver",
|
|
});
|
|
}
|
|
},
|
|
/**
|
|
* 楼层状态清理
|
|
*/
|
|
clearFloor: function (fIndex = -1, reSet = true) {
|
|
isJUZ = false;
|
|
if (fIndex == -1) {
|
|
fIndex = Map_QM.util.deviceObj.floor;
|
|
}
|
|
if (Map_QM.selectShop) {
|
|
Map_QM.selectShop.scale.z = 1;
|
|
}
|
|
if (Map_QM.endModel && Map_QM.endModel.visible) {
|
|
Map_QM.endModel.visible = false;
|
|
}
|
|
if (Map_QM.endIcon && Map_QM.endIcon.visible) {
|
|
Map_QM.endIcon.visible = false;
|
|
}
|
|
if (Map_QM.moveFloorbg) {
|
|
Map_QM.moveFloorbg.element.style.display = "none";
|
|
}
|
|
if (reSet) {
|
|
//叠层不处理
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.mapArr[Map_QM.util.selectBuild].length > 0) {
|
|
for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) {
|
|
let child = Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj;
|
|
for (let k = child.children.length - 1; k >= 0; k--) {
|
|
if (child.children[k].name == "lineDash") {
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.remove(child.children[k]);
|
|
}
|
|
}
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][i].findPath.clearPath();
|
|
}
|
|
}
|
|
Map_QM.remove_child(Map_QM.dtLineGroup);
|
|
}
|
|
Map_QM.removeHeatMap();
|
|
TweenMax.killAll(true);
|
|
},
|
|
|
|
remove_child: function (remObj) {
|
|
if (!remObj) {
|
|
return;
|
|
}
|
|
let child_elem = remObj.children;
|
|
for (let i = child_elem.length - 1; i >= 0; i--) {
|
|
if (child_elem[i].children.length > 0) {
|
|
Map_QM.remove_child(child_elem[i]);
|
|
} else {
|
|
if (child_elem[i] instanceof THREE.Mesh) {
|
|
child_elem[i].geometry.dispose(); // 删除几何体
|
|
if (child_elem[i].material !== undefined)
|
|
Map_QM.removeMaterial(child_elem.material); // 删除材质
|
|
}
|
|
}
|
|
if (child_elem[i].name != "light" && child_elem[i].name != "dtline") {
|
|
remObj.remove(child_elem[i]);
|
|
}
|
|
}
|
|
},
|
|
removeMaterial: function (material) {
|
|
if (Array.isArray(material)) {
|
|
for (var i = 0, l = material.length; i < l; i++) {
|
|
this.removeMaterialFromRefCounter(material[i]);
|
|
}
|
|
} else {
|
|
this.removeMaterialFromRefCounter(material);
|
|
}
|
|
},
|
|
removeMaterialFromRefCounter: function (material) {
|
|
var materialsRefCounter = this.materialsRefCounter;
|
|
if (materialsRefCounter) {
|
|
var count = materialsRefCounter.get(material);
|
|
count--;
|
|
if (count === 0) {
|
|
materialsRefCounter.delete(material);
|
|
delete this.materials[material.uuid];
|
|
} else {
|
|
materialsRefCounter.set(material, count);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} pathStop() 导航暂停/播放
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 导航动画暂停/播放
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
*/
|
|
pathStop: function (isPlaying) {
|
|
Map_QM.util.pathStateObj.isPathPlay =isPlaying === undefined? !Map_QM.util.pathStateObj.isPathPlay : isPlaying;
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.pathPlay.isPlay = Map_QM.util.pathStateObj.isPathPlay;
|
|
},
|
|
/**
|
|
* @api {方法} pathRePlay() 导航动画重播
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 导航动画重播
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
*/
|
|
pathRePlay: function () {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
TweenMax.killAll(true);
|
|
if (!Map_QM.util.overObj.node) {
|
|
return;
|
|
}
|
|
if (Map_QM.util.pathStateObj.isPathState) {
|
|
Map_QM.util.timeObj.pathTime = setTimeout(() => {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
Map_QM.controls.reset();
|
|
if (Map_QM.util.overObj && Map_QM.forShopArr[0]) {
|
|
Map_QM.util.pathStateObj.isPathPlay = true;
|
|
Map_QM.clearFloor();
|
|
Map_QM.onFindPathToObj();
|
|
}
|
|
}, 100);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @api {方法} ChangePathByFt() 切换扶梯模式
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 导航切换扶梯模式
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {function} callBack 回调函数
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.ChangePathByFt(function);
|
|
*
|
|
*/
|
|
ChangePathByFt: function (callBack) {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
TweenMax.killAll(true);
|
|
if (!Map_QM.util.overObj.node || Map_QM.util.isMorePath) {
|
|
return;
|
|
}
|
|
Map_QM.util.timeObj.pathTime = setTimeout(() => {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
Map_QM.controls.reset();
|
|
if (Map_QM.util.overObj) {
|
|
Map_QM.clearFloor();
|
|
Map_QM.onFindPathModel(Map_QM.util.pathStateObj.ftPath);
|
|
if (callBack) {
|
|
Map_QM.parseForShopArr();
|
|
const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr));
|
|
callBack(data);
|
|
}
|
|
}
|
|
}, 100);
|
|
},
|
|
/**
|
|
* @api {方法} ChangePathByDt() 切换电梯模式
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 导航切换电梯模式
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {function} callBack 回调函数
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.ChangePathByDt(function);
|
|
*
|
|
*/
|
|
ChangePathByDt: function (callBack) {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
TweenMax.killAll(true);
|
|
if (!Map_QM.util.overObj.node || Map_QM.util.isMorePath) {
|
|
return;
|
|
}
|
|
Map_QM.util.timeObj.pathTime = setTimeout(() => {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
Map_QM.controls.reset();
|
|
if (Map_QM.util.overObj) {
|
|
Map_QM.clearFloor();
|
|
Map_QM.onFindPathModel(Map_QM.util.pathStateObj.dtPath);
|
|
if (callBack) {
|
|
Map_QM.parseForShopArr();
|
|
const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr));
|
|
callBack(data);
|
|
}
|
|
}
|
|
}, 100);
|
|
},
|
|
/**
|
|
* @api {方法} ChangePathByGood() 切换最佳模式
|
|
* @apiGroup 地图导航
|
|
* @apiDescription 导航切换最佳模式
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {function} callBack 回调函数
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.ChangePathByGood(function);
|
|
*
|
|
*/
|
|
ChangePathByGood: function (callBack) {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
TweenMax.killAll(true);
|
|
if (!Map_QM.util.overObj.node || Map_QM.util.isMorePath) {
|
|
return;
|
|
}
|
|
Map_QM.util.timeObj.pathTime = setTimeout(() => {
|
|
clearTimeout(Map_QM.util.timeObj.pathTime);
|
|
Map_QM.controls.reset();
|
|
if (Map_QM.util.overObj) {
|
|
Map_QM.clearFloor();
|
|
Map_QM.onFindPathModel(Map_QM.util.pathStateObj.graphPath);
|
|
if (callBack) {
|
|
Map_QM.parseForShopArr();
|
|
const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr));
|
|
callBack(data);
|
|
}
|
|
}
|
|
}, 100);
|
|
},
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
changeDocmentResize: function (e) {
|
|
let w = parseInt(Map_QM.ele.clientWidth) || parseInt(window.getComputedStyle(Map_QM.ele, null).getPropertyValue("width"));
|
|
let h = parseInt(Map_QM.ele.clientHeight) || parseInt( window.getComputedStyle(Map_QM.ele, null).getPropertyValue("height"));
|
|
Map_QM.changeWindowResize(w, h);
|
|
},
|
|
/**
|
|
* @api {方法} changeWindowResize() 窗口变化
|
|
* @apiGroup 地图交互
|
|
* @apiDescription 窗口变化
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {int} width 窗口宽
|
|
* @apiParam {int} height 窗口高
|
|
*
|
|
* @apiSampleRequest off
|
|
*
|
|
* @apiParamExample 请求示例
|
|
*
|
|
* Map_QM.changeWindowResize(1280,1080);
|
|
*/
|
|
changeWindowResize: function (width, height) {
|
|
let h1=Map_QM.h;
|
|
if(width){
|
|
h1 = Math.floor(width/Map_QM.aspect);
|
|
}else{
|
|
width = Map_QM.w;
|
|
}
|
|
if(height && height<h1){
|
|
width = Math.floor(height*Map_QM.aspect);
|
|
}else{
|
|
height = h1;
|
|
}
|
|
Map_QM.renderer.setSize(width, height);
|
|
Map_QM.labelRenderer.setSize(width, height);
|
|
Map_QM.w = width;
|
|
Map_QM.h = height;
|
|
Map_QM.updateRender();
|
|
Map_QM.collLabel();
|
|
},
|
|
};
|
|
/**
|
|
* @api {方法} init(callBack,options) 地图初始化
|
|
* @apiGroup 地图数据
|
|
* @apiDescription 初始化地图赋值 Map_QM
|
|
* @apiVersion 4.0.0
|
|
*
|
|
* @apiParam {function} callBack 初始化成功后的回调函数
|
|
* @apiParam {object} options 初始化对象
|
|
* @apiParam {int} options.build 设备所在楼栋编号 默认值6
|
|
* @apiParam {int} options.floor 设备所在楼层编号 默认值 true
|
|
* @apiParam {int} options.navPoint 设备导航点 默认值 -1
|
|
* @apiParam {int} options.angle 起点设备角度 默认值 0
|
|
* @apiParam {string} options.perc_H 弹窗的偏移量 默认值 "-50%";
|
|
* @apiParam {string} options.containerId 地图div容器Id 默认值 "mapContainer"
|
|
* @apiParam {string} options.playSpeed 动画播放速度 默认值8
|
|
* @apiParam {boolean} options.collision 是否支持名称的碰撞检测 默认值 true
|
|
* @apiParam {boolean} options.modelIcon 交通设施是否使用模型 默认值 true
|
|
* @apiParam {Array} options.otherPath 人为干预的路线 默认值 [];
|
|
* @apiParam {int} options.fSpace 双叠层状态下楼层的间距 默认值 500
|
|
* @apiParam {uint} options.navColor 途径店铺颜色 默认值 0xEE6A50
|
|
* @apiParam {boolean} options.shadow 是否显示阴影 默认值 false
|
|
* @apiParam {boolean} options.iconName 图标名称是否显示 默认值false
|
|
* @apiParam {uint} options.pathColor 导航路径颜色 默认值 0xb47834,
|
|
* @apiParam {string} options.pathStyle 导航第一视角 默认值 "2D",
|
|
* @apiParam {string} options.shopStyle 店铺显示字段编号(houseNumber)名称(shopName) 默认值 "shopName",
|
|
* @apiParam {boolean} options.inArea 地图点击后是否聚焦到当前位置 默认值 false
|
|
* @apiParam {string} options.mapData 地图数据 res.data.mapData
|
|
* @apiParam {string} options.shopData 店铺数据 res.data
|
|
* @apiParam {Array} options.iconUrl 设施库图标 默认值 []
|
|
*
|
|
* @apiSampleRequest off
|
|
* @apiParamExample {String} 请求示例
|
|
*
|
|
* MainMap_QM.init(callBackLoadOver,{build : 0, floor : 3, navPoint : 7, angle : 0, perc_H : "-50%",containerId : "mapContainer"});
|
|
*/
|
|
MainMap_QM.init = function (callBack, options) {
|
|
if (Map_QM) {
|
|
Map_QM.cancelRender();
|
|
Map_QM.beforeDestroy();
|
|
}
|
|
Map_QM = new MainMap_QM(callBack, options);
|
|
return Map_QM;
|
|
};
|
|
Object.assign(MainMap_QM.prototype, THREE.EventDispatcher.prototype);
|
|
|
|
//////////////////////////////////////-------------------------------FloorMap
|
|
var FloorMap_QM = function (bIndex, fIndex, floorName) {
|
|
this.Model_QM = new MyModel_QM();
|
|
this.facUtil = new Facilities_QM();
|
|
this.findPath = new FindPath_QM();
|
|
this.logoUtil = new ShopLogo_QM();
|
|
this.allObj = new THREE.Group();
|
|
this.allObj.name = floorName;
|
|
this.allObj.rotation.x = Math.PI / -2;
|
|
this.CSSObj = new THREE.Group();
|
|
this.labelObj = new THREE.Group();
|
|
this.labelObj.renderOrder = 100;
|
|
this.floorOrder = fIndex;
|
|
this.buildOrder = bIndex;
|
|
this.floorName = floorName;
|
|
//存第三方
|
|
this.otherObj = new THREE.Object3D();
|
|
this.allObj.add(this.otherObj);
|
|
|
|
//存放设施图标
|
|
this.serObj = new THREE.Object3D();
|
|
//存放车位box
|
|
this.parkObj = new THREE.Group();
|
|
//标签
|
|
this.tagObj = new THREE.Group();
|
|
this.tagObj.renderOrder = 100;
|
|
//存放设施图标
|
|
this.svgObj = new THREE.Group();
|
|
//店铺
|
|
this.shopObj = new THREE.Group();
|
|
this.allObj.add(this.shopObj);
|
|
this.allObj.add(this.svgObj);
|
|
this.allObj.add(this.CSSObj);
|
|
|
|
this.CSSObj.add(this.serObj);
|
|
this.CSSObj.add(this.labelObj);
|
|
this.CSSObj.add(this.tagObj);
|
|
//标签
|
|
this.showTagObj = new THREE.Group();
|
|
this.showTagObj.renderOrder = 100;
|
|
this.CSSObj.add(this.showTagObj);
|
|
|
|
//线条
|
|
this.lineObj = new THREE.Group();
|
|
this.lineObj.renderOrder = 100;
|
|
this.allObj.add(this.lineObj);
|
|
|
|
this.startIcon;
|
|
};
|
|
|
|
FloorMap_QM.prototype = {
|
|
initDraw: function () {
|
|
this.initFloor();
|
|
this.initFacilitie();
|
|
this.initStairs();
|
|
this.initTextArea();
|
|
this.initWall();
|
|
this.initDecos();
|
|
this.initPark();
|
|
this.initModel();
|
|
this.initTree(); //植树
|
|
this.initLogos(); //贴图
|
|
},
|
|
initLogos: function () {
|
|
let sopce = this;
|
|
if (Map_QM.util.logos) {
|
|
Map_QM.util.logos.map((item) => {
|
|
if (item.build == sopce.buildOrder && item.floor == sopce.floorOrder) {
|
|
sopce.logoUtil.renderIcon(item, sopce, item.site || 0);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
initModel: function () {
|
|
let sopce = this;
|
|
if (Map_QM.util.modelArr) {
|
|
for (let i = 0; i < Map_QM.util.modelArr.length; i++) {
|
|
if (Map_QM.util.modelArr[i].build == this.buildOrder && Map_QM.util.modelArr[i].floor == this.floorOrder) {
|
|
new THREE.GLTFLoader().load(
|
|
Map_QM.util.beforPath + Map_QM.util.modelArr[i].url,
|
|
function (object) {
|
|
//加载路径fbx文件
|
|
let mod = object.scene;
|
|
mod.traverse(function (child) {
|
|
if (child.isMesh) {
|
|
child.userData.opacity = child.material.opacity;
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
child.material.color.convertGammaToLinear(0.7);
|
|
}
|
|
});
|
|
for (let t = 0; t < Map_QM.util.modelArr[i].list.length; t++) {
|
|
let obj = mod.clone();
|
|
obj.position.set(
|
|
Map_QM.util.modelArr[i].list[t].site.x,
|
|
-1 * Map_QM.util.modelArr[i].list[t].site.y,
|
|
Map_QM.util.modelArr[i].list[t].site.z
|
|
);
|
|
obj.scale.set(
|
|
Map_QM.util.modelArr[i].list[t].size.x,
|
|
Map_QM.util.modelArr[i].list[t].size.y,
|
|
Map_QM.util.modelArr[i].list[t].size.z
|
|
);
|
|
obj.rotateX((Map_QM.util.modelArr[i].list[t].rot.x * Math.PI) / 180);
|
|
obj.rotateY((Map_QM.util.modelArr[i].list[t].rot.y * Math.PI) / 180);
|
|
obj.rotateZ((Map_QM.util.modelArr[i].list[t].rot.z * Math.PI) / 180);
|
|
sopce.allObj.add(obj);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
}
|
|
}
|
|
if (Map_QM.util.labelIconArr) {
|
|
for (let i = 0; i < Map_QM.util.labelIconArr.length; i++) {
|
|
if (Map_QM.util.labelIconArr[i].build == this.buildOrder && Map_QM.util.labelIconArr[i].floor == this.floorOrder) {
|
|
let SpriteDiv = document.createElement("div");
|
|
SpriteDiv.className = Map_QM.util.labelIconArr[i].className;
|
|
SpriteDiv.innerHTML = Map_QM.util.labelIconArr[i].title;
|
|
SpriteDiv.dataset.id = Map_QM.util.labelIconArr[i].data.id;
|
|
SpriteDiv.dataset.x = Map_QM.util.labelIconArr[i].site.x;
|
|
SpriteDiv.dataset.y = Map_QM.util.labelIconArr[i].site.y;
|
|
SpriteDiv.dataset.z = Map_QM.util.labelIconArr[i].site.z;
|
|
let pointLabel = new THREE.CSS2DObject(SpriteDiv);
|
|
pointLabel.position.set(
|
|
Map_QM.util.labelIconArr[i].site.x,
|
|
-1 * Map_QM.util.labelIconArr[i].site.y,
|
|
Map_QM.util.labelIconArr[i].site.z
|
|
);
|
|
pointLabel.name = Map_QM.util.labelIconArr[i].title;
|
|
pointLabel.userData = Map_QM.util.labelIconArr[i].data;
|
|
pointLabel.userData.site = Map_QM.util.labelIconArr[i].site;
|
|
pointLabel.userData.mapShow = true;
|
|
pointLabel.userData.isShow = true;
|
|
pointLabel.userData.type = "icon";
|
|
if (Map_QM.util.labelIconArr[i].click) {
|
|
//可点击
|
|
SpriteDiv.addEventListener("click", (event) => {
|
|
Map_QM.dispatchEvent({
|
|
type: "labelIcon",
|
|
data: event.target.dataset,
|
|
});
|
|
},
|
|
false
|
|
);
|
|
} else {
|
|
pointLabel.element.style.pointerEvents = "none";
|
|
}
|
|
pointLabel.userData.floor = Map_QM.util.labelIconArr[i].floor;
|
|
sopce.showTagObj.add(pointLabel);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
initTree: function () {
|
|
let mapData =
|
|
Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
|
|
if (mapData.models) {
|
|
for (let t = 0; t < mapData.models.length; t++) {
|
|
for (let i = 0; i < Map_QM.util.fbxModels.length; i++) {
|
|
if (mapData.models[t].type == Map_QM.util.fbxModels[i].key) {
|
|
let obj = Map_QM.util.fbxModels[i].obj.scene.clone();
|
|
obj.position.set(mapData.models[t].x, -1 * mapData.models[t].y, mapData.models[t].site);
|
|
obj.scale.set(mapData.models[t].scale,mapData.models[t].scale,mapData.models[t].scale);
|
|
obj.rotateX(Map_QM.util.fbxModels[i].operation.rot.x);
|
|
obj.rotateY((-1 * mapData.models[t].angle * Math.PI) / 180);
|
|
obj.renderOrder = 100;
|
|
for (let k = 0;k < Map_QM.util.fbxModels[i].obj.animations.length; k++ ) {
|
|
let mixer = new THREE.AnimationMixer(obj);
|
|
mixer.clipAction(Map_QM.util.fbxModels[i].obj.animations[k]).play();
|
|
Map_QM.mixers.push(mixer);
|
|
}
|
|
//加载编辑器动画
|
|
obj.name = mapData.models[t].name;
|
|
if (mapData.animations) {
|
|
mapData.animations.forEach((item) => {
|
|
if (mapData.models[t].name == item.name) {
|
|
obj.rotateY(mapData.models[t].angle * Math.PI / 180);
|
|
let posArr = [],
|
|
rotArr = [],
|
|
scaleArr = [],
|
|
keyArr = [],
|
|
proArr = [],
|
|
clip;
|
|
item.frames.forEach((it) => {
|
|
keyArr.push(it.time);
|
|
posArr.push(it.pos.x, -1 * it.pos.y, it.pos.z);
|
|
rotArr.push((it.rot / -180) * Math.PI);
|
|
scaleArr.push(it.size, it.size, it.size);
|
|
proArr.push(it.pro);
|
|
});
|
|
if (item.isType) {
|
|
//特殊模型动画
|
|
let rotKF = new THREE.KeyframeTrack(item.sonName, keyArr, proArr);
|
|
clip = new THREE.AnimationClip(item.name, keyArr[keyArr.length - 1], [rotKF]);
|
|
} else {
|
|
let posKF = new THREE.KeyframeTrack(item.name + ".position",keyArr,posArr);
|
|
let rotKF = new THREE.KeyframeTrack(item.name + ".rotation[y]", keyArr,rotArr);
|
|
let scalKF = new THREE.KeyframeTrack(item.name + ".scale",keyArr,scaleArr);
|
|
clip = new THREE.AnimationClip(item.name,keyArr[keyArr.length - 1],[posKF, rotKF, scalKF]);
|
|
}
|
|
if (clip) {
|
|
let mixer = new THREE.AnimationMixer(obj);
|
|
mixer.clipAction(clip).play();
|
|
Map_QM.mixers.push(mixer);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
this.allObj.add(obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
//初始化单楼层
|
|
initFloor: function () {
|
|
let floor;
|
|
let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
|
|
let entColor, borderColor;
|
|
if (mapData.floorArea) {
|
|
floor = Map_QM.util.changeAreaToString(mapData.floorArea);
|
|
}
|
|
let bLen = mapData.buildArea.length;
|
|
let hLen = mapData.hollowArea.length;
|
|
let hows_f = [];
|
|
for (let m = 0; m < hLen; m++) {
|
|
let isIn = Map_QM.util.checkAreaInArea(mapData.hollowArea[m],mapData.floorArea);
|
|
if (isIn) {
|
|
hows_f.push(Map_QM.util.changeAreaToString(mapData.hollowArea[m]));
|
|
}
|
|
}
|
|
if (floor) {
|
|
entColor = mapData.floorArea.entColor;
|
|
borderColor = mapData.floorArea.borderColor;
|
|
floorH = parseInt(mapData.floorArea.toHeight);
|
|
let mash = this.Model_QM.MyModelShape(floor,hows_f,mapData.floorArea,entColor,borderColor,10 + 100 * this.floorOrder);
|
|
mash.receiveShadow = true;
|
|
mash.castShadow = false;
|
|
mash.userData = {
|
|
type: "floor",
|
|
order: this.floorOrder,
|
|
};
|
|
mash.userData.opacity = mapData.floorArea.alphaModle / 100 || 0;
|
|
mash.name = "floor";
|
|
this.allObj.add(mash);
|
|
}
|
|
/////////////////////初始化楼栋
|
|
for (let i = 0; i < bLen; i++) {
|
|
let build = Map_QM.util.changeAreaToString(mapData.buildArea[i]);
|
|
let hows = [];
|
|
for (let t = 0; t < hLen; t++) {
|
|
let isIn = Map_QM.util.checkAreaInArea(mapData.hollowArea[t],mapData.buildArea[i]);
|
|
if (isIn) {
|
|
hows.push(Map_QM.util.changeAreaToString(mapData.hollowArea[t]));
|
|
}
|
|
}
|
|
entColor = mapData.buildArea[i].entColor;
|
|
borderColor = mapData.buildArea[i].borderColor;
|
|
buildH = parseInt(mapData.buildArea[i].toHeight);
|
|
let mash = this.Model_QM.MyPlaneShape(build,hows,mapData.buildArea[i],entColor,borderColor,30 + 100 * this.floorOrder);
|
|
mash.receiveShadow = true;
|
|
mash.castShadow = false;
|
|
mash.userData = {
|
|
type: "build",
|
|
order: this.floorOrder,
|
|
xaxis: mapData.buildArea[i].xaxis,
|
|
yaxis: mapData.buildArea[i].yaxis,
|
|
};
|
|
mash.userData.opacity = mapData.buildArea[i].alphaModle / 100 || 0;
|
|
mash.name = mapData.buildArea[i].name;
|
|
this.allObj.add(mash);
|
|
}
|
|
//店铺
|
|
let sLen = mapData.shopArea.length;
|
|
let show = "",
|
|
showE = "",
|
|
showLeb = "",
|
|
formatCode = "",
|
|
mapShow = false;
|
|
let logo = "",
|
|
navRecommend = false,
|
|
shopD = {};
|
|
let shopData = Map_QM.util.shopData;
|
|
for (let i = 0; i < sLen; i++) {
|
|
if (Map_QM.util.changeAreaToString(mapData.shopArea[i]) != "") {
|
|
for (let t = 0; t < sLen; t++) {
|
|
let isIn = Map_QM.util.checkAreaInArea(mapData.shopArea[i], mapData.shopArea[t]);
|
|
isIn &&(mapData.shopArea[i].site = parseInt(mapData.shopArea[i].site) + 1);
|
|
}
|
|
let arr = Map_QM.util.changeShopLinesToString(mapData.shopArea[i]);
|
|
entColor = mapData.shopArea[i].entColor || "#b79266";
|
|
borderColor = mapData.shopArea[i].borderColor || "#b79266";
|
|
show = showE = mapData.shopArea[i].name;
|
|
logo = "";
|
|
showLeb = "";
|
|
navRecommend = false;
|
|
mapShow = false;
|
|
shopD = {};
|
|
if (shopData) {
|
|
for (let h = 0; h < shopData.length; h++) {
|
|
if (shopData[h].houseNumber === mapData.shopArea[i].name) {
|
|
showLeb = shopData[h].houseNumber;
|
|
show = shopData[h].shopName == undefined ? shopData[h].name : shopData[h].shopName;
|
|
showE = shopData[h].shopNameEn == undefined ? shopData[h].nameEn : shopData[h].shopNameEn;
|
|
logo = shopData[h].logoUrl;
|
|
mapShow = shopData[h].mapShow ?? false; //是否常显示
|
|
formatCode = shopData[h].industryFatherCode;
|
|
if (shopData[h].isPass) {
|
|
navRecommend = shopData[h].isPass;
|
|
} else {
|
|
navRecommend = false;
|
|
}
|
|
shopD = shopData[h];
|
|
if (shopData[h].isNewShop) {
|
|
//新店
|
|
mapData.shopArea[i].type = "new-shop";
|
|
this.addTagLabel(mapData.shopArea[i], {node: mapData.shopArea[i].shopNav, floor: this.floorOrder, build: this.buildOrder});
|
|
} else {
|
|
if (shopData[h].activityList &&shopData[h].activityList.length > 0) {
|
|
//促销
|
|
mapData.shopArea[i].type = "promotion";
|
|
this.addTagLabel(mapData.shopArea[i], {node: mapData.shopArea[i].shopNav, floor: this.floorOrder, build: this.buildOrder });
|
|
}
|
|
}
|
|
shopData[h].color && (entColor = shopData[h].color);
|
|
shopData[h].formatColor && (entColor = shopData[h].formatColor);
|
|
shopData[h].borderColor && (borderColor = shopData[h].borderColor);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
let hollShop = [];
|
|
if (mapData.shopArea[i].hollArea) {
|
|
for (let k = 0; k < mapData.shopArea[i].hollArea.length; k++) {
|
|
hollShop.push(Map_QM.util.changeAreaToString(mapData.shopArea[i].hollArea[k]));
|
|
}
|
|
}
|
|
let mahc = this.Model_QM.MyModelShape(arr,hollShop,mapData.shopArea[i],entColor,borderColor,60 + 100 * this.floorOrder);
|
|
mahc.node = mapData.shopArea[i].shopNav;
|
|
mahc.userData = {
|
|
id: mapData.shopArea[i].id,
|
|
shopData: shopD,
|
|
xaxis: mapData.shopArea[i].xaxis >> 0,
|
|
yaxis: mapData.shopArea[i].yaxis >> 0,
|
|
node: mahc.node,
|
|
floor: this.floorOrder,
|
|
build: this.buildOrder,
|
|
navRecommend: navRecommend,
|
|
type: "shop",
|
|
houseNumber: mapData.shopArea[i].name,
|
|
shopName: show,
|
|
formatCode: formatCode,
|
|
logo: logo,
|
|
opacity: mapData.shopArea[i].alphaModle / 100 || 0,
|
|
};
|
|
mahc.name = showLeb;
|
|
mahc.xaxis = mapData.shopArea[i].xaxis >> 0;
|
|
mahc.yaxis = mapData.shopArea[i].yaxis >> 0;
|
|
this.shopObj.add(mahc);
|
|
if (mapData.shopArea[i].logoUrl && mapData.shopArea[i].isLabel == 0) {
|
|
//添加logo
|
|
this.logoUtil.renderIcon(mapData.shopArea[i],mahc,parseInt(mapData.shopArea[i].toHeight) +1 );
|
|
} else {
|
|
//添加文字
|
|
let some = false;
|
|
if (Map_QM.util.options.boxShop.length && Map_QM.util.options.boxShop[0] !== "") {
|
|
some = Map_QM.util.options.boxShop.some((item) => {
|
|
return mapData.shopArea[i].name.includes(item);
|
|
});
|
|
}
|
|
if (showLeb != "" || some) {
|
|
let shopDiv = document.createElement("div");
|
|
shopDiv.className = "map_label";
|
|
if (window.innerWidth > 2000) {
|
|
shopDiv.style.fontSize = "18px";
|
|
}
|
|
let shopNameLab = Map_QM.util.options.shopStyle == "shopName" ? show : mapData.shopArea[i].name;
|
|
shopDiv.innerHTML = Map_QM.util.showHouseNumberAndName?`<span style="background-color: rgba(0, 0, 0, 0.6); margin: auto; color:#FFFFFF;text-shadow: none !important;">${mapData.shopArea[i].name}</span><span>${show}</span>`:shopNameLab;
|
|
shopDiv.dataset.name = show;
|
|
shopDiv.dataset.nameEn = showE;
|
|
shopDiv.style.display = "none";
|
|
let shopLabel = new THREE.CSS2DObject(shopDiv);
|
|
shopLabel.position.set(mapData.shopArea[i].xaxis >> 0, (-1 * mapData.shopArea[i].yaxis) >> 0, parseInt(mapData.shopArea[i].toHeight) + parseInt(mapData.shopArea[i].site || 0));
|
|
shopLabel.name = mapData.shopArea[i].name;
|
|
shopLabel.userData.mapShow = mapShow; //是否永久显示
|
|
shopLabel.userData.formatCode = formatCode;
|
|
shopLabel.userData.isShow = true;
|
|
this.labelObj.add(shopLabel);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
addTagLabel: function (obj, userData) {
|
|
let shopDiv = document.createElement("img");
|
|
shopDiv.src = Map_QM.util.beforPath + "static/img/" + obj.type + ".png";
|
|
shopDiv.style.zIndex = 30;
|
|
shopDiv.style.width = "3.125vw";
|
|
let shopLabel = new THREE.CSS2DObject(shopDiv);
|
|
shopLabel.userData = userData;
|
|
shopLabel.userData.mapShow = true; //是否永久显示
|
|
shopLabel.userData.isShow = false;
|
|
shopLabel.userData.type = obj.type;
|
|
shopLabel.position.set(obj.xaxis >> 0, (-1 * obj.yaxis) >> 0, Map_QM.util.shopHeight + 30);
|
|
this.tagObj.add(shopLabel);
|
|
},
|
|
//初始化服务图标
|
|
initFacilitie: function () {
|
|
let serArr = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData.icons;
|
|
for (let i = 0; i < serArr.length; i++) {
|
|
if (serArr[i].hasOwnProperty("iShow")) {
|
|
if (serArr[i].iShow) {
|
|
serArr[i].floorOrder = this.floorOrder;
|
|
serArr[i].buildOrder = this.buildOrder;
|
|
this.facUtil.renderIcon(serArr[i], this);
|
|
}
|
|
} else {
|
|
serArr[i].floorOrder = this.floorOrder;
|
|
serArr[i].buildOrder = this.buildOrder;
|
|
this.facUtil.renderIcon(serArr[i], this);
|
|
}
|
|
}
|
|
},
|
|
//初始化电梯图标
|
|
initStairs: function () {
|
|
let facArr = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData.stairs;
|
|
for (let i = 0; i < facArr.length; i++) {
|
|
if (facArr[i].facCode == "ft") {
|
|
if (Map_QM.util.pathStateObj.elevatorDown && Map_QM.util.pathStateObj.elevator && Map_QM.util.options.modelIcon) {
|
|
if (facArr[i].downState) {
|
|
//上扶梯
|
|
let ex = Map_QM.util.pathStateObj.elevator.clone();
|
|
ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
|
|
ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
|
|
ex.userData.type = "icon";
|
|
ex.userData.use = "3d";
|
|
ex.userData.name = "upft";
|
|
ex.userData.buildOrder = facArr[i].buildOrder;
|
|
ex.userData.floorOrder = facArr[i].floorOrder;
|
|
ex.userData.navCode = facArr[i].navCode;
|
|
ex.userData.src = "static/img/ft.png";
|
|
ex.userData.facCode = facArr[i].facCode;
|
|
ex.userData.title = facArr[i].title;
|
|
this.serObj.add(ex);
|
|
facArr[i].facCode = "ft";
|
|
this.facUtil.renderIcon(facArr[i], this, false, ex);
|
|
} else if (facArr[i].upState) {
|
|
//下扶梯
|
|
let ex = Map_QM.util.pathStateObj.elevatorDown.clone();
|
|
ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
|
|
ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
|
|
ex.userData.type = "icon";
|
|
ex.userData.use = "3d";
|
|
ex.userData.name = "downft";
|
|
ex.userData.buildOrder = facArr[i].buildOrder;
|
|
ex.userData.floorOrder = facArr[i].floorOrder;
|
|
ex.userData.navCode = facArr[i].navCode;
|
|
ex.userData.src = "static/img/ft.png";
|
|
ex.userData.facCode = facArr[i].facCode;
|
|
ex.userData.title = facArr[i].title;
|
|
this.serObj.add(ex);
|
|
facArr[i].facCode = "ft";
|
|
this.facUtil.renderIcon(facArr[i], this, false, ex);
|
|
} else {
|
|
this.facUtil.renderIcon(facArr[i], this, true);
|
|
}
|
|
} else {
|
|
this.facUtil.renderIcon(facArr[i], this, true);
|
|
}
|
|
} else if (facArr[i].facCode == "upft") {
|
|
if (Map_QM.util.pathStateObj.elevator && Map_QM.util.options.modelIcon) {
|
|
let ex = Map_QM.util.pathStateObj.elevator.clone();
|
|
ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
|
|
ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
|
|
ex.userData.type = "icon";
|
|
ex.userData.use = "3d";
|
|
ex.userData.name = "upft";
|
|
ex.userData.buildOrder = facArr[i].buildOrder;
|
|
ex.userData.floorOrder = facArr[i].floorOrder;
|
|
ex.userData.navCode = facArr[i].navCode;
|
|
ex.userData.src = "static/img/ft.png";
|
|
ex.userData.facCode = facArr[i].facCode;
|
|
ex.userData.title = facArr[i].title;
|
|
this.serObj.add(ex);
|
|
facArr[i].facCode = "ft";
|
|
this.facUtil.renderIcon(facArr[i], this, false, ex);
|
|
} else {
|
|
facArr[i].facCode = "ft";
|
|
this.facUtil.renderIcon(facArr[i], this, true);
|
|
}
|
|
} else if (facArr[i].facCode == "downft") {
|
|
if (Map_QM.util.pathStateObj.elevatorDown && Map_QM.util.options.modelIcon) {
|
|
let ex = Map_QM.util.pathStateObj.elevatorDown.clone();
|
|
ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
|
|
ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
|
|
ex.userData.type = "icon";
|
|
ex.userData.use = "3d";
|
|
ex.userData.name = "downft";
|
|
ex.userData.buildOrder = facArr[i].buildOrder;
|
|
ex.userData.floorOrder = facArr[i].floorOrder;
|
|
ex.userData.navCode = facArr[i].navCode;
|
|
ex.userData.src = "static/img/ft.png";
|
|
ex.userData.facCode = facArr[i].facCode;
|
|
ex.userData.title = facArr[i].title;
|
|
this.serObj.add(ex);
|
|
facArr[i].facCode = "ft";
|
|
this.facUtil.renderIcon(facArr[i], this, false, ex);
|
|
} else {
|
|
facArr[i].facCode = "ft";
|
|
this.facUtil.renderIcon(facArr[i], this, true);
|
|
}
|
|
} else if (facArr[i].facCode == "dt") {
|
|
if (Map_QM.util.pathStateObj.straight && Map_QM.util.options.modelIcon) {
|
|
let stra = Map_QM.util.pathStateObj.straight.clone();
|
|
stra.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
|
|
stra.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
|
|
stra.userData.type = "icon";
|
|
stra.userData.use = "3d";
|
|
stra.userData.name = "dt";
|
|
stra.userData.buildOrder = facArr[i].buildOrder;
|
|
stra.userData.floorOrder = facArr[i].floorOrder;
|
|
stra.userData.navCode = facArr[i].navCode;
|
|
stra.userData.src = "static/img/dt.png";
|
|
stra.userData.facCode = facArr[i].facCode;
|
|
stra.userData.title = facArr[i].title;
|
|
this.serObj.add(stra);
|
|
this.facUtil.renderIcon(facArr[i], this, false, stra);
|
|
} else {
|
|
this.facUtil.renderIcon(facArr[i], this, true);
|
|
}
|
|
} else {
|
|
this.facUtil.renderIcon(facArr[i], this, true);
|
|
}
|
|
}
|
|
},
|
|
//初始化装饰图标
|
|
initDecos: function () {
|
|
let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
|
|
let sLen = mapData.decos.length;
|
|
let entColor, borderColor;
|
|
|
|
if (mapData.groupArea) {
|
|
for (let k = 0; k < mapData.groupArea.length; k++) {
|
|
var gp = new THREE.Group();
|
|
gp.rotateX((mapData.groupArea[k].angleX * Math.PI) / 180);
|
|
gp.rotateY((mapData.groupArea[k].angleY * Math.PI) / 180);
|
|
gp.rotateZ((mapData.groupArea[k].angleZ * Math.PI) / 180);
|
|
for (let i = 0; i < sLen; i++) {
|
|
let arr = Map_QM.util.changeAreaToString(mapData.decos[i]);
|
|
if (mapData.decos[i].gid && mapData.decos[i].gid == mapData.groupArea[k].name && arr.length > 0) {
|
|
entColor = mapData.decos[i].entColor;
|
|
borderColor = mapData.decos[i].borderColor;
|
|
let show = mapData.decos[i].name == "deco" ? "" : mapData.decos[i].name;
|
|
let hollShop = [];
|
|
if (mapData.decos[i].hollArea) {
|
|
for (let k = 0; k < mapData.decos[i].hollArea.length; k++) {
|
|
hollShop.push(Map_QM.util.changeAreaToString(mapData.decos[i].hollArea[k]));
|
|
}
|
|
}
|
|
let mahc = this.Model_QM.MyModelShape(arr,hollShop,mapData.decos[i],entColor,borderColor,70 + 100 * this.floorOrder);
|
|
mahc.xaxis = mapData.decos[i].xaxis >> 0;
|
|
mahc.yaxis = mapData.decos[i].yaxis >> 0;
|
|
mahc.node = mapData.decos[i].shopNav;
|
|
mahc.userData = {
|
|
type: "deco",
|
|
name: show,
|
|
};
|
|
mahc.userData.opacity = mapData.decos[i].alphaModle / 100 || 0;
|
|
gp.add(mahc);
|
|
mahc.position.x = -1 * mapData.groupArea[k].xaxis;
|
|
mahc.position.y = mapData.groupArea[k].yaxis;
|
|
}
|
|
}
|
|
this.allObj.add(gp);
|
|
gp.position.x = mapData.groupArea[k].xaxis;
|
|
gp.position.y = -1 * mapData.groupArea[k].yaxis;
|
|
gp.position.z = mapData.groupArea[k].site || 0;
|
|
gp.scale.set(mapData.groupArea[k].scale,mapData.groupArea[k].scale,mapData.groupArea[k].scale);
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < sLen; i++) {
|
|
let arr = Map_QM.util.changeAreaToString(mapData.decos[i]);
|
|
if (!mapData.decos[i].gid && arr.length > 0) {
|
|
entColor = mapData.decos[i].entColor;
|
|
borderColor = mapData.decos[i].borderColor;
|
|
let show = mapData.decos[i].name == "deco" ? "" : mapData.decos[i].name;
|
|
let hollShop = [];
|
|
if (mapData.decos[i].hollArea) {
|
|
for (let k = 0; k < mapData.decos[i].hollArea.length; k++) {
|
|
hollShop.push(Map_QM.util.changeAreaToString(mapData.decos[i].hollArea[k]));
|
|
}
|
|
}
|
|
let mahc;
|
|
mahc = this.Model_QM.MyModelShape(arr,hollShop,mapData.decos[i],entColor,borderColor,70 + 100 * this.floorOrder );
|
|
mahc.userData = {
|
|
type: "deco",
|
|
node: mapData.decos[i].shopNav,
|
|
xaxis: mapData.decos[i].xaxis,
|
|
yaxis: mapData.decos[i].yaxis,
|
|
houseNumber: mahc.name,
|
|
name: show,
|
|
};
|
|
this.allObj.add(mahc);
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* 渲染墙体
|
|
*/
|
|
initWall: function () {
|
|
let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
|
|
//渲染
|
|
if (mapData.wallArea) {
|
|
let sLen = mapData.wallArea.length;
|
|
for (let i = 0; i < sLen; i++) {
|
|
let arr = Map_QM.util.changeWallToString(mapData.wallArea[i]);
|
|
let mahc = this.Model_QM.MyModelShape(arr, null, mapData.wallArea[i], mapData.wallArea[i].entColor || "#eaeaea", mapData.wallArea[i].borderColor || "#eaeaea", 300);
|
|
mahc.userData = {
|
|
type: "wall",
|
|
};
|
|
mahc.userData.opacity = mapData.wallArea[i].alphaModle / 100 || 0;
|
|
this.allObj.add(mahc);
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* 渲染文本
|
|
*/
|
|
initTextArea: function () {
|
|
let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
|
|
//渲染
|
|
if (mapData.svgArea) {
|
|
let sLen = mapData.svgArea.length;
|
|
for (let i = 0; i < sLen; i++) {
|
|
let mahc = this.Model_QM.MyModelText(mapData.svgArea[i]);
|
|
mahc.userData = {
|
|
type: "svg",
|
|
rot: mahc.rotation.z,
|
|
houseNumber: mapData.svgArea[i].name,
|
|
};
|
|
this.svgObj.add(mahc);
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* 设置终点图标
|
|
*/
|
|
setOverSite: function (shopX, shopY, shopZ) {
|
|
if (Map_QM.endModel) {
|
|
Map_QM.endModel.visible = pathCameraState == "2D" ? false : true;
|
|
Map_QM.endModel.scale.x = Map_QM.endModel.scale.y = Map_QM.endModel.scale.z = 100;
|
|
Map_QM.endModel.position.set(shopX, shopZ, shopY); //x,z,y
|
|
Map_QM.endModel.applyMatrix4(Map_QM.sceneGap.matrix);
|
|
if (Map_QM.endIcon) {
|
|
Map_QM.endIcon.visible = pathCameraState == "2D" ? true : false;
|
|
Map_QM.endIcon.scale.x = 100;
|
|
Map_QM.endIcon.scale.y = 120;
|
|
Map_QM.endIcon.position.set(shopX, 100, shopY); //x,z,y
|
|
Map_QM.endIcon.applyMatrix4(Map_QM.sceneGap.matrix);
|
|
}
|
|
} else {
|
|
try {
|
|
Map_QM.scene.traverse((item) => {
|
|
if (item.name == "Z-model") {
|
|
Map_QM.scene.remove(item);
|
|
}
|
|
});
|
|
} catch (e) {
|
|
window.captureException && window.captureException(e);
|
|
console.log("traverse");
|
|
}
|
|
|
|
let loader2 = new THREE.GLTFLoader();
|
|
loader2.load(
|
|
Map_QM.util.beforPath + "static/img/zhong.glb",
|
|
function (collada2) {
|
|
collada2.scene.scale.x = collada2.scene.scale.y = collada2.scene.scale.z = 100;
|
|
if (shopX != 0 && shopY != 0) {
|
|
collada2.scene.position.set(shopX, shopZ, shopY); //x,z,y
|
|
}
|
|
collada2.scene.applyMatrix4(Map_QM.sceneGap.matrix);
|
|
collada2.scene.renderOrder = 200;
|
|
collada2.scene.traverse(function (child) {
|
|
if (child.type === "Mesh") {
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
}
|
|
});
|
|
for (let k = 0; k < collada2.animations.length; k++) {
|
|
let mixer = new THREE.AnimationMixer(collada2.scene);
|
|
mixer.clipAction(collada2.animations[k]).play();
|
|
Map_QM.mixers.push(mixer);
|
|
}
|
|
collada2.scene.name = "Z-model";
|
|
Map_QM.endModel = collada2.scene;
|
|
Map_QM.scene.add(collada2.scene);
|
|
Map_QM.endModel.visible = pathCameraState == "2D" ? false : true;
|
|
}
|
|
);
|
|
let spriteMap = new THREE.TextureLoader().load(
|
|
Map_QM.util.beforPath + "static/img/Z.png"
|
|
);
|
|
let spriteMaterial = new THREE.SpriteMaterial({
|
|
//sizeAttenuation: false 禁止跟随鼠标缩放
|
|
map: spriteMap,
|
|
depthTest: true,
|
|
transparent: true,
|
|
alphaTest: 0.5,
|
|
});
|
|
Map_QM.endIcon = new MySprite_QM(spriteMaterial);
|
|
Map_QM.endIcon.scale.set(100, 120, 1);
|
|
Map_QM.endIcon.center = new THREE.Vector2(0.5, 0);
|
|
Map_QM.endIcon.position.set(shopX, 100, shopY);
|
|
Map_QM.endIcon.applyMatrix4(Map_QM.sceneGap.matrix);
|
|
Map_QM.endIcon.renderOrder = 300;
|
|
Map_QM.endIcon.name = "Z-model";
|
|
Map_QM.endIcon.visible = pathCameraState == "2D" ? true : false;
|
|
Map_QM.scene.add(Map_QM.endIcon);
|
|
}
|
|
},
|
|
/**
|
|
* 设置起点图标
|
|
*/
|
|
setStartSite: function (shopX, shopY, shopZ) {
|
|
let _this = this;
|
|
if (Map_QM.qiModel) {
|
|
Map_QM.devModel.position.set(shopX, -1 * shopY, 20);
|
|
_this.allObj.add(Map_QM.devModel);
|
|
Map_QM.qiModel.position.set(shopX, -1 * shopY, 10);
|
|
_this.allObj.add(Map_QM.qiModel);
|
|
Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ);
|
|
_this.allObj.add(Map_QM.qiIcon);
|
|
} else {
|
|
new THREE.GLTFLoader().load(
|
|
Map_QM.util.beforPath + "static/img/guide.glb",
|
|
function (obj) {
|
|
obj.scene.scale.x = obj.scene.scale.y = obj.scene.scale.z = 100;
|
|
obj.scene.rotation.x = Math.PI / 2;
|
|
obj.scene.rotation.y = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
|
|
obj.scene.traverse(function (child) {
|
|
if (child.type === "Mesh") {
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
}
|
|
});
|
|
if (shopX != 0 && shopY != 0) {
|
|
obj.scene.position.set(shopX, -1 * shopY, 50); //x,z,y
|
|
}
|
|
for (let k = 0; k < obj.animations.length; k++) {
|
|
let mixer = new THREE.AnimationMixer(obj.scene);
|
|
mixer.clipAction(obj.animations[k]).play();
|
|
Map_QM.mixers.push(mixer);
|
|
}
|
|
Map_QM.devModel = obj.scene;
|
|
Map_QM.devModel.visible = false;
|
|
Map_QM.devModel.renderOrder = 160;
|
|
_this.allObj.add(Map_QM.devModel);
|
|
}
|
|
);
|
|
new THREE.GLTFLoader().load(
|
|
Map_QM.util.beforPath + "static/img/qi.glb",
|
|
function (collada) {
|
|
collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = 100;
|
|
collada.scene.rotateX(Math.PI / 2);
|
|
collada.scene.traverse(function (child) {
|
|
if (child.type === "Mesh") {
|
|
if (child.material.map) {
|
|
child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
|
|
}
|
|
}
|
|
});
|
|
if (shopX != 0 && shopY != 0) {
|
|
collada.scene.position.set( shopX, -1 * shopY, parseInt(Map_QM.util.buildHeight) + 5); //x,z,y
|
|
}
|
|
for (let k = 0; k < collada.animations.length; k++) {
|
|
let mixer = new THREE.AnimationMixer(collada.scene);
|
|
mixer.clipAction(collada.animations[k]).play();
|
|
Map_QM.mixers.push(mixer);
|
|
}
|
|
collada.scene.renderOrder = 200;
|
|
collada.scene.userData.type = "start";
|
|
Map_QM.qiModel = collada.scene;
|
|
_this.allObj.add(collada.scene);
|
|
//--------------------------------------------------------------
|
|
let spriteMap = new THREE.TextureLoader().load(
|
|
Map_QM.util.beforPath + "static/img/Q.png"
|
|
);
|
|
let spriteMaterial = new THREE.SpriteMaterial({
|
|
//sizeAttenuation: false 禁止跟随鼠标缩放
|
|
map: spriteMap,
|
|
depthTest: true,
|
|
transparent: true,
|
|
alphaTest: 0.5,
|
|
});
|
|
Map_QM.qiIcon = new MySprite_QM(spriteMaterial);
|
|
Map_QM.qiIcon.scale.set(100, 120, 1);
|
|
Map_QM.qiIcon.center = new THREE.Vector2(0.5, 0);
|
|
Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ + 50);
|
|
Map_QM.qiIcon.renderOrder = 500;
|
|
Map_QM.qiIcon.visible = false;
|
|
Map_QM.qiIcon.userData.type = "start";
|
|
_this.allObj.add(Map_QM.qiIcon);
|
|
}
|
|
);
|
|
}
|
|
},
|
|
/**
|
|
* 查找线
|
|
* @param {Object} startNode
|
|
* @param {Object} endNode
|
|
*/
|
|
isNoFindLine: function (startNode, endNode) {
|
|
let no = false;
|
|
for (let i = 0; i < startNode.lineArr.length; i++) {
|
|
if (startNode.lineArr[i].nextNode.id == endNode.id ||startNode.lineArr[i].selfNode.id == endNode.id) {
|
|
no = true;
|
|
break;
|
|
}
|
|
}
|
|
return no;
|
|
},
|
|
//初始化停车位
|
|
initPark: function () {
|
|
let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
|
|
//渲染车位
|
|
if (mapData.parkArea) {
|
|
let sLen = mapData.parkArea.length;
|
|
if (sLen > 0) {
|
|
this.allObj.add(this.parkObj);
|
|
}
|
|
let shapeArr = [],
|
|
materials = [],
|
|
parkHeight = 1,
|
|
borderColor = 0xaaaaaa;
|
|
for (let i = 0; i < sLen; i++) {
|
|
let arr = Map_QM.util.changeParkToString(mapData.parkArea[i]);
|
|
if (arr != "") {
|
|
parkHeight = Math.max(parseInt(mapData.parkArea[i].toHeight), parkHeight);
|
|
borderColor = mapData.parkArea[i].borderColor;
|
|
if (arr.length > 0) {
|
|
let shape = new THREE.Shape();
|
|
shape.moveTo(arr[0][0], -1 * arr[0][1]);
|
|
for (let k = 1; k < arr.length; k++) {
|
|
shape.lineTo(arr[k][0], -1 * arr[k][1]);
|
|
}
|
|
shapeArr.push(shape);
|
|
let meshMaterial;
|
|
let color2 = new THREE.Color(mapData.parkArea[i].entColor);
|
|
for (let e = 0; e < Map_QM.util.parkMaterialArr.length; e++) {
|
|
if (Map_QM.util.parkMaterialArr[e].color.equals(color2)) {
|
|
meshMaterial = Map_QM.util.parkMaterialArr[e];
|
|
}
|
|
}
|
|
if (!meshMaterial) {
|
|
meshMaterial = new THREE.MeshBasicMaterial({
|
|
color: mapData.parkArea[i].entColor,
|
|
});
|
|
Map_QM.util.parkMaterialArr.push(meshMaterial);
|
|
}
|
|
materials.push(meshMaterial);
|
|
if (mapData.parkArea[i].childArea && mapData.parkArea[i].childArea.length > 0) {
|
|
for (let m = 0; m < mapData.parkArea[i].childArea.length; m++) {
|
|
let meshMaterial0;
|
|
if (mapData.parkArea[i].childArea[m].color && mapData.parkArea[i].childArea[m].color != "#FFffff") {
|
|
let color2 = new THREE.Color(mapData.parkArea[i].childArea[m].color);
|
|
for (let e = 0; e < Map_QM.util.parkMaterialArr.length; e++) {
|
|
if (Map_QM.util.parkMaterialArr[e].color.equals(color2)) {
|
|
meshMaterial0 = Map_QM.util.parkMaterialArr[e];
|
|
}
|
|
}
|
|
if (!meshMaterial0) {
|
|
meshMaterial0 = new THREE.MeshBasicMaterial({
|
|
color: mapData.parkArea[i].childArea[m].color,
|
|
});
|
|
Map_QM.util.parkMaterialArr.push(meshMaterial0);
|
|
}
|
|
} else {
|
|
meshMaterial0 = meshMaterial;
|
|
}
|
|
let ps = mapData.parkArea[i].childArea[m].points;
|
|
let shape0 = new THREE.Shape();
|
|
// 设置开始点的位置
|
|
shape0.moveTo(ps[0].x, -1 * ps[0].y);
|
|
for (let t = 0; t < ps.length; t++) {
|
|
shape0.lineTo(ps[t].x, -1 * ps[t].y);
|
|
}
|
|
shapeArr.push(shape0);
|
|
materials.push(meshMaterial0);
|
|
}
|
|
}
|
|
}
|
|
//显示车位编号
|
|
if (mapData.parkArea[i].parkNum != "NaN" && i % 20 == 0) {
|
|
let shopDiv = document.createElement("div");
|
|
shopDiv.className = "map_label";
|
|
shopDiv.style.display = "none";
|
|
shopDiv.textContent = mapData.parkArea[i].parkNum;
|
|
let shopLabel = new THREE.CSS2DObject(shopDiv);
|
|
shopLabel.userData.mapShow = true; //是否永久显示
|
|
shopLabel.name = mapData.parkArea[i].name;
|
|
shopLabel.position.set(mapData.parkArea[i].xaxis >> 0,(-1 * mapData.parkArea[i].yaxis) >> 0,parseInt(mapData.parkArea[i].toHeight) + 1);
|
|
this.labelObj.add(shopLabel);
|
|
}
|
|
}
|
|
}
|
|
let mahc = this.Model_QM.MyParkShape(shapeArr, materials, parkHeight);
|
|
this.parkObj.add(mahc);
|
|
}
|
|
},
|
|
};
|
|
|
|
/**
|
|
* 渲染3D模型类
|
|
* 传入区域点list
|
|
* 镂空点 howllowArr
|
|
* 模型对象 options
|
|
*/
|
|
MyModel_QM = function () {
|
|
this.xaxis = 0;
|
|
this.yaxis = 0;
|
|
this.node = 0;
|
|
};
|
|
MyModel_QM.prototype.MyParkShape = function (shapes, materials, toHeight = 5) {
|
|
let scanGeometry = new THREE.ShapeBufferGeometry(shapes, 1);
|
|
let material = new THREE.LineBasicMaterial({
|
|
color: "#aeaeae",
|
|
}); //材质对象lineColor
|
|
Map_QM.util.lineBasicMaterialArr.push(material);
|
|
|
|
// 创建模型
|
|
let mesh = new THREE.Mesh(scanGeometry, materials);
|
|
mesh.position.z = toHeight;
|
|
mesh.renderOrder = 300;
|
|
mesh.userData.type = "park";
|
|
|
|
let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60);
|
|
let cubeLine = new THREE.LineSegments(cubeEdges, material);
|
|
mesh.add(cubeLine);
|
|
return mesh;
|
|
};
|
|
|
|
MyModel_QM.prototype.MyModelShape = function (areaArr,howllowArr,opObj,entityColor = 0xdadada,lineColor = 0xeeeeee,indexOrder = 1) {
|
|
let len = areaArr.length;
|
|
if (len == 0) {
|
|
return;
|
|
}
|
|
let alphaModle = opObj.alphaModle / 100 || 0;
|
|
// 实例化shape对象
|
|
let shape = new THREE.Shape();
|
|
// 设置开始点的位置
|
|
shape.moveTo(areaArr[0][0], -1 * areaArr[0][1]);
|
|
for (let i = 0; i < areaArr.length; i++) {
|
|
if (areaArr[i].length == 4) {
|
|
shape.lineTo(areaArr[i][2], -1 * areaArr[i][3]);
|
|
} else {
|
|
shape.bezierCurveTo(areaArr[i][2], -1 * areaArr[i][3], areaArr[i][4], -1 * areaArr[i][5], areaArr[i][6], -1 * areaArr[i][7]);
|
|
}
|
|
}
|
|
let material;
|
|
let matcolor = new THREE.Color(lineColor);
|
|
for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) {
|
|
if (Map_QM.util.lineBasicMaterialArr[k].color.equals(matcolor)) {
|
|
material = Map_QM.util.lineBasicMaterialArr[k];
|
|
}
|
|
}
|
|
if (!material) {
|
|
material = new THREE.LineBasicMaterial({
|
|
color: lineColor,
|
|
opacity: 0.8,
|
|
transparent: true,
|
|
}); //材质对象lineColor
|
|
Map_QM.util.lineBasicMaterialArr.push(material);
|
|
}
|
|
if (howllowArr && howllowArr.length > 0) {
|
|
for (let n = 0; n < howllowArr.length; n++) {
|
|
let hole = new THREE.Path(); // 添加孔洞
|
|
hole.moveTo(howllowArr[n][0][0], -1 * howllowArr[n][0][1]);
|
|
for (let k = 0; k < howllowArr[n].length; k++) {
|
|
if (howllowArr[n][k].length == 4) {
|
|
hole.lineTo(howllowArr[n][k][2], -1 * howllowArr[n][k][3]);
|
|
} else {
|
|
hole.bezierCurveTo(howllowArr[n][k][2],-1 * howllowArr[n][k][3],howllowArr[n][k][4],-1 * howllowArr[n][k][5],howllowArr[n][k][6],-1 * howllowArr[n][k][7]);
|
|
}
|
|
}
|
|
shape.holes.push(hole);
|
|
}
|
|
}
|
|
|
|
let scanGeometry,
|
|
meshMaterial,
|
|
options = {
|
|
depth: parseInt(opObj.toHeight),
|
|
bevelEnabled: false,
|
|
curveSegments: 12,
|
|
bevelThickness: 0,
|
|
bevelSize: 0,
|
|
bevelSegments: 0,
|
|
material: 0, //frontMaterial = green
|
|
extrudeMaterial: 1, //sideMaterial = gray
|
|
};
|
|
|
|
scanGeometry = new THREE.ExtrudeGeometry(shape, options);
|
|
let meshColor = new THREE.Color(entityColor);
|
|
for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
|
|
if (Map_QM.util.meshMaterialArr[e].color &&
|
|
Map_QM.util.meshMaterialArr[e].color.equals(meshColor) &&
|
|
Map_QM.util.meshMaterialArr[e].opacity == alphaModle &&
|
|
!Map_QM.util.meshMaterialArr[e].userData.map
|
|
) {
|
|
meshMaterial = Map_QM.util.meshMaterialArr[e];
|
|
}
|
|
}
|
|
if (!meshMaterial) {
|
|
meshMaterial = new THREE.MeshPhongMaterial({
|
|
//MeshStandardMaterial MeshPhongMaterial MeshBasicMaterial
|
|
color: entityColor,
|
|
transparent: true,
|
|
opacity: alphaModle,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
Map_QM.util.meshMaterialArr.push(meshMaterial);
|
|
}
|
|
if (opObj.angleY || opObj.angleZ) {
|
|
Map_QM.util.rotateYZ(scanGeometry,(opObj.angleY * Math.PI) / 180,(opObj.angleZ * Math.PI) / 180);
|
|
}
|
|
// 创建模型
|
|
let mesh;
|
|
if (opObj.map == "home") {
|
|
Map_QM.util.assignUVs(scanGeometry);
|
|
let mapMaterial, ceMaterial;
|
|
for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
|
|
if (Map_QM.util.meshMaterialArr[e].userData.map == "front" && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) {
|
|
mapMaterial = Map_QM.util.meshMaterialArr[e];
|
|
}
|
|
if (Map_QM.util.meshMaterialArr[e].userData.map == "c50" && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) {
|
|
ceMaterial = Map_QM.util.meshMaterialArr[e];
|
|
}
|
|
}
|
|
if (!mapMaterial) {
|
|
let texture = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/map/front.png");
|
|
texture.wrapS = THREE.ClampToEdgeWrapping;
|
|
texture.wrapT = THREE.RepeatWrapping;
|
|
mapMaterial = new THREE.MeshPhongMaterial({
|
|
color: entityColor,
|
|
map: texture,
|
|
transparent: true,
|
|
opacity: alphaModle,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
mapMaterial.userData.map = "front";
|
|
Map_QM.util.meshMaterialArr.push(mapMaterial);
|
|
}
|
|
if (!ceMaterial) {
|
|
let texture2 = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/map/c50.png");
|
|
texture2.wrapS = THREE.RepeatWrapping;
|
|
texture2.wrapT = THREE.ClampToEdgeWrapping;
|
|
ceMaterial = new THREE.MeshPhongMaterial({
|
|
color: entityColor,
|
|
map: texture2,
|
|
transparent: true,
|
|
opacity: alphaModle,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
ceMaterial.userData.map = "c50";
|
|
Map_QM.util.meshMaterialArr.push(ceMaterial);
|
|
}
|
|
mesh = new THREE.Mesh(scanGeometry, [meshMaterial, ceMaterial, mapMaterial,]);
|
|
} else if (opObj.map) {
|
|
Map_QM.util.packUv(scanGeometry);
|
|
let ceMaterial;
|
|
for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
|
|
if (Map_QM.util.meshMaterialArr[e].userData.map == opObj.map && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) {
|
|
ceMaterial = Map_QM.util.meshMaterialArr[e];
|
|
}
|
|
}
|
|
if (!ceMaterial) {
|
|
let texture2 = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/map/" + opObj.map + ".png");
|
|
texture2.wrapS = THREE.RepeatWrapping;
|
|
texture2.wrapT = THREE.ClampToEdgeWrapping;
|
|
ceMaterial = new THREE.MeshPhongMaterial({
|
|
color: entityColor,
|
|
map: texture2,
|
|
transparent: true,
|
|
opacity: alphaModle,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
ceMaterial.userData.map = opObj.map;
|
|
Map_QM.util.meshMaterialArr.push(ceMaterial);
|
|
}
|
|
mesh = new THREE.Mesh(scanGeometry, [meshMaterial, ceMaterial]);
|
|
} else {
|
|
mesh = new THREE.Mesh(scanGeometry, meshMaterial);
|
|
}
|
|
|
|
if (opObj.type != "wall") {
|
|
let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60);
|
|
let cubeLine = new THREE.LineSegments(cubeEdges, material);
|
|
cubeLine.renderOrder = indexOrder - 5;
|
|
mesh.add(cubeLine);
|
|
}
|
|
if (opObj.name != "floor") {
|
|
mesh.position.z = opObj.site || 0;
|
|
} else {
|
|
mesh.position.z = -1 * parseInt(opObj.toHeight) - 1;
|
|
}
|
|
mesh.castShadow = true;
|
|
mesh.renderOrder = indexOrder;
|
|
mesh.name = opObj.name || "";
|
|
return mesh;
|
|
};
|
|
|
|
//绘制平面
|
|
MyModel_QM.prototype.MyPlaneShape = function (areaArr,howllowArr,opObj,entityColor = "#dadada",lineColor = "#eeeeee",indexOrder = 1) {
|
|
let len = areaArr.length;
|
|
if (len == 0) {
|
|
return;
|
|
}
|
|
let alphaModle = opObj.alphaModle / 100 || 0;
|
|
// 实例化shape对象
|
|
let shape = new THREE.Shape();
|
|
// 设置开始点的位置
|
|
shape.moveTo(areaArr[0][0], -1 * areaArr[0][1]);
|
|
for (let i = 0; i < areaArr.length; i++) {
|
|
if (areaArr[i].length == 4) {
|
|
shape.lineTo(areaArr[i][2], -1*areaArr[i][3]);
|
|
} else {
|
|
shape.bezierCurveTo(areaArr[i][2], -1*areaArr[i][3], areaArr[i][4], -1*areaArr[i][5], areaArr[i][6], -1*areaArr[i][7]);
|
|
}
|
|
}
|
|
let material;
|
|
for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) {
|
|
let color2 = new THREE.Color(lineColor);
|
|
if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) {
|
|
material = Map_QM.util.lineBasicMaterialArr[k];
|
|
}
|
|
}
|
|
if (!material) {
|
|
material = new THREE.LineBasicMaterial({
|
|
color: lineColor,
|
|
opacity: 0.8,
|
|
transparent: true,
|
|
}); //材质对象lineColor
|
|
Map_QM.util.lineBasicMaterialArr.push(material);
|
|
}
|
|
if (howllowArr && howllowArr.length > 0) {
|
|
for (let n = 0; n < howllowArr.length; n++) {
|
|
let hole = new THREE.Path(); // 添加孔洞
|
|
hole.moveTo(howllowArr[n][0][0], -1 * howllowArr[n][0][1]);
|
|
for (let k = 0; k < howllowArr[n].length; k++) {
|
|
if (howllowArr[n][k].length == 4) {
|
|
hole.lineTo(howllowArr[n][k][2], -1 * howllowArr[n][k][3]);
|
|
} else {
|
|
hole.bezierCurveTo(howllowArr[n][k][2], -1*howllowArr[n][k][3], howllowArr[n][k][4], -1*howllowArr[n][k][5], howllowArr[n][k][6], -1*howllowArr[n][k][7]);
|
|
}
|
|
}
|
|
shape.holes.push(hole);
|
|
}
|
|
}
|
|
let scanGeometry, meshMaterial;
|
|
scanGeometry = new THREE.ShapeGeometry(shape, 8);
|
|
Map_QM.util.assignUVs(scanGeometry);
|
|
if (opObj.map) {
|
|
let texture = new THREE.TextureLoader().load(
|
|
Map_QM.util.beforPath + "static/img/map/" + opObj.map + ".png"
|
|
);
|
|
meshMaterial = new THREE.MeshPhongMaterial({
|
|
//MeshStandardMaterial MeshPhongMaterial olor: entityColor,
|
|
color: entityColor,
|
|
map: texture,
|
|
transparent: true,
|
|
opacity: alphaModle,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
meshMaterial.userData.map = opObj.map;
|
|
Map_QM.util.meshMaterialArr.push(meshMaterial);
|
|
} else {
|
|
for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
|
|
let color2 = new THREE.Color(entityColor);
|
|
if (
|
|
Map_QM.util.meshMaterialArr[e].color &&
|
|
Map_QM.util.meshMaterialArr[e].color.equals(color2) &&
|
|
Map_QM.util.meshMaterialArr[e].opacity == alphaModle &&
|
|
!Map_QM.util.meshMaterialArr[e].userData.map
|
|
) {
|
|
meshMaterial = Map_QM.util.meshMaterialArr[e];
|
|
}
|
|
}
|
|
if (!meshMaterial) {
|
|
meshMaterial = new THREE.MeshPhongMaterial({
|
|
color: entityColor,
|
|
transparent: true,
|
|
opacity: alphaModle,
|
|
side: THREE.DoubleSide,
|
|
depthTest: true,
|
|
});
|
|
Map_QM.util.meshMaterialArr.push(meshMaterial);
|
|
}
|
|
if (opObj.angleY || opObj.angleZ) {
|
|
Map_QM.util.rotateYZ(
|
|
scanGeometry,
|
|
(opObj.angleY * Math.PI) / 180,
|
|
(opObj.angleZ * Math.PI) / 180
|
|
);
|
|
}
|
|
}
|
|
// 创建模型
|
|
let mesh = new THREE.Mesh(scanGeometry, meshMaterial);
|
|
|
|
let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60);
|
|
let cubeLine = new THREE.LineSegments(cubeEdges, material);
|
|
cubeLine.renderOrder = indexOrder - 5;
|
|
mesh.add(cubeLine);
|
|
|
|
if (opObj.name != "floor") {
|
|
mesh.position.z = parseInt(opObj.toHeight) || 0;
|
|
}
|
|
mesh.castShadow = true;
|
|
mesh.renderOrder = indexOrder;
|
|
mesh.name = opObj.name || "";
|
|
return mesh;
|
|
};
|
|
|
|
MyModel_QM.prototype.MyModelText = function (svgArea) {
|
|
let text = svgArea.data;
|
|
const paths = new THREE.SVGLoader().parse(text).paths;
|
|
const group = new THREE.Group();
|
|
|
|
group.position.x = parseInt(svgArea.xaxis);
|
|
group.position.y = -1 * parseInt(svgArea.yaxis);
|
|
group.position.z = parseInt(svgArea.site || 0);
|
|
group.rotateX((parseInt(svgArea.angleZ) * Math.PI) / 180);
|
|
group.rotateY((parseInt(svgArea.angleY) * Math.PI) / 180);
|
|
group.rotateZ((parseInt(svgArea.angle) * Math.PI) / 180);
|
|
group.scale.multiplyScalar(svgArea.scale);
|
|
group.scale.y *= -1;
|
|
|
|
let meshMaterial;
|
|
for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
|
|
let color2 = new THREE.Color().setHex(svgArea.entColor);
|
|
if (Map_QM.util.meshMaterialArr[e].color &&
|
|
Map_QM.util.meshMaterialArr[e].color.equals(color2) &&
|
|
Map_QM.util.meshMaterialArr[e].opacity == svgArea.alphaModle
|
|
) {
|
|
meshMaterial = Map_QM.util.meshMaterialArr[e];
|
|
}
|
|
}
|
|
if (!meshMaterial) {
|
|
meshMaterial = new THREE.MeshStandardMaterial({
|
|
color: svgArea.entColor,
|
|
opacity: parseInt(svgArea.alphaModle) / 100,
|
|
});
|
|
Map_QM.util.meshMaterialArr.push(meshMaterial);
|
|
}
|
|
|
|
for (let i = 0; i < paths.length; i++) {
|
|
const path = paths[i];
|
|
let shapes = path.toShapes(true);
|
|
const geometry = new THREE.ShapeGeometry(shapes, 12);
|
|
const mesh = new THREE.Mesh(geometry, meshMaterial);
|
|
mesh.renderOrder = 50;
|
|
mesh.name = svgArea.name || "";
|
|
mesh.position.set( svgArea.width / -2, svgArea.height / -2, parseInt(svgArea.toHeight) + 1);
|
|
group.add(mesh);
|
|
}
|
|
return group;
|
|
};
|
|
|
|
/**
|
|
* 公共设施
|
|
*/
|
|
var MySprite_QM = function (spriteMaterial, obj = null) {
|
|
THREE.Sprite.call(this);
|
|
if (obj) {
|
|
this.navCode = obj.navCode;
|
|
this.no = obj.no;
|
|
this.facCode = obj.facCode;
|
|
this.floor = obj.floorOrder;
|
|
this.build = obj.buildOrder;
|
|
this.site = parseInt(obj.site) || Map_QM.util.shopHeight + 32;
|
|
}
|
|
this.imgUrl;
|
|
this.material = spriteMaterial !== undefined ? spriteMaterial : new SpriteMaterial();
|
|
//图标跳动
|
|
this.jumpIcon = function () {
|
|
let oldZ = this.site;
|
|
let self = this;
|
|
TweenMax.fromTo(self.position, 0.5, { z: oldZ }, {z: oldZ + 20, repeat: 1,
|
|
onComplete: function () {
|
|
TweenMax.to(self.position, 0.2, { z: oldZ });
|
|
},
|
|
}
|
|
);
|
|
};
|
|
this.reSetSite = function () {
|
|
//重置位置
|
|
this.position.z = this.site;
|
|
};
|
|
};
|
|
|
|
MySprite_QM.prototype = Object.create(THREE.Sprite.prototype);
|
|
MySprite_QM.prototype.constructor = MySprite_QM;
|
|
|
|
/**
|
|
* 渲染公共设施
|
|
*/
|
|
var Facilities_QM = function () {
|
|
this.renderIcon = function (obj, _this, isShow = true, ele = null) {
|
|
if (obj) {
|
|
let url = Map_QM.util.beforPath + "static/img/" + obj.facCode + ".png";
|
|
let name = obj.title;
|
|
let nameEn = obj.title;
|
|
if (Map_QM.util.iconUrl.length > 0) {
|
|
//使用设施库
|
|
for (let i = 0; i < Map_QM.util.iconUrl.length; i++) {
|
|
if (Map_QM.util.iconUrl[i].abbreviation == obj.facCode) {
|
|
url = Map_QM.util.iconUrl[i].navFilePath;
|
|
name = Map_QM.util.iconUrl[i].name;
|
|
nameEn = Map_QM.util.iconUrl[i].nameEn;
|
|
}
|
|
}
|
|
}
|
|
let shopDiv = document.createElement("img");
|
|
shopDiv.src = url;
|
|
shopDiv.style.zIndex = 100;
|
|
shopDiv.style.width = "1.2vw";
|
|
shopDiv.style.display = isShow ? "" : "none";
|
|
shopDiv.dataset.name = name;
|
|
shopDiv.dataset.src = url;
|
|
shopDiv.dataset.nameEn = nameEn;
|
|
shopDiv.dataset.buildOrder = obj.buildOrder;
|
|
shopDiv.dataset.floorOrder = obj.floorOrder;
|
|
shopDiv.dataset.facCode = obj.facCode;
|
|
shopDiv.dataset.node = obj.navCode;
|
|
|
|
|
|
let shopLabel = new THREE.CSS2DObject(shopDiv);
|
|
shopLabel.userData.mapShow = true; //是否永久显示
|
|
shopLabel.userData = obj;
|
|
shopLabel.userData.type = "icon";
|
|
shopLabel.userData.use = ele ? "2d" : "all";
|
|
shopLabel.userData.model = ele;
|
|
shopLabel.userData.src = url;
|
|
shopLabel.userData.isShow = true;
|
|
shopLabel.position.set(obj.x, -1*obj.y, Math.max(30, parseInt(obj.site) || 0));
|
|
_this.serObj.add(shopLabel);
|
|
|
|
if (Map_QM.util.options.iconName) {
|
|
let titleDiv = document.createElement("div");
|
|
titleDiv.className = "map_label";
|
|
if (window.innerWidth > 2000) {
|
|
titleDiv.style.fontSize = "18px";
|
|
}
|
|
titleDiv.innerText = obj.title;
|
|
titleDiv.dataset.name = name;
|
|
titleDiv.dataset.nameEn = nameEn;
|
|
titleDiv.style.zIndex = 480;
|
|
let shopLabel = new THREE.CSS2DObject(titleDiv);
|
|
shopLabel.position.set(obj.x, -1 * obj.y, parseInt(obj.site) + 85);
|
|
shopLabel.userData.mapShow = true;
|
|
shopLabel.userData.isShow = true;
|
|
_this.labelObj.add(shopLabel);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
/**
|
|
* 店铺LOGO地图展示类
|
|
*/
|
|
var ShopLogo_QM = function () {
|
|
this.renderIcon = function (obj, _this, z) {
|
|
if (obj) {
|
|
let x = obj.xaxis >> 0;
|
|
let y = (-1 * obj.yaxis) >> 0;
|
|
let imgW = obj.imgW >> 0;
|
|
let imgH = obj.imgH >> 0;
|
|
|
|
new THREE.TextureLoader().load(obj.logoUrl, (textu) => {
|
|
let planeMaterial = new THREE.MeshPhongMaterial({
|
|
map: textu,
|
|
depthTest: true,
|
|
transparent: true,
|
|
alphaTest: 0.01,
|
|
});
|
|
let planeGeometry = new THREE.PlaneGeometry(imgW, imgH);
|
|
let plane = new THREE.Mesh(planeGeometry, planeMaterial);
|
|
plane.center = new THREE.Vector2(0, 0);
|
|
plane.position.set(x, y, obj.site || z);
|
|
plane.userData.rot = 0;
|
|
plane.userData.type = "logo";
|
|
plane.renderOrder = 70;
|
|
_this.add(plane);
|
|
});
|
|
}
|
|
};
|
|
};
|
|
|
|
var _selfFindPath;
|
|
var FindPath_QM = function () {
|
|
this.pathArr = [];
|
|
this.lineDashed;
|
|
this.lineDashed_old;
|
|
//路线指引箭头皮肤
|
|
this.planeGeometry = new THREE.PlaneGeometry(128, 128);
|
|
this.morePath = false;
|
|
this.stop = null;
|
|
this._index = 0; //寻路用
|
|
this.pathState = "init";
|
|
this.pathPlay = {
|
|
_isPlay: false,
|
|
get isPlay() {
|
|
return this._isPlay;
|
|
},
|
|
set isPlay(val) {
|
|
this._isPlay = val;
|
|
if (_selfFindPath && _selfFindPath.stop) {
|
|
window.cancelAnimationFrame(_selfFindPath.stop);
|
|
_selfFindPath.stop = null;
|
|
}
|
|
if (_selfFindPath && _selfFindPath.pathState == "isPlay" && _selfFindPath._index < _selfFindPath.pathArr.length) {
|
|
_selfFindPath.playMoveGuide();
|
|
}
|
|
},
|
|
};
|
|
};
|
|
|
|
FindPath_QM.prototype.clearPath = function () {
|
|
this.pathArr = [];
|
|
if (this.lineDashed) {
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(this.lineDashed);
|
|
}
|
|
this.lineDashed.destroy();
|
|
this.lineDashed = null;
|
|
}
|
|
if (this.lineDashed_old) {
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(this.lineDashed_old);
|
|
}
|
|
this.lineDashed_old.destroy();
|
|
this.lineDashed_old = null;
|
|
}
|
|
if (Map_QM.guide) {
|
|
Map_QM.guide.visible = false;
|
|
if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(Map_QM.man_2d);
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(Map_QM.man_3d);
|
|
}
|
|
}
|
|
|
|
if (_selfFindPath && _selfFindPath.stop) {
|
|
window.cancelAnimationFrame(_selfFindPath.stop);
|
|
}
|
|
this._index = 0;
|
|
this.pathState = "init";
|
|
};
|
|
/**
|
|
* @param {Object} startNade
|
|
* @param {Object} toNade
|
|
* @param {Object} callBack 回调函数
|
|
*/
|
|
FindPath_QM.prototype.onFindPathAnimation = function (pathArray,morePath = false,floorOrder = -1) {
|
|
this.morePath = morePath;
|
|
if (pathArray && pathArray.length > 0) {
|
|
this.pathState = "isPlay";
|
|
this._index = 0;
|
|
this.pathArr = [];
|
|
if (floorOrder === -1) {
|
|
floorOrder = Map_QM.util.selectFloor;
|
|
}
|
|
if (morePath) {
|
|
for (let j = 0; j < pathArray.length; j++) {
|
|
this.drawPath(floorOrder,pathArray[j], parseInt(Map_QM.util.buildHeight) + j);
|
|
}
|
|
} else {
|
|
for (let j = 0; j < pathArray.length; j++) {
|
|
this.pathArr.push(pathArray[j]);
|
|
}
|
|
this.drawPath(floorOrder);
|
|
}
|
|
}
|
|
};
|
|
|
|
FindPath_QM.prototype.drawPath = function (floorOrder, pathArr = null, height = 1) {
|
|
let linePath = [];
|
|
if (!pathArr) {
|
|
for (let i = 0; i < this.pathArr.length; i++) {
|
|
if (i < this.pathArr.length) {
|
|
linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]);
|
|
}
|
|
}
|
|
} else {
|
|
for (let i = 0; i < pathArr.length; i++) {
|
|
if (i < pathArr.length) {
|
|
linePath.push([pathArr[i].x, -1 * pathArr[i].y]);
|
|
}
|
|
}
|
|
}
|
|
if (this.morePath) {
|
|
this.lineDashed_old = new PathLine(12,linePath,height,Map_QM.util.options.pathColor,Map_QM.util.options.pathColor2,true);
|
|
} else {
|
|
this.lineDashed_old = new PathLine(12,linePath,parseInt(Map_QM.util.buildHeight) + 1,Map_QM.util.options.pathColor,Map_QM.util.options.pathColor2,true);
|
|
}
|
|
this.lineDashed_old.name = "lineDash";
|
|
this.lineDashed_old.renderOrder = 128;
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][floorOrder].allObj.add(this.lineDashed_old);
|
|
};
|
|
|
|
FindPath_QM.prototype.guidePathPlay = function (paths) {
|
|
if (Map_QM.guide) {
|
|
Map_QM.guide.renderOrder = 99;
|
|
if (paths.PathPoint) {
|
|
Map_QM.guide.position.x = paths.PathPoint[0].x;
|
|
Map_QM.guide.position.y = -1 * paths.PathPoint[0].y;
|
|
Map_QM.moveCameraBy2D(paths.PathPoint[0]);
|
|
Map_QM.man_2d.position.z = parseInt(Map_QM.util.buildHeight) + 120;
|
|
Map_QM.man_3d.position.z = parseInt(Map_QM.util.buildHeight) + 5;
|
|
Map_QM.guide.visible = true;
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][paths.floor].allObj.add(Map_QM.man_2d);
|
|
Map_QM.mapArr[Map_QM.util.selectBuild][paths.floor].allObj.add(Map_QM.man_3d);
|
|
}
|
|
}
|
|
this.pathArr = paths.PathPoint;
|
|
_selfFindPath = this;
|
|
if (Map_QM.util.pathStateObj.isPathPlay) {
|
|
this.pathPlay.isPlay = true;
|
|
}
|
|
};
|
|
/**
|
|
* 播放图标指引动画
|
|
*/
|
|
FindPath_QM.prototype.playMoveGuide = function () {
|
|
if (!Map_QM.guide) {
|
|
return;
|
|
}
|
|
let px = Map_QM.guide.position.x;
|
|
let py = Map_QM.guide.position.y;
|
|
let targetX = _selfFindPath.pathArr[_selfFindPath._index].x - px;
|
|
let targetY = -1 * _selfFindPath.pathArr[_selfFindPath._index].y - py;
|
|
let dist = Math.sqrt(targetX * targetX + targetY * targetY);
|
|
let df = Math.ceil(dist / (Map_QM.util.options.playSpeed * Map_QM.util.options.speedMult));
|
|
let dx = (_selfFindPath.pathArr[_selfFindPath._index].x - px) / df;
|
|
let dy = (-1 * _selfFindPath.pathArr[_selfFindPath._index].y - py) / df;
|
|
let ang = 0;
|
|
if (df < 2) {
|
|
Map_QM.guide.position.x = _selfFindPath.pathArr[_selfFindPath._index].x;
|
|
Map_QM.guide.position.y = -1 * _selfFindPath.pathArr[_selfFindPath._index].y;
|
|
Map_QM.moveCameraBy2D({x: _selfFindPath.pathArr[_selfFindPath._index].x, y: _selfFindPath.pathArr[_selfFindPath._index].y });
|
|
_selfFindPath._index++;
|
|
if (_selfFindPath._index > 0 && _selfFindPath._index < _selfFindPath.pathArr.length) {
|
|
Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = 0; //180;
|
|
let s = Math.sqrt(
|
|
(_selfFindPath.pathArr[_selfFindPath._index].x - _selfFindPath.pathArr[_selfFindPath._index - 1].x) *
|
|
(_selfFindPath.pathArr[_selfFindPath._index].x - _selfFindPath.pathArr[_selfFindPath._index - 1].x) +
|
|
(_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y) *
|
|
(_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y)
|
|
);
|
|
ang = Math.acos((_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y) /s);
|
|
if ( _selfFindPath.pathArr[_selfFindPath._index].x < _selfFindPath.pathArr[_selfFindPath._index - 1].x) {
|
|
Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = Math.PI - ang;
|
|
} else {
|
|
Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = Math.PI + ang;
|
|
}
|
|
}
|
|
let pathShop = "";
|
|
for (let t = 0; t < Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop.length; t++) {
|
|
if (Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].pathIndex ==_selfFindPath._index) {
|
|
let shop_ = Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop;
|
|
pathShop = shop_.houseNumber;
|
|
let shops = Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop.floorOrder)].shopObj.children;
|
|
for (let i = 0; i < shops.length; i++) {
|
|
let _shop = shops[i].userData.shopData;
|
|
if (_shop && _shop.houseNumber == pathShop) {
|
|
let shopModel = shops[i];
|
|
let material = shopModel.material;
|
|
shopModel.material = new THREE.MeshBasicMaterial({
|
|
color: Map_QM.util.options.navColor,
|
|
});
|
|
TweenMax.to(shopModel.scale, 0.8, { z: 3, yoyo: true, ease: Cubic.easeIn,
|
|
onComplete: function () {
|
|
if (shopModel) {
|
|
TweenMax.to(shopModel.scale, 0.5, { z: 1 });
|
|
shopModel.material = material;
|
|
}
|
|
},
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
Map_QM.dispatchEvent({
|
|
//寻路中返回小人当前所在点位
|
|
type: "PathPlaying",
|
|
data: { houseNumber: pathShop },
|
|
});
|
|
} else {
|
|
px += dx;
|
|
py += dy;
|
|
Map_QM.guide.position.x = px;
|
|
Map_QM.guide.position.y = py;
|
|
Map_QM.moveCameraBy2D({ x: px, y: -1 * py });
|
|
}
|
|
|
|
if (_selfFindPath.pathPlay.isPlay && Map_QM.guide) {
|
|
if (_selfFindPath._index < _selfFindPath.pathArr.length) {
|
|
_selfFindPath.stop = requestAnimationFrame(_selfFindPath.playMoveGuide);
|
|
} else {
|
|
if (_selfFindPath && _selfFindPath.stop) {
|
|
window.cancelAnimationFrame(_selfFindPath.stop);
|
|
_selfFindPath.stop = null;
|
|
}
|
|
_selfFindPath._index = 0;
|
|
if (Map_QM.guide) {
|
|
Map_QM.guide.visible = false;
|
|
}
|
|
let myEvent = new CustomEvent("pathOver", {
|
|
detail: { dx: dx, dy: dy },
|
|
});
|
|
document.dispatchEvent(myEvent); //触发导航完成事件
|
|
_selfFindPath.pathState = "pathOver";
|
|
}
|
|
}
|
|
};
|
|
|