diff --git a/public/static/qm/MainMap_QM_go.js b/public/static/qm/MainMap_QM_go.js index 6c63d5e..08a0b92 100644 --- a/public/static/qm/MainMap_QM_go.js +++ b/public/static/qm/MainMap_QM_go.js @@ -1,5817 +1,6281 @@ -var Map_QM, renderFrame = -1, pathCameraState, stats, isJUZ = false, iot = true, shopTime, debug = false; +var Map_QM, + renderFrame = -1, + pathCameraState, + stats, + isJUZ = false, + iot = true, + shopTime, + debug = false //basePath 基础路径 graphPath最佳路径 ftPath 扶梯路径 dtPath 电梯路径 -var css_LR = "color:#000000;height: 16px;font-size: 14px; z-index: 90; text-shadow: 1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff; pointer-events:none;"; - -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: '白石龙' }]; +var css_LR = + 'color:#000000;height: 16px;font-size: 14px; z-index: 90; text-shadow: 1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff; pointer-events:none;' + +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: '白石龙' } +] QMUtil = function () { - this.shopServerInfo = "static/offline/JSON/getMapInfo.json"; - this.mapServerInfo = "static/offline/JSON/getMap.json"; - this.beforPath = "./"; - this.options = { - playSpeed: 6, //动画播放速度 - collision: true, //是否支持名称的碰撞检测 - showStyle: false, //是否4K - 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: 5000, - fSpace: 500, //双叠层状态下楼层的间距 - maxDis: 1000, - minDis: 60, - shadow: true, //是否显示阴影 - navColor: 0xEE6A50, //途径店铺颜色 - aRadius: 2, //圆角半径 大于2 则店铺box显示圆角 - overlap: false, //是否叠层 - iconName: false, //图标名称是否显示 - mapScale: 18, //地图比例尺 - pathColor: 0xb47834, - pathStyle: "3D", - shopStyle: "shopName", //设置box显示名称shopName或编号shopNum - inArea: false, //点击后是否聚焦到店铺 - camZoom: 3, //设置我的方向状态地图放大倍数 - boxShop: [], //设置box上显示的文字(过滤指),可点击触发onlyShop - deviceAng: 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; - this._clock = new THREE.Clock(); - this._indexPathFloor = 0; // 遍历途径数据 - this.changeDist = { inner: 350, outner: 900 }; //室内外切换的极限值, 如果 inner小于minDis 则不支持缩放切换 - /** - * isPathState 寻路状态 - */ - this.pathStateObj = { isPathState: false, isPathPlay: true, basePath: "", graphPath: "", ftPath: "", dtPath: "", facAllArr: [], forShopArr: {}, elevator: null, straight: null, elevatorDown: null, seldtFacNo: "", seldownftFacNo: "", selupftFacNo: "" }; - this.timeObj = { timeS: 0, collTime: -1, pathTime: -1 }; - //debug 参数 相机坐标/ 镜头方向 - this.guiOptions = { cameraX: 0, cameraY: 200, cameraZ: 200, targatX: 0, targatY: 0, targatZ: 0 }; //this.button = function() {}; - - this.sceneGap = { x: -10, y: 0, z: 0, scale: 0.08 }; //改变地图位置,大小 - - this.selectBuild = 0; - this.selectFloor = 0; - this.deviceObj = {}; //angle --- 设备旋转角度 node ---- 设备导航点位 floor --- 设备楼层 - this.startObj = {}; // 导航起点; - this.overObj = {}; //导航结束点 - this.tubeMaterial = new THREE.MeshPhongMaterial({ color: this.options.pathColor, transparent: true, opacity: 0.6 }); //叠层的路径材质 - this.buildHeight = 5; - this.shopHeight = 30; //店铺高度 控制店铺相关的其它第三方组件高度 - //服务icon 英文配置 - this.iconEn = { "洗手间": "Toilets", "停车场": "Parking", "电梯": "Lift", "扶梯": "Escalator", "母婴室": "Baby care room", "服务台": "service desk" }; - //添加平铺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/model/jianfa.gltf",type:"out", scale:0.038, rot:{x:0,y:30,z:0}, site:{x:-20,y:-100,z:20}, colorModel:"gama" }]; - */ - this.initModelArr = []; // - /** - * 一直显示不隐藏, 在楼层内显示 - */ - 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': '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': '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': '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': '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: "

进入商场

", x: 55, y: 12, z: 3, click: true, type: "out" } - */ - this.tipArr = []; //模型标签 periphery - /** - * 室内地图标签 - * Map_QM.util.labelIconArr([{floor:0,title:'', 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 = []; - this.isInnerTouch = true; //室内地图是否可点击 - /*** ------------------------------------------------ 参数 API START ------------------------------------------------- */ - this.setModelState = function (state = "3d") { //设置模型显示状态 2d 3d - if (Map_QM) { - Map_QM.renderer.clear(); - Map_QM.changeIconState(state); - } - } - - 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(speed) 改变导航速度 - * @apiGroup 地图交互 - * @apiDescription 改变导航播放速度 - * @apiVersion 2.0.0 - * - * @apiParam {int} speed 播放速度(默认 6) - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.util.changePlaySpeed(6) - * - */ - this.changePlaySpeed = function (speed = 6) { - Map_QM.util.options.playSpeed = speed; - } - /*** ----------------------------------------------- 参数 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(); + this.shopServerInfo = 'static/offline/JSON/getMapInfo.json' + this.mapServerInfo = 'static/offline/JSON/getMap.json' + this.beforPath = './' + this.options = { + playSpeed: 6, //动画播放速度 + collision: true, //是否支持名称的碰撞检测 + showStyle: false, //是否4K + 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: 5000, + fSpace: 500, //双叠层状态下楼层的间距 + maxDis: 1000, + minDis: 60, + shadow: true, //是否显示阴影 + navColor: 0xee6a50, //途径店铺颜色 + aRadius: 2, //圆角半径 大于2 则店铺box显示圆角 + overlap: false, //是否叠层 + iconName: false, //图标名称是否显示 + mapScale: 18, //地图比例尺 + pathColor: 0xb47834, + pathStyle: '3D', + shopStyle: 'shopName', //设置box显示名称shopName或编号shopNum + inArea: false, //点击后是否聚焦到店铺 + camZoom: 3, //设置我的方向状态地图放大倍数 + boxShop: [], //设置box上显示的文字(过滤指),可点击触发onlyShop + deviceAng: 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 + this._clock = new THREE.Clock() + this._indexPathFloor = 0 // 遍历途径数据 + this.changeDist = { inner: 350, outner: 900 } //室内外切换的极限值, 如果 inner小于minDis 则不支持缩放切换 + /** + * isPathState 寻路状态 + */ + this.pathStateObj = { + isPathState: false, + isPathPlay: true, + basePath: '', + graphPath: '', + ftPath: '', + dtPath: '', + facAllArr: [], + forShopArr: {}, + elevator: null, + straight: null, + elevatorDown: null, + seldtFacNo: '', + seldownftFacNo: '', + selupftFacNo: '' + } + this.timeObj = { timeS: 0, collTime: -1, pathTime: -1 } + //debug 参数 相机坐标/ 镜头方向 + this.guiOptions = { cameraX: 0, cameraY: 200, cameraZ: 200, targatX: 0, targatY: 0, targatZ: 0 } //this.button = function() {}; + + this.sceneGap = { x: -10, y: 0, z: 0, scale: 0.08 } //改变地图位置,大小 + + this.selectBuild = 0 + this.selectFloor = 0 + this.deviceObj = {} //angle --- 设备旋转角度 node ---- 设备导航点位 floor --- 设备楼层 + this.startObj = {} // 导航起点; + this.overObj = {} //导航结束点 + this.tubeMaterial = new THREE.MeshPhongMaterial({ color: this.options.pathColor, transparent: true, opacity: 0.6 }) //叠层的路径材质 + this.buildHeight = 5 + this.shopHeight = 30 //店铺高度 控制店铺相关的其它第三方组件高度 + //服务icon 英文配置 + this.iconEn = { 洗手间: 'Toilets', 停车场: 'Parking', 电梯: 'Lift', 扶梯: 'Escalator', 母婴室: 'Baby care room', 服务台: 'service desk' } + //添加平铺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/model/jianfa.gltf",type:"out", scale:0.038, rot:{x:0,y:30,z:0}, site:{x:-20,y:-100,z:20}, colorModel:"gama" }]; + */ + this.initModelArr = [] // + /** + * 一直显示不隐藏, 在楼层内显示 + */ + 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: '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: '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: '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: '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: "

进入商场

", x: 55, y: 12, z: 3, click: true, type: "out" } + */ + this.tipArr = [] //模型标签 periphery + /** + * 室内地图标签 + * Map_QM.util.labelIconArr([{floor:0,title:'', 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 = [] + this.isInnerTouch = true //室内地图是否可点击 + /*** ------------------------------------------------ 参数 API START ------------------------------------------------- */ + this.setModelState = function (state = '3d') { + //设置模型显示状态 2d 3d + if (Map_QM) { + Map_QM.renderer.clear() + Map_QM.changeIconState(state) + } + } + + 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(speed) 改变导航速度 + * @apiGroup 地图交互 + * @apiDescription 改变导航播放速度 + * @apiVersion 2.0.0 + * + * @apiParam {int} speed 播放速度(默认 6) + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.util.changePlaySpeed(6) + * + */ + this.changePlaySpeed = function (speed = 6) { + Map_QM.util.options.playSpeed = speed + } + /*** ----------------------------------------------- 参数 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() var max = geometry.boundingBox.max, - min = geometry.boundingBox.min; - var offset = new THREE.Vector2(0 - min.x, 0 - min.y); - var range = new THREE.Vector2(max.x - min.x, max.y - min.y); - var faces = geometry.faces; - geometry.faceVertexUvs[0] = []; - for (var i = 0; i < faces.length ; i++) { - var v1 = geometry.vertices[faces[i].a], - v2 = geometry.vertices[faces[i].b], - v3 = geometry.vertices[faces[i].c]; - 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) - ]); - } - geometry.uvsNeedUpdate = true; + min = geometry.boundingBox.min + var offset = new THREE.Vector2(0 - min.x, 0 - min.y) + var range = new THREE.Vector2(max.x - min.x, max.y - min.y) + var faces = geometry.faces + geometry.faceVertexUvs[0] = [] + for (var i = 0; i < faces.length; i++) { + var v1 = geometry.vertices[faces[i].a], + v2 = geometry.vertices[faces[i].b], + v3 = geometry.vertices[faces[i].c] + 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) + ]) + } + geometry.uvsNeedUpdate = true + } + /** + * 检测点是否在多边形区域内 + */ + 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.request = function (params) { + params.method = params.method || 'GET' + let xmlhttp = new XMLHttpRequest() + xmlhttp.onreadystatechange = function () { + if (xmlhttp.readyState === 4 && xmlhttp.status === 200) { + ////console.log(xmlhttp.responseText); + let data = Map_QM.util.decrypt(xmlhttp.responseText) + let jsonObject = JSON.parse(data) + params.success(jsonObject) + } + if (xmlhttp.readyState === 4 && (xmlhttp.status === 404 || xmlhttp.status === 405)) { + params.fail() + } + } + xmlhttp.onerror = function (e) { + params.fail() + } + xmlhttp.open(params.method, params.url, true) + xmlhttp.setRequestHeader('Access-Control-Allow-Origin', '*') + xmlhttp.setRequestHeader('Content-type', 'application/json') + xmlhttp.setRequestHeader('Access-Control-Allow-Method', 'POST,GET') + xmlhttp.send(params.data) + } + 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) { + params.fail() + return + } + params.success(jsonObject) + } + if (xmlhttp.readyState === 4 && (xmlhttp.status === 404 || xmlhttp.status === 405)) { + params.fail() + } + } + xmlhttp.onerror = function (e) { + params.fail() + } + xmlhttp.open(params.method, params.url, true) + xmlhttp.setRequestHeader('Access-Control-Allow-Origin', '*') + xmlhttp.setRequestHeader('Content-type', 'application/json') + xmlhttp.setRequestHeader('Access-Control-Allow-Method', 'POST,GET') + xmlhttp.send(params.data) + } + + //加密 + this.encrypt = function (word, keyStr) { + keyStr = keyStr ? keyStr : '0123456789QMSaas' + var key = CryptoJS.enc.Utf8.parse(keyStr) //Latin1 w8m31+Yy/Nw6thPsMpO5fg== + var srcs = CryptoJS.enc.Utf8.parse(word) + var encrypted = CryptoJS.AES.encrypt(srcs, key, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }) + return encrypted.toString() + } + //解密 + this.decrypt = function (word, keyStr) { + keyStr = keyStr ? keyStr : '0123456789QMSaas' + 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) { + //console.log(e); + } + } + } + rawFile.onerror = function () { + callBack(null) + } + rawFile.send(null) + } + + this.blocked = (dom, checkList, cfloor, topAd = 0, leftAd = 0) => { + const { top, left, right, bottom } = dom.getBoundingClientRect() + let corners = [ + [left + leftAd, top + topAd], + [right - leftAd, top + topAd], + [left + leftAd, bottom - topAd], + [right - leftAd, bottom - topAd] + ] + + for (let i = 0; i < corners.length; i++) { + const [x, y] = corners[i] + const raycaster = new THREE.Raycaster() + const p = new THREE.Vector2() + let ele = document.getElementById(options.containerId || 'mapContainer') + p.x = (x / parseInt(ele.clientWidth)) * 2 - 1 + p.y = -(y / parseInt(ele.clientHeight)) * 2 + 1 + + raycaster.setFromCamera(p, Map_QM.camera) + let intersects = raycaster.intersectObjects(checkList) + for (let t = 0; t < intersects.length; t++) { + if (intersects[t].object.userData.order > cfloor) { + return true + } + } + } + return false + } + //绘制3D线 传入起点(3D坐标)、终点(3D坐标)、控制点1、控制点2(如没有则绘制直线) + this.drawDashedLine = function (startPoint, endPoint, dash = 50, color = 0x2269dd, ctrlPoint1 = null, ctrlPoint2 = null) { + //THREE.Vector3 + let gopObj = new THREE.Group() + let curve + if (!ctrlPoint1 && !ctrlPoint2) { + //控制点为空 + ctrlPoint1 = new THREE.Vector3( + startPoint.x + (endPoint.x - startPoint.x) / 4, + startPoint.y + (endPoint.y - startPoint.y) / 4, + startPoint.z + (endPoint.z - startPoint.z) / 4 + ) + ctrlPoint2 = new THREE.Vector3( + endPoint.x + (startPoint.x - endPoint.x) / 4, + endPoint.y + (startPoint.y - endPoint.y) / 4, + endPoint.z + (startPoint.z - endPoint.z) / 4 + ) + } + curve = new THREE.CubicBezierCurve3(startPoint, ctrlPoint1, ctrlPoint2, endPoint) + let points = curve.getPoints(dash) + let array = [] + points.forEach(element => { + array.push(element.x, element.y, element.z) + }) + let geometry = new THREE.LineSegmentsGeometry() + // 几何体传入顶点坐标 + geometry.setPositions(array) + // 自定义的材质 + let material = new THREE.LineMaterial({ + color: color, + linewidth: 4, + scale: 1, + dashSize: 1, + gapSize: 2 + }) + // 把渲染窗口尺寸分辨率传值给材质LineMaterial的resolution属性 + // resolution属性值会在着色器代码中参与计算 + material.resolution.set(window.innerWidth, window.innerHeight) + let mesh = new THREE.Mesh(geometry, material) + gopObj.add(mesh) + let jtArr = [] + if (Math.abs(endPoint.x - startPoint.x) > Math.abs(endPoint.y - startPoint.y)) { + jtArr.push(endPoint.x - 10, endPoint.y, endPoint.z + 10) + jtArr.push(endPoint.x, endPoint.y, endPoint.z) + jtArr.push(endPoint.x + 10, endPoint.y, endPoint.z + 10) + jtArr.push(endPoint.x, endPoint.y, endPoint.z) + jtArr.push(endPoint.x, endPoint.y, endPoint.z + 10) + } else { + jtArr.push(endPoint.x, endPoint.y - 10, endPoint.z + 10) + jtArr.push(endPoint.x, endPoint.y, endPoint.z) + jtArr.push(endPoint.x, endPoint.y + 10, endPoint.z + 10) + jtArr.push(endPoint.x, endPoint.y, endPoint.z) + jtArr.push(endPoint.x, endPoint.y, endPoint.z + 10) + } + let jtgeom = new THREE.LineGeometry() + jtgeom.setPositions(jtArr) + let jtmesh = new THREE.Mesh(jtgeom, material) + gopObj.add(jtmesh) + gopObj.userData.type = 'toLine' + return gopObj + } + /**碰撞检测 + * 传入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) { + 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.wordToSreen = function (world_vector) { + let vector = world_vector.project(Map_QM.camera) + let halfWidth = window.innerWidth / 2, + halfHeight = window.innerHeight / 2 + return { + x: Math.round(vector.x * halfWidth + halfWidth), + y: Math.round(-vector.y * halfHeight + halfHeight) + } + } + //////////////////////////////////////////////////////////////////////////////////////////// + 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.PointToLineDistance = function (xx, yy, x1, y1, x2, y2) { + let ang1, ang2, ang, m + let result = 0 + // 分别计算三条边的长度 + const a = Math.sqrt((x1 - xx) * (x1 - xx) + (y1 - yy) * (y1 - yy)) + if (a === 0) { + return [0, { x: x1, y: y1 }] + } + const b = Math.sqrt((x2 - xx) * (x2 - xx) + (y2 - yy) * (y2 - yy)) + if (b === 0) { + return [0, { x: x2, y: y2 }] + } + const c = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) + // 如果线段是一个点则退出函数并返回距离 + if (c === 0) { + result = a + return [result, { x: x1, y: y1 }] + } + // 如果点(xx, yy到点x1, y1)这条边短 + if (a < b) { + // 如果直线段AB是水平线。得到直线段AB的弧度 + if (y1 === y2) { + if (x1 < x2) { + ang1 = 0 + } else { + ang1 = Math.PI + } + } else { + m = (x2 - x1) / c + if (m - 1 > 0.00001) { + m = 1 + } + ang1 = Math.acos(m) + if (y1 > y2) { + ang1 = Math.PI * 2 - ang1 + } // 直线(x1, y1)-(x2, y2)与折X轴正向夹角的弧度 + } + m = (xx - x1) / a + if (m - 1 > 0.00001) { + m = 1 + } + ang2 = Math.acos(m) + if (y1 > yy) { + ang2 = Math.PI * 2 - ang2 + } // 直线(x1, y1)-(xx, yy)与折X轴正向夹角的弧度 + ang = ang2 - ang1 + if (ang < 0) { + ang = -ang + } + if (ang > Math.PI) { + ang = Math.PI * 2 - ang + } + // 如果是钝角则直接返回距离 + if (ang > Math.PI / 2) { + return [a, { x: x1, y: y1 }] + } + // 返回距离并且求得当前距离所在线段的坐标 + if (x1 === x2) { + return [b * Math.sin(ang), { x: x1, y: yy }] + } else if (y1 === y2) { + return [b * Math.sin(ang), { x: xx, y: y1 }] + } + // 直线的斜率存在且不为0的情况下 + let x = 0, + y = 0 + const k1 = (y2 - y1) / x2 - x1 + const kk = -1 / k1 + const bb = yy - xx * kk + const b1 = y2 - x2 * k1 + x = (b1 - bb) / (kk - k1) + y = kk * x + bb + return [a * Math.sin(ang), { x, y }] + } + // 如果两个点的纵坐标相同,则直接得到直线斜率的弧度 + if (y1 === y2) { + if (x1 < x2) { + ang1 = Math.PI + } else { + ang1 = 0 + } + } else { + m = (x1 - x2) / c + if (m - 1 > 0.00001) { + m = 1 + } + ang1 = Math.acos(m) + if (y2 > y1) { + ang1 = Math.PI * 2 - ang1 + } + } + m = (xx - x2) / b + if (m - 1 > 0.00001) { + m = 1 + } + ang2 = Math.acos(m) // 直线(x2-x1)-(xx, yy)斜率的弧度 + if (y2 > yy) { + ang2 = Math.PI * 2 - ang2 + } + ang = ang2 - ang1 + if (ang < 0) { + ang = -ang + } + if (ang > Math.PI) { + ang = Math.PI * 2 - ang + } // 交角的大小 + // 如果是对角则直接返回距离 + if (ang > Math.PI / 2) { + return [b, { x: x2, y: y2 }] + } + // 如果是锐角,返回计算得到的距离,并计算出相应的坐标 + if (x1 === x2) { + return [b * Math.sin(ang), { x: x1, y: yy }] + } else if (y1 === y2) { + return [b * Math.sin(ang), { x: xx, y: y1 }] + } + // 直线的斜率存在且不为0的情况下 + let x = 0, + y = 0 + const k1 = (y2 - y1) / x2 - x1 + const kk = -1 / k1 + const bb = yy - xx * kk + const b1 = y2 - x2 * k1 + x = (b1 - bb) / (kk - k1) + y = kk * x + bb + return [b * Math.sin(ang), { x, y }] + } + //点到直线距离 + this.PointToLineDis = function (xx, yy, x1, y1, x2, y2) { + let len + if (x1 - x2 == 0) { + len = Math.abs(xx - x1) + } else { + let A = (y1 - y2) / (x1 - x2) + let B = y1 - A * x1 + len = Math.abs((A * xx + B - yy) / Math.sqrt(A * A + 1)) + } + return len + } + ////////////////////////////////////////////////////////////////////////////---------------------------end + /** + * 根据色值获取材质 + */ + 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.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) + } + //对象克隆 + this.cloneObject = function (sourceObj) { + let target = sourceObj instanceof Array ? [] : {} + for (attr in sourceObj) { + if (!obj.hasOwnProperty(attr)) continue + target[attr] = typeof sourceObj[i] == 'object' ? obj[attr].clone() : obj[attr] + } + return target + } + //用于生成uuid + this.guid = function () { + function S4() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) + } + return S4() + S4() + S4() } - /** - * 检测点是否在多边形区域内 - */ - 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.request = function (params) { - params.method = params.method || 'GET'; - let xmlhttp = new XMLHttpRequest(); - xmlhttp.onreadystatechange = function () { - if (xmlhttp.readyState === 4 && xmlhttp.status === 200) { - ////console.log(xmlhttp.responseText); - let data = Map_QM.util.decrypt(xmlhttp.responseText); - let jsonObject = JSON.parse(data); - params.success(jsonObject); - } - if (xmlhttp.readyState === 4 && (xmlhttp.status === 404 || xmlhttp.status === 405)) { - params.fail(); - } - }; - xmlhttp.onerror = function (e) { - params.fail(); - }; - xmlhttp.open(params.method, params.url, true); - xmlhttp.setRequestHeader("Access-Control-Allow-Origin", "*"); - xmlhttp.setRequestHeader("Content-type", "application/json"); - xmlhttp.setRequestHeader("Access-Control-Allow-Method", "POST,GET"); - xmlhttp.send(params.data); - } - 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) { - params.fail(); - return; - } - params.success(jsonObject); - } - if (xmlhttp.readyState === 4 && (xmlhttp.status === 404 || xmlhttp.status === 405)) { - params.fail(); - } - }; - xmlhttp.onerror = function (e) { - params.fail(); - }; - xmlhttp.open(params.method, params.url, true); - xmlhttp.setRequestHeader("Access-Control-Allow-Origin", "*"); - xmlhttp.setRequestHeader("Content-type", "application/json"); - xmlhttp.setRequestHeader("Access-Control-Allow-Method", "POST,GET"); - xmlhttp.send(params.data); - } - - //加密 - this.encrypt = function (word, keyStr) { - keyStr = keyStr ? keyStr : "0123456789QMSaas"; - var key = CryptoJS.enc.Utf8.parse(keyStr); //Latin1 w8m31+Yy/Nw6thPsMpO5fg== - var srcs = CryptoJS.enc.Utf8.parse(word); - var encrypted = CryptoJS.AES.encrypt(srcs, key, { - mode: CryptoJS.mode.ECB, - padding: CryptoJS.pad.Pkcs7 - }); - return encrypted.toString(); - } - //解密 - this.decrypt = function (word, keyStr) { - keyStr = keyStr ? keyStr : "0123456789QMSaas"; - 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) { - //console.log(e); - } - } - } - rawFile.onerror = function () { - callBack(null); - } - rawFile.send(null); - } - - this.blocked = (dom, checkList, cfloor, topAd = 0, leftAd = 0) => { - const { top, left, right, bottom } = dom.getBoundingClientRect(); - let corners = [ - [left + leftAd, top + topAd], - [right - leftAd, top + topAd], - [left + leftAd, bottom - topAd], - [right - leftAd, bottom - topAd] - ]; - - for (let i = 0; i < corners.length; i++) { - const [x, y] = corners[i]; - const raycaster = new THREE.Raycaster(); - const p = new THREE.Vector2(); - let ele = document.getElementById(options.containerId || "mapContainer"); - p.x = (x / parseInt(ele.clientWidth)) * 2 - 1; - p.y = -(y / parseInt(ele.clientHeight)) * 2 + 1; - - raycaster.setFromCamera(p, Map_QM.camera); - let intersects = raycaster.intersectObjects(checkList); - for (let t = 0; t < intersects.length; t++) { - if (intersects[t].object.userData.order > cfloor) { - return true; - } - } - } - return false; - } - //绘制3D线 传入起点(3D坐标)、终点(3D坐标)、控制点1、控制点2(如没有则绘制直线) - this.drawDashedLine = function (startPoint, endPoint, dash = 50, color = 0x2269dd, ctrlPoint1 = null, ctrlPoint2 = null) { //THREE.Vector3 - let gopObj = new THREE.Group(); - let curve; - if (!ctrlPoint1 && !ctrlPoint2) { //控制点为空 - ctrlPoint1 = new THREE.Vector3(startPoint.x + (endPoint.x - startPoint.x) / 4, startPoint.y + (endPoint.y - startPoint.y) / 4, startPoint.z + (endPoint.z - startPoint.z) / 4); - ctrlPoint2 = new THREE.Vector3(endPoint.x + (startPoint.x - endPoint.x) / 4, endPoint.y + (startPoint.y - endPoint.y) / 4, endPoint.z + (startPoint.z - endPoint.z) / 4); - } - curve = new THREE.CubicBezierCurve3(startPoint, ctrlPoint1, ctrlPoint2, endPoint); - let points = curve.getPoints(dash); - let array = []; - points.forEach(element => { - array.push(element.x, element.y, element.z); - }); - let geometry = new THREE.LineSegmentsGeometry(); - // 几何体传入顶点坐标 - geometry.setPositions(array); - // 自定义的材质 - let material = new THREE.LineMaterial({ - color: color, - linewidth: 4, - scale: 1, - dashSize: 1, - gapSize: 2, - }); - // 把渲染窗口尺寸分辨率传值给材质LineMaterial的resolution属性 - // resolution属性值会在着色器代码中参与计算 - material.resolution.set(window.innerWidth, window.innerHeight); - let mesh = new THREE.Mesh(geometry, material); - gopObj.add(mesh); - let jtArr = []; - if (Math.abs(endPoint.x - startPoint.x) > Math.abs(endPoint.y - startPoint.y)) { - jtArr.push(endPoint.x - 10, endPoint.y, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x + 10, endPoint.y, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x, endPoint.y, endPoint.z + 10); - } else { - jtArr.push(endPoint.x, endPoint.y - 10, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x, endPoint.y + 10, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x, endPoint.y, endPoint.z + 10); - } - let jtgeom = new THREE.LineGeometry(); - jtgeom.setPositions(jtArr); - let jtmesh = new THREE.Mesh(jtgeom, material); - gopObj.add(jtmesh); - gopObj.userData.type = "toLine"; - return gopObj; - } - /**碰撞检测 - * 传入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) { - 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.wordToSreen = function (world_vector) { - let vector = world_vector.project(Map_QM.camera); - let halfWidth = window.innerWidth / 2, halfHeight = window.innerHeight / 2; - return { - x: Math.round(vector.x * halfWidth + halfWidth), - y: Math.round(-vector.y * halfHeight + halfHeight) - }; - } - //////////////////////////////////////////////////////////////////////////////////////////// - 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.PointToLineDistance = function (xx, yy, x1, y1, x2, y2) { - let ang1, ang2, ang, m; - let result = 0; - // 分别计算三条边的长度 - const a = Math.sqrt((x1 - xx) * (x1 - xx) + (y1 - yy) * (y1 - yy)); - if (a === 0) { - return [0, { x: x1, y: y1 }]; - } - const b = Math.sqrt((x2 - xx) * (x2 - xx) + (y2 - yy) * (y2 - yy)); - if (b === 0) { - return [0, { x: x2, y: y2 }]; - } - const c = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); - // 如果线段是一个点则退出函数并返回距离 - if (c === 0) { - result = a; - return [result, { x: x1, y: y1 }]; - } - // 如果点(xx, yy到点x1, y1)这条边短 - if (a < b) { - // 如果直线段AB是水平线。得到直线段AB的弧度 - if (y1 === y2) { - if (x1 < x2) { - ang1 = 0; - } else { - ang1 = Math.PI; - } - } else { - m = (x2 - x1) / c; - if (m - 1 > 0.00001) { - m = 1; - } - ang1 = Math.acos(m); - if (y1 > y2) { - ang1 = Math.PI * 2 - ang1; - }// 直线(x1, y1)-(x2, y2)与折X轴正向夹角的弧度 - } - m = (xx - x1) / a; - if (m - 1 > 0.00001) { - m = 1; - } - ang2 = Math.acos(m); - if (y1 > yy) { - ang2 = Math.PI * 2 - ang2; - }// 直线(x1, y1)-(xx, yy)与折X轴正向夹角的弧度 - ang = ang2 - ang1; - if (ang < 0) { - ang = -ang; - } - if (ang > Math.PI) { - ang = Math.PI * 2 - ang; - } - // 如果是钝角则直接返回距离 - if (ang > Math.PI / 2) { - return [a, { x: x1, y: y1 }]; - } - // 返回距离并且求得当前距离所在线段的坐标 - if (x1 === x2) { - return [b * Math.sin(ang), { x: x1, y: yy }]; - } else if (y1 === y2) { - return [b * Math.sin(ang), { x: xx, y: y1 }]; - } - // 直线的斜率存在且不为0的情况下 - let x = 0, y = 0; - const k1 = ((y2 - y1) / x2 - x1); - const kk = -1 / k1; - const bb = yy - xx * kk; - const b1 = y2 - x2 * k1; - x = (b1 - bb) / (kk - k1); - y = kk * x + bb; - return [a * Math.sin(ang), { x, y }]; - } - // 如果两个点的纵坐标相同,则直接得到直线斜率的弧度 - if (y1 === y2) { - if (x1 < x2) { - ang1 = Math.PI; - } else { - ang1 = 0; - } - } else { - m = (x1 - x2) / c; - if (m - 1 > 0.00001) { - m = 1; - } - ang1 = Math.acos(m); - if (y2 > y1) { - ang1 = Math.PI * 2 - ang1; - } - } - m = (xx - x2) / b; - if (m - 1 > 0.00001) { - m = 1; - } - ang2 = Math.acos(m);// 直线(x2-x1)-(xx, yy)斜率的弧度 - if (y2 > yy) { - ang2 = Math.PI * 2 - ang2; - } - ang = ang2 - ang1; - if (ang < 0) { - ang = -ang; - } - if (ang > Math.PI) { - ang = Math.PI * 2 - ang; - }// 交角的大小 - // 如果是对角则直接返回距离 - if (ang > Math.PI / 2) { - return [b, { x: x2, y: y2 }]; - } - // 如果是锐角,返回计算得到的距离,并计算出相应的坐标 - if (x1 === x2) { - return [b * Math.sin(ang), { x: x1, y: yy }]; - } else if (y1 === y2) { - return [b * Math.sin(ang), { x: xx, y: y1 }]; - } - // 直线的斜率存在且不为0的情况下 - let x = 0, y = 0; - const k1 = ((y2 - y1) / x2 - x1); - const kk = -1 / k1; - const bb = yy - xx * kk; - const b1 = y2 - x2 * k1; - x = (b1 - bb) / (kk - k1); - y = kk * x + bb; - return [b * Math.sin(ang), { x, y }]; - } - //点到直线距离 - this.PointToLineDis = function (xx, yy, x1, y1, x2, y2) { - let len; - if (x1 - x2 == 0) { - len = Math.abs(xx - x1); - } else { - let A = (y1 - y2) / (x1 - x2); - let B = y1 - A * x1; - len = Math.abs((A * xx + B - yy) / Math.sqrt(A * A + 1)) - } - return len; - } - ////////////////////////////////////////////////////////////////////////////---------------------------end - /** - * 根据色值获取材质 - */ - 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.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); - } - //对象克隆 - this.cloneObject = function (sourceObj) { - let target = (sourceObj instanceof Array) ? [] : {}; - for (attr in sourceObj) { - if (!obj.hasOwnProperty(attr)) continue; - target[attr] = (typeof sourceObj[i] == "object") ? obj[attr].clone() : obj[attr]; - } - return target; - } - //用于生成uuid - this.guid = function () { - function S4() { - return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); - } - return (S4() + S4() + S4()); - } } //////////////////////////////-------------------------------------------配置 UtilFun /** * 地图主类,入口 初始化设备点位 */ MainMap_QM = function (callBack, options) { - this.util = new QMUtil(); - this.callBackLoadOver = callBack; - let ele = document.getElementById(options.containerId || "mapContainer"); - this.w = parseInt(ele.clientWidth) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('width')) - this.h = parseInt(ele.clientHeight) || parseInt(window.getComputedStyle(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.guiOptions.cameraX, this.util.guiOptions.cameraY, this.util.guiOptions.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.guiOptions.cameraX, this.util.guiOptions.cameraY, this.util.guiOptions.cameraZ); - this.cameraOrtho.lookAt(new THREE.Vector3(0, 0, 0)); - this.camera = this.cameraPerspective; - // - this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, preserveDrawingBuffer: true }); // preserveDrawingBuffer 是否可以截图 - //this.renderer.outputEncoding = THREE.sRGBEncoding; - this.renderer.setSize(this.w, this.h); - this.renderer.setPixelRatio(window.devicePixelRatio); - this.renderer.shadowMap.enabled = true; - // 阴影类型 - this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; - ele.appendChild(this.renderer.domElement); - - 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; - 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, 1); - 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.shawLight.castShadow = this.util.options.shadow; //阴影 - this.shawLight.shadow.camera.top = 200; - this.shawLight.shadow.camera.bottom = -200; - this.shawLight.shadow.camera.right = 200; - this.shawLight.shadow.camera.left = -200; - this.shawLight.shadow.camera.far = 800; - this.shawLight.shadow.camera.near = 100; - this.shawLight.shadow.bias = -0.001; - this.shawLight.shadow.darkness = 0.3; - this.shawLight.shadow.mapSize.set(2048, 2048); - this.scene.add(this.shawLight); - - this.mixers = []; - this.controls = new THREE.OrbitControls(this.camera, ele); - //鼠标控制 - //this.controls.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT }; - //this.controls.enabled = true; - this.controls.minZoom = 0.8; - this.controls.maxZoom = this.util.options.camZoom; - //设置相机距离原点的最远距离 - 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 - - if (debug) { - stats = new Stats(); - stats.setMode(1); // 0: fps, 1: ms - stats.domElement.style.position = 'absolute'; //绝对坐标 - stats.domElement.style.left = '10px'; // (0,0)px,左上角 - stats.domElement.style.top = '60px'; - document.getElementById(options.containerId || "mapContainer").appendChild(stats.domElement); - } - - document.getElementById(options.containerId || "mapContainer").addEventListener('click', this.onMouseClickBox, false); //地图点击 - document.addEventListener('rezise', this.changeDocmentResize, false); //窗口变化 - 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')) { - this.moveFloorbg = new THREE.CSS2DObject(document.getElementById('moveFloorBG')); - this.scene.add(this.moveFloorbg); - } - this.man_3d; - this.man_2d; - this.guide; - 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.buildObj = new THREE.Group(); - this.qiModel; //起点 - this.qiIcon; //起点Icon - this.dirIcon; //我的方向Icon - this.endIcon; //终点Icon - this.endModel; - this.forShopArr = []; //途径数据 - this.getInstance(options); + this.util = new QMUtil() + this.callBackLoadOver = callBack + let ele = document.getElementById(options.containerId || 'mapContainer') + this.w = parseInt(ele.clientWidth) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('width')) + this.h = parseInt(ele.clientHeight) || parseInt(window.getComputedStyle(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.guiOptions.cameraX, this.util.guiOptions.cameraY, this.util.guiOptions.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.guiOptions.cameraX, this.util.guiOptions.cameraY, this.util.guiOptions.cameraZ) + this.cameraOrtho.lookAt(new THREE.Vector3(0, 0, 0)) + this.camera = this.cameraPerspective + // + this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, preserveDrawingBuffer: true }) // preserveDrawingBuffer 是否可以截图 + //this.renderer.outputEncoding = THREE.sRGBEncoding; + this.renderer.setSize(this.w, this.h) + this.renderer.setPixelRatio(window.devicePixelRatio) + this.renderer.shadowMap.enabled = true + // 阴影类型 + this.renderer.shadowMap.type = THREE.PCFSoftShadowMap + ele.appendChild(this.renderer.domElement) + + 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 + 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, 1) + 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.shawLight.castShadow = this.util.options.shadow //阴影 + this.shawLight.shadow.camera.top = 200 + this.shawLight.shadow.camera.bottom = -200 + this.shawLight.shadow.camera.right = 200 + this.shawLight.shadow.camera.left = -200 + this.shawLight.shadow.camera.far = 800 + this.shawLight.shadow.camera.near = 100 + this.shawLight.shadow.bias = -0.001 + this.shawLight.shadow.darkness = 0.3 + this.shawLight.shadow.mapSize.set(2048, 2048) + this.scene.add(this.shawLight) + + this.mixers = [] + this.controls = new THREE.OrbitControls(this.camera, ele) + //鼠标控制 + //this.controls.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT }; + //this.controls.enabled = true; + this.controls.minZoom = 0.8 + this.controls.maxZoom = this.util.options.camZoom + //设置相机距离原点的最远距离 + 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 + + if (debug) { + stats = new Stats() + stats.setMode(1) // 0: fps, 1: ms + stats.domElement.style.position = 'absolute' //绝对坐标 + stats.domElement.style.left = '10px' // (0,0)px,左上角 + stats.domElement.style.top = '60px' + document.getElementById(options.containerId || 'mapContainer').appendChild(stats.domElement) + } + + document.getElementById(options.containerId || 'mapContainer').addEventListener('click', this.onMouseClickBox, false) //地图点击 + document.addEventListener('rezise', this.changeDocmentResize, false) //窗口变化 + 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')) { + this.moveFloorbg = new THREE.CSS2DObject(document.getElementById('moveFloorBG')) + this.scene.add(this.moveFloorbg) + } + this.man_3d + this.man_2d + this.guide + 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.buildObj = new THREE.Group() + this.qiModel //起点 + this.qiIcon //起点Icon + this.dirIcon //我的方向Icon + this.endIcon //终点Icon + this.endModel + this.forShopArr = [] //途径数据 + this.getInstance(options) } MainMap_QM.prototype = { - 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(); - let token = encodeURIComponent(this.util.encrypt("/api/CDN/GetMapInfo" + tim)); - this.util.requestNoJM({ - method: "POST", - data: JSON.stringify({ "mallCode": options.mallCode, "key": "Zeditor" }), - url: options.url + '/api/CDN/GetMapInfo?token=' + token + '&time=' + tim, - success: (res) => { - if (res.code == "200" && res.data) { - try { - _space.util.allMap = JSON.parse(LZString.decompressFromBase64(res.data.mapData)); - console.log("地图数据更新时间: " + res.data.updateTime); - _space.initOptions(options); - } catch (e) { - _space.backObj.code = 404; - _space.backObj.msg = "地图数据JSON格式错误"; - } - tim = _space.util.timeStamp(); - token = encodeURIComponent(_space.util.encrypt("/api/Shop/QueryShopListForMap" + tim)); - let param = _space.util.encrypt(JSON.stringify({ "mallCode": options.mallCode, "BuildingOrder": options.build })); - _space.util.request({ - method: "POST", - data: param, - url: options.url + '/api/Shop/QueryShopListForMap?token=' + token + '&time=' + tim, - success: (res) => { - if (res.code == "200") { - _space.util.shopData = []; - if (Array.isArray(res.data)) { - for (let i = 0; i < res.data.length; i++) { - for (let n = 0; n < res.data[i].shopList.length; n++) { - res.data[i].shopList[n].buildingOrder = options.build; - _space.util.shopData.push(res.data[i].shopList[n]); - } - } - } else { - _space.backObj.code = 500; - _space.backObj.msg = "店铺数据解析失败"; - } - } else { - _space.backObj.code = 500; - _space.backObj.msg = "店铺数据解析失败"; - } - _space.initOutModel(); - }, - fail: () => { - try { - _space.initOutModel(); - } catch (e) { - _space.backObj.code = 404; - _space.backObj.msg = "地图数据解析失败"; - } - if (_space.backObj.code == 404) { - _space.callBackLoadOver(_space.backObj); - _space.callBackLoadOver = null; - } - } - }); - } else { - _space.backObj.code = 404; - _space.backObj.msg = "地图数据获取失败"; - _space.callBackLoadOver(_space.backObj); - _space.callBackLoadOver = null; - return; - } - }, - fail: () => { - _space.backObj.code = 404; - _space.backObj.msg = "地图数据获取失败"; - _space.callBackLoadOver(_space.backObj); - _space.callBackLoadOver = null; - } - }); - } else { - if (options.mapData) { - try { - if (options.mapData.mallKey != 'Zeditor') { - _space.util.allMap = JSON.parse(options.mapData.mapData) - } else { - _space.util.allMap = JSON.parse(LZString.decompressFromBase64(options.mapData.mapData)) - } - console.log("地图数据更新时间: " + options.mapData.updateTime); - _space.initOptions(options); - } catch (e) { - console.log(e) - backObj.code = 404 - backObj.msg = '地图数据JSON格式错误' - callBack(backObj) - callBack = null - } - _space.util.shopData = options.shopData; - let backObj = { "code": 200, msg: "加载成功", "data": [] }; - if (_space.util.shopData && Array.isArray(_space.util.shopData)) { - _space.util.shopData.sort(_space.util.sortShopByFloor); - } else { - backObj.code = 500; - backObj.msg = "店铺数据错误"; - } - try { - _space.initOutModel(); - } catch (e) { - console.log(e); - _space.callBackLoadOver({ "code": 404, "msg": "地图数据解析失败" }) - _space.callBackLoadOver = null; - } - } else { - _space.util.readTextFile(_space.util.beforPath + _space.util.mapServerInfo, function (res) { - try { - if (res.data.mallKey != "Zeditor") { - _space.util.allMap = JSON.parse(res.data.mapData); - } else { - _space.util.allMap = JSON.parse(LZString.decompressFromBase64(res.data.mapData)); - } - console.log("地图数据更新时间: " + res.data.updateTime); - _space.initOptions(options); - } catch (e) { - console.log(e); - _space.backObj.code = 404; - _space.backObj.msg = "地图数据JSON格式错误"; - _space.callBackLoadOver(_space.backObj); - _space.callBackLoadOver = null; - } - - _space.util.readTextFile(_space.util.beforPath + _space.util.shopServerInfo, function (res) { - console.log(res) - _space.util.shopData = res.data.shopList; - let backObj = { "code": 200, msg: "加载成功", "data": [] }; - if (_space.util.shopData && Array.isArray(_space.util.shopData)) { - _space.util.shopData.sort(_space.util.sortShopByFloor); - } else { - backObj.code = 500; - backObj.msg = "店铺数据错误"; - } - if (backObj.code == 404) { - _space.callBackLoadOver(backObj) - } - }); - try { - _space.initOutModel(); - } catch (e) { - _space.callBackLoadOver({ "code": 404, "msg": "地图数据解析失败" }) - _space.callBackLoadOver = null; - } - }); - } - } - if (debug) { - var gui = new dat.GUI() - gui.add(this.util.guiOptions, "cameraX", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "cameraY", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "cameraZ", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "targatX", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "targatY", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "targatZ", -500, 500).step(1).listen(); - //gui.add(options, 'button'); - } - }, - initOptions: function (options) { - //初始化参数 - if (this.util.allMap[this.util.selectBuild].playSpeed) { - this.util.options.mapScale = this.util.allMap[this.util.selectBuild].hasOwnProperty("scale") ? parseInt(this.util.allMap[this.util.selectBuild].scale) : 18; - this.util.options.playSpeed = this.util.allMap[this.util.selectBuild].hasOwnProperty("playSpeed") ? parseInt(this.util.allMap[this.util.selectBuild].playSpeed) : 6; - this.util.options.collision = this.util.allMap[this.util.selectBuild].hasOwnProperty("collision") ? this.util.allMap[this.util.selectBuild].collision : true; - this.util.options.navColor = this.util.allMap[this.util.selectBuild].hasOwnProperty("navColor") ? this.util.allMap[this.util.selectBuild].navColor : 0xEE6A50; - this.util.options.aRadius = this.util.allMap[this.util.selectBuild].hasOwnProperty("aRadius") ? parseInt(this.util.allMap[this.util.selectBuild].aRadius) : 2; - this.util.options.boxShop = this.util.allMap[this.util.selectBuild].hasOwnProperty("boxShop") ? this.util.allMap[this.util.selectBuild].boxShop.split(",") : []; - this.util.options.shopStyle = this.util.allMap[this.util.selectBuild].hasOwnProperty("shopStyle") ? this.util.allMap[this.util.selectBuild].shopStyle : "shopName"; - this.util.options.modelIcon = this.util.allMap[this.util.selectBuild].hasOwnProperty("modelIcon") ? this.util.allMap[this.util.selectBuild].modelIcon : true; - - 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.5; - 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.1; - - if(this.util.allMap[this.util.selectBuild].c_site && this.util.allMap[this.util.selectBuild].c_site.split(",")){ - this.util.guiOptions.cameraX = this.util.allMap[this.util.selectBuild].c_site.split(",")[0] || 0; - this.util.guiOptions.cameraY = this.util.allMap[this.util.selectBuild].c_site.split(",")[1] ?? 220; - this.util.guiOptions.cameraZ = this.util.allMap[this.util.selectBuild].c_site.split(",")[2] ?? 220; - } - if(this.util.allMap[this.util.selectBuild].m_site && this.util.allMap[this.util.selectBuild].m_site.split(",")){ - this.util.guiOptions.targatX = this.util.allMap[this.util.selectBuild].m_site.split(",")[0] || 0; - this.util.guiOptions.targatY = this.util.allMap[this.util.selectBuild].m_site.split(",")[1] || 0; - this.util.guiOptions.targatZ = this.util.allMap[this.util.selectBuild].m_site.split(",")[2] || 0; - } - if(this.util.allMap[this.util.selectBuild].m_zoom){ - this.util.m_zoom = this.util.allMap[this.util.selectBuild].m_zoom; - } - } - let { playSpeed = 6, collision = true, showStyle = false, modelIcon = true, shopStyle = "shopName", shadow = true, otherPath = [], navColor = 0xEE6A50, iconUrl = [], overlap = false, iconName = false, camZoom = 3, inArea = false, pathColor = 0xb47834, pathStyle = "3D" } = options; - this.util.options.playSpeed = playSpeed != 6 ? playSpeed : this.util.options.playSpeed; - this.util.options.collision = !collision ? collision : this.util.options.collision; - this.util.options.showStyle = showStyle ? showStyle : this.util.options.showStyle; - this.util.options.modelIcon = !modelIcon ? modelIcon : this.util.options.modelIcon; - this.util.options.shadow = !shadow ? shadow : this.util.options.shadow - this.util.options.shopStyle = shopStyle != "shopName" ? shopStyle : this.util.options.shopStyle; - this.util.options.otherPath = otherPath.length > 0 ? otherPath : []; - this.util.options.navColor = navColor != 0xEE6A50 ? navColor : this.util.options.navColor; - this.util.options.overlap = overlap ? overlap : this.util.options.overlap; - this.util.options.iconName = iconName ? iconName : this.util.options.iconName; - this.util.options.camZoom = camZoom != 3 ? camZoom : this.util.options.camZoom; - this.util.options.inArea = inArea ? inArea : this.util.options.inArea; - this.util.options.pathColor = pathColor != 0xb47834 ? pathColor : this.util.options.pathColor; - this.util.options.pathStyle = pathStyle != "3D" ? pathStyle : this.util.options.pathStyle; - this.util.iconUrl = 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; - } - } - } - } - - }, - //加载全局模型 - 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.castShadow = _this.util.options.shadow; - child.receiveShadow = _this.util.options.shadow; - child.userData.opacity = child.material.opacity; - if (_this.util.initModelArr[i].colorModel == "gama") { - if (child.material.map) { - child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码 - } - child.material.color.convertGammaToLinear(0.9); - } - } - }); - 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 = 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' - if (_this.util.tipArr[u].type == "out") { - _this.outModelGap.add(pointLabel2); - } else if (_this.util.tipArr[u].type == "periphery") { - _this.peripheryGap.add(pointLabel2); - } - } - _this.initBuild(); - } - } - } else { - _this.util.changeDist.inner = _this.util.options.maxDis; - _this.initBuild(); - } - }, - - initBuild: function (e) { - 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.gltf', function (collada2) { - collada2.scene.traverse(function (child2) { - if ( - child2.name == 'object_1' || - child2.name == 'object_2' || - child2.name == 'object_3' || - child2.name == 'object_4' || - child2.name == 'object_6' || - child2.name == 'object_11' || - child2.name == 'object_21' || - child2.name == 'object_31' || - child2.name == 'object_41' - ) { - child2.material = new THREE.MeshBasicMaterial({ color: 0xff464e, transparent: true }) - } - if (child2.name == 'object_5' || child2.name == 'object_51') { - child2.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }) - } - }) - collada2.scene.scale.x = collada2.scene.scale.y = collada2.scene.scale.z = 100 - collada2.scene.applyMatrix4(_this.buildObj.matrix) - collada2.scene.renderOrder = 200 - collada2.scene.name = "Z-model"; - _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(80, 80, 1) - _this.endIcon.center = new THREE.Vector2(0.5, 0) - _this.endIcon.position.set(0, 55, 0) - _this.endIcon.applyMatrix4(_this.buildObj.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 = 15; - collada.scene.rotation.x = -90 * Math.PI / -180; - collada.scene.renderOrder = 300; - _this.util.pathStateObj.elevator = collada.scene; - collada.scene.children[0].traverse(function (child) { - if (child.isMesh && child.name == "boli2") { - child.material.color = new THREE.Color(0xffffff); - child.material.opacity = 0.8; - } - if (child.isMesh && child.name == "pidai") { - child.material.color = new THREE.Color(0xffffff); - child.material.opacity = 0.8; - } - }); - 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 = 15; - collada.scene.rotation.x = -90 * Math.PI / -180; - collada.scene.renderOrder = 300; - _this.util.pathStateObj.elevatorDown = collada.scene; - collada.scene.traverse(function (child) { - if (child.isMesh && child.name == "boli1") { - child.material.color = new THREE.Color(0xffffff); - child.material.opacity = 0.8; - } - if (child.isMesh && child.name == "pidai") { - child.material.color = new THREE.Color(0xffffff); - child.material.opacity = 0.8; - } - }); - - 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 = 15; - collada.scene.rotation.x = -90 * Math.PI / -180; - collada.scene.renderOrder = 300; - _this.util.pathStateObj.straight = collada.scene; - //console.log(Map_QM.util.pathStateObj.straight); - _this.util.pathStateObj.straight.traverse(function (child) { - if (child.isMesh && child.name == "zhitiboli") { - child.material.color = new THREE.Color(0xffffff); - child.material.opacity = 0.6; - child.material.side = 1; - } - if (child.isMesh && child.name == "zhitijiegou") { - child.material.color = new THREE.Color(0xffffff); - child.material.opacity = 0.8; - } - }); - _this.index = 0; - _this.initTreeModel(); - }); - }); - }); - } else { - _this.index = 0; - _this.initTreeModel(); - } - }, - loaderOver: function (e) { - this.cancelRender(); - this.util.pathStateObj.basePath = null; - this.renderer.dispose(); - this.remove_child(this.sceneGap); - this.scene.remove(this.sceneGap); - this.sceneGap = new THREE.Group(); - this.sceneGap.position.set(this.util.sceneGap.x, this.util.sceneGap.y, this.util.sceneGap.z); - 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(); - this.buildObj.add(this.CSSObject); - this.buildObj.add(this.dtLineGroup); - this.initGuide(); - this.controls.target.set(this.util.guiOptions.targatX, this.util.guiOptions.targatY, this.util.guiOptions.targatZ); - 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); - 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] = 1000 + 600 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));; - if (this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.seldtFacNo) { - graphPathObj[facP][nP] = 300 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - } else { - graphPathObj[facP][nP] = 800 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - } - dtPathObj[facP][nP] = 1000 + 100 * 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] = 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - ftPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - dtPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - } else { - dtPathObj[facP][nP] = 1000 + 600 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - if (this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.selupftFacNo || this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.seldownftFacNo) { - graphPathObj[facP][nP] = 300 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - } else { - graphPathObj[facP][nP] = 800 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - } - ftPathObj[facP][nP] = 1000 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); - } - } - } - } - } - } catch (e) { - console.log("交通设施点位问题: " + e); - } - - this.util.pathStateObj.graphPath = graphPathObj; - this.util.pathStateObj.ftPath = ftPathObj; - this.util.pathStateObj.dtPath = dtPathObj; - 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, (fIndex - parseInt(Map_QM.util.deviceObj.floor)) * Map_QM.util.options.fSpace, 0); - 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); - this.controls.minPan = new THREE.Vector3(this.w / -10, 0, this.h / -10); - this.controls.maxPan = new THREE.Vector3(this.w / 10, 0, this.h / 10); - 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)); - } 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)) { - 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)); - } - } - this.initFloor(); - } else { - bIndex++; - fIndex = 0; - this.mapArr[bIndex] = []; - } - } - }, 50); - }, - initTreeModel: function () { - let url = Map_QM.util.beforPath + Map_QM.util.modelStr[this.index].url; - this.gltfLoad(url); - }, - gltfLoad: function (url) { - let sopce = this; - new THREE.GLTFLoader().load(url, function (object) {//加载路径fbx文件 - object.scene.traverse(function (child) { - if (child.type === "Mesh") { - child.castShadow = Map_QM.util.options.shadow; - child.receiveShadow = Map_QM.util.options.shadow; - if (child.material.map) { - child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码 - } - if (Map_QM.util.modelStr[sopce.index].colorModel === 'gama') { - child.material.color.convertGammaToLinear(0.6); - } - } - }); - object.scene.children[0].scale.set(Map_QM.util.modelStr[sopce.index].size.x, Map_QM.util.modelStr[sopce.index].size.y, Map_QM.util.modelStr[sopce.index].size.z); - Map_QM.util.fbxModels.push({ 'key': Map_QM.util.modelStr[sopce.index].key, 'obj': object.scene, 'operation': Map_QM.util.modelStr[sopce.index] }); - if (sopce.index < Map_QM.util.modelStr.length - 1) { - sopce.index++; - sopce.initTreeModel(); - } else { - if (Map_QM.util.allMap && Map_QM.util.allMap.length > 0) { - Map_QM.loaderOver(); - } - } - }); - }, - initGuide: function () { - new THREE.GLTFLoader().load(Map_QM.util.beforPath + "static/img/runman.gltf", function (obj) { - obj.scene.scale.x = obj.scene.scale.y = obj.scene.scale.z = 15; - obj.scene.children[0].children[1].children[0].material.color = new THREE.Color(0xfe9219); - Map_QM.sceneGap.add(obj.scene); - 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(); - Map_QM.mixers.push(mixer); - Map_QM.man_3d = obj.scene; - Map_QM.guide = Map_QM.man_3d; - }); - - new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/guide.png", textu => { - let planeMaterial = new THREE.MeshPhongMaterial({ - map: textu, - depthTest: true, - transparent: true, - alphaTest: 0.1 - }); - let planeGeometry = new THREE.PlaneGeometry(128, 128); - Map_QM.man_2d = new THREE.Mesh(planeGeometry, planeMaterial); - Map_QM.man_2d.center = new THREE.Vector2(0.5, 0.5); - Map_QM.man_2d.visible = false; - Map_QM.sceneGap.add(Map_QM.man_2d); - }); - }, - initFloor: function () { - if (Map_QM.util.initModelArr && Map_QM.util.initModelArr.length > 0) { - this.buildObj.visible = false; - } - Map_QM.changeBuild(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor); - Map_QM.controls.target.set(Map_QM.util.guiOptions.targatX, Map_QM.util.guiOptions.targatY, Map_QM.util.guiOptions.targatZ); - //初始化方向为第一人称方向 - let angle = Map_QM.util.options.deviceAng ? Map_QM.util.deviceObj.angle : 0; - Map_QM.rotationAngle(angle); - Map_QM.startRender(); - setTimeout(() => { -Map_QM.cameraPerspective.position.set(parseInt(Map_QM.util.guiOptions.cameraX), parseInt(Map_QM.util.guiOptions.cameraY), parseInt(Map_QM.util.guiOptions.cameraZ)); - Map_QM.cameraPerspective.updateProjectionMatrix(); //必须update - Map_QM.cameraOrtho.position.set(parseInt(Map_QM.util.guiOptions.cameraX), parseInt(Map_QM.util.guiOptions.cameraY), parseInt(Map_QM.util.guiOptions.cameraZ)); - Map_QM.controls.saveState(); - Map_QM.controls.addEventListener('change', this.controlsChock, false); //控制器变化 - }, 100) - }, - /** - * 解析路径 - */ - convertPath: function (buildOrder, floorOrder) { - let mapData = this.util.allMap[buildOrder].buildArr[floorOrder].mapData; - let pathData = mapData.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; - Map_QM.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; - } - Map_QM.util.pathStateObj.basePath += "\"" + buildOrder + "_" + floorOrder + "_" + b + "\":" + pathData.nodes[i]["list"][n].cost + ","; - } - if (pathData.nodes[i]["list"].length > 0) { - Map_QM.util.pathStateObj.basePath = Map_QM.util.pathStateObj.basePath.substr(0, Map_QM.util.pathStateObj.basePath.length - 1); - } - Map_QM.util.pathStateObj.basePath += "},"; - } - } - - let mindt = -1, minupft = -1, mindownft = -1; ///Map_QM.util.pathStateObj.selupftFacNo, Map_QM.util.pathStateObj.seldownftFacNo, - if (buildOrder == this.util.deviceObj.build && floorOrder == this.util.deviceObj.floor) { - if (pathData && !this.util.deviceObj.xaxis && 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 - } - for (let h = 0; h < mapData.stairs.length; h++) { - if (mapData.stairs[h].state && mapData.stairs[h].no != "") { - 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 == "dt") { - if (mindt == -1) { - mindt = ms; - Map_QM.util.pathStateObj.seldtFacNo = mapData.stairs[h].no; - } else { - if (mindt > ms) { - mindt = ms; - Map_QM.util.pathStateObj.seldtFacNo = mapData.stairs[h].no; - } - } - } else if (mapData.stairs[h].facCode == "upft" || mapData.stairs[h].downState) { //上扶梯 - if (minupft == -1) { - minupft = ms; - Map_QM.util.pathStateObj.selupftFacNo = mapData.stairs[h].no; - } else { - if (minupft > ms) { - minupft = ms; - Map_QM.util.pathStateObj.selupftFacNo = mapData.stairs[h].no; - } - } - } else if (mapData.stairs[h].facCode == "upft" || mapData.stairs[h].downState) { - if (mindownft == -1) { - mindownft = ms; - Map_QM.util.pathStateObj.seldownftFacNo = mapData.stairs[h].no; - } else { - if (mindownft > ms) { - mindownft = ms; - Map_QM.util.pathStateObj.seldownftFacNo = mapData.stairs[h].no; - } - } - } - } - } - } - - let noHas; - for (let j = 0; j < mapData.stairs.length; j++) { - if ((mapData.stairs[j].hasOwnProperty("state") && mapData.stairs[j].state) || !mapData.stairs[j].state) { //排除禁用的设施 - noHas = true; - for (let k = 0; k < Map_QM.util.pathStateObj.facAllArr.length; k++) { //Map_QM.util.pathStateObj.facAllArr 记录遍历结果 - if (Map_QM.util.pathStateObj.facAllArr[k][0].no != "" && Map_QM.util.pathStateObj.facAllArr[k][0].navCode != "" && Map_QM.util.pathStateObj.facAllArr[k][0].no == mapData.stairs[j].no) { - if (Map_QM.util.pathStateObj.facAllArr[k][0].facCode == mapData.stairs[j].facCode || (Map_QM.util.pathStateObj.facAllArr[k][0].facCode.search("ft") != -1 && mapData.stairs[j].facCode.search("ft") != -1)) { - noHas = false; - mapData.stairs[j].floorOrder = floorOrder; - mapData.stairs[j].buildOrder = buildOrder; - Map_QM.util.pathStateObj.facAllArr[k].push(mapData.stairs[j]); - } - } - } - if (noHas) { - mapData.stairs[j].buildOrder = buildOrder; - mapData.stairs[j].floorOrder = floorOrder; - let array = [mapData.stairs[j]]; - Map_QM.util.pathStateObj.facAllArr.push(array); - } - } - } - }, - /** - * @api {方法} changeMapState("3d") 地图状态切换 - * @apiGroup 地图显示 - * @apiDescription 地图展示状态切换 - * @apiVersion 2.0.0 - * @apiParam {string} state 地图状态 - * - * @apiSampleRequest off - * - * @apiParamExample {String} 请求示例 - * - * Map_QM.changeMapState("2d"); - * - */ - changeMapState: function (state) { - Map_QM.controls.reset(); - 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.camera.updateProjectionMatrix(); //必须update - Map_QM.camera.position.set(Map_QM.util.guiOptions.cameraX, Map_QM.util.guiOptions.cameraY, Map_QM.util.guiOptions.cameraZ); - 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.camera.updateProjectionMatrix(); //必须update - Map_QM.controls.maxPolarAngle = 0; - Map_QM.changeIconState(state); - } - }, - - changeIconState: function (state) { - for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { - 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; - } else { - obj.visible = true; - } - } - }); - } - if (Map_QM.dirIcon) { - Map_QM.dirIcon.visible = state == "2d" ? true : false; - } - if (Map_QM.qiModel) { - Map_QM.qiModel.visible = state == "2d" ? false : true; - } - if (Map_QM.qiIcon) { - Map_QM.qiIcon.visible = (state == "2d" && Map_QM.util.pathStateObj.isPathState) ? true : false; - } - }, - - /** - * @api {方法} changeBuild(buildOrder,floorOrder) 楼栋切换 - * @apiGroup 地图交互 - * @apiDescription 楼栋切换 传入楼栋编号,楼层编号 - * @apiVersion 2.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.resetFloorState(); - 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; - TweenMax.to(Map_QM.buildObj.position, 0.5, { - x: build * Map_QM.util.options.bSpace * -1, - onComplete: function () { - Map_QM.changeFloorInner(build, fIndex); //结束后切换楼层 - } - }); - }, - resetFloorState: function () { - 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.util.pathStateObj.forShopArr = { direction: "", wayList: [] }; - Map_QM.resetMeDir(); - 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 2.0.0 - * - * @apiParam {int} floorOrder 楼层编号 - * - * @apiSampleRequest off - * - * @apiParamExample {int} 请求示例 - * - * Map_QM.showFloor(1); - * - */ - showFloor: function (fIndex = -1, callBack = undefined) { - Map_QM.resetFloorState(); - Map_QM.clearFloor(fIndex); - if (fIndex != -1) { - Map_QM.changeFloorInner(-1, fIndex, callBack); - } - }, - /** - * @api {方法} changeFloorByName(floorOrder) 通过楼层名称切换楼层 - * @apiGroup 地图交互 - * @apiDescription 楼层切换,传入楼层名称, - * @apiVersion 2.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; - } - } - }, - changeFloorInner: function (build = -1, fIndex = -1, callBack = undefined, endIndex = -1, midIndex = -1) { - let addFloor = fIndex - Map_QM.util.deviceObj.floor > 0 ? 1 : -1; - 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].labelObj.traverse((obj) => { - obj.element && (obj.element.style.visibility = "hidden"); - }); - Map_QM.mapArr[t][i].tagObj.traverse((obj) => { - obj.element && (obj.element.style.visibility = "hidden"); - }); - Map_QM.mapArr[t][i].showTagObj.traverse((obj) => { - obj.element && (obj.element.style.visibility = "hidden"); - }); - } - } - if (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 || (i == midIndex && Map_QM.util.options.overlap) || (i == endIndex && Map_QM.util.options.overlap)) { - Map_QM.mapArr[build][i].allObj.visible = true; - Map_QM.mapArr[build][i].labelObj.traverse((obj) => { - obj.element && (obj.element.style.visibility = "visible") - }); - Map_QM.mapArr[build][i].showTagObj.traverse((obj) => { - obj.element && (obj.element.style.visibility = "visible"); - }); - } else { - Map_QM.mapArr[build][i].allObj.visible = false; - } - if (i == Map_QM.mapArr[build].length - 1) { - if (Map_QM.util.options.overlap) { //叠层 - if (midIndex === -1 && endIndex !== -1) { //两层 - Map_QM.mapArr[build][fIndex].allObj.position.y = fIndex < endIndex ? -1 * Map_QM.util.options.fSpace : Map_QM.util.options.fSpace; - Map_QM.mapArr[build][endIndex].allObj.position.y = fIndex > endIndex ? -1 * Map_QM.util.options.fSpace : Map_QM.util.options.fSpace; - Map_QM.timeOutInit(); - } else if (endIndex === -1) { //一层 - if (build == Map_QM.util.selectBuild && fIndex == Map_QM.util.selectFloor) { - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y = 0; - Map_QM.timeOutInit(); - if (callBack) callBack(); - } else { - Map_QM.util.selectBuild = build; - Map_QM.util.selectFloor = fIndex; - if (Map_QM.util.options.shadow) { - TweenMax.fromTo(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position, 0.3, { z: Map_QM.util.options.fSpace, y: 0 }, { - z: 0, y: 0, ease: Cubic.easeIn, onComplete: function () { - Map_QM.timeOutInit(); - if (callBack) callBack(); - } - }); - } else { - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y = 0; - Map_QM.timeOutInit() + 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() + let token = encodeURIComponent(this.util.encrypt('/api/CDN/GetMapInfo' + tim)) + this.util.requestNoJM({ + method: 'POST', + data: JSON.stringify({ mallCode: options.mallCode, key: 'Zeditor' }), + url: options.url + '/api/CDN/GetMapInfo?token=' + token + '&time=' + tim, + success: res => { + if (res.code == '200' && res.data) { + try { + _space.util.allMap = JSON.parse(LZString.decompressFromBase64(res.data.mapData)) + console.log('地图数据更新时间: ' + res.data.updateTime) + _space.initOptions(options) + } catch (e) { + _space.backObj.code = 404 + _space.backObj.msg = '地图数据JSON格式错误' + } + tim = _space.util.timeStamp() + token = encodeURIComponent(_space.util.encrypt('/api/Shop/QueryShopListForMap' + tim)) + let param = _space.util.encrypt(JSON.stringify({ mallCode: options.mallCode, BuildingOrder: options.build })) + _space.util.request({ + method: 'POST', + data: param, + url: options.url + '/api/Shop/QueryShopListForMap?token=' + token + '&time=' + tim, + success: res => { + if (res.code == '200') { + _space.util.shopData = [] + if (Array.isArray(res.data)) { + for (let i = 0; i < res.data.length; i++) { + for (let n = 0; n < res.data[i].shopList.length; n++) { + res.data[i].shopList[n].buildingOrder = options.build + _space.util.shopData.push(res.data[i].shopList[n]) + } + } + } else { + _space.backObj.code = 500 + _space.backObj.msg = '店铺数据解析失败' + } + } else { + _space.backObj.code = 500 + _space.backObj.msg = '店铺数据解析失败' + } + _space.initOutModel() + }, + fail: () => { + try { + _space.initOutModel() + } catch (e) { + _space.backObj.code = 404 + _space.backObj.msg = '地图数据解析失败' + } + if (_space.backObj.code == 404) { + _space.callBackLoadOver(_space.backObj) + _space.callBackLoadOver = null + } + } + }) + } else { + _space.backObj.code = 404 + _space.backObj.msg = '地图数据获取失败' + _space.callBackLoadOver(_space.backObj) + _space.callBackLoadOver = null + return + } + }, + fail: () => { + _space.backObj.code = 404 + _space.backObj.msg = '地图数据获取失败' + _space.callBackLoadOver(_space.backObj) + _space.callBackLoadOver = null + } + }) + } else { + if (options.mapData) { + try { + if (options.mapData.mallKey != 'Zeditor') { + _space.util.allMap = JSON.parse(options.mapData.mapData) + } else { + _space.util.allMap = JSON.parse(LZString.decompressFromBase64(options.mapData.mapData)) + } + console.log('地图数据更新时间: ' + options.mapData.updateTime) + _space.initOptions(options) + } catch (e) { + console.log(e) + backObj.code = 404 + backObj.msg = '地图数据JSON格式错误' + callBack(backObj) + callBack = null + } + _space.util.shopData = options.shopData + let backObj = { code: 200, msg: '加载成功', data: [] } + if (_space.util.shopData && Array.isArray(_space.util.shopData)) { + _space.util.shopData.sort(_space.util.sortShopByFloor) + } else { + backObj.code = 500 + backObj.msg = '店铺数据错误' + } + try { + _space.initOutModel() + } catch (e) { + console.log(e) + _space.callBackLoadOver({ code: 404, msg: '地图数据解析失败' }) + _space.callBackLoadOver = null + } + } else { + _space.util.readTextFile(_space.util.beforPath + _space.util.mapServerInfo, function (res) { + try { + if (res.data.mallKey != 'Zeditor') { + _space.util.allMap = JSON.parse(res.data.mapData) + } else { + _space.util.allMap = JSON.parse(LZString.decompressFromBase64(res.data.mapData)) + } + console.log('地图数据更新时间: ' + res.data.updateTime) + _space.initOptions(options) + } catch (e) { + console.log(e) + _space.backObj.code = 404 + _space.backObj.msg = '地图数据JSON格式错误' + _space.callBackLoadOver(_space.backObj) + _space.callBackLoadOver = null + } + + _space.util.readTextFile(_space.util.beforPath + _space.util.shopServerInfo, function (res) { + console.log(res) + _space.util.shopData = res.data.shopList + let backObj = { code: 200, msg: '加载成功', data: [] } + if (_space.util.shopData && Array.isArray(_space.util.shopData)) { + _space.util.shopData.sort(_space.util.sortShopByFloor) + } else { + backObj.code = 500 + backObj.msg = '店铺数据错误' + } + if (backObj.code == 404) { + _space.callBackLoadOver(backObj) + } + }) + try { + _space.initOutModel() + } catch (e) { + _space.callBackLoadOver({ code: 404, msg: '地图数据解析失败' }) + _space.callBackLoadOver = null + } + }) + } + } + if (debug) { + var gui = new dat.GUI() + gui.add(this.util.guiOptions, 'cameraX', -500, 500).step(1).listen() + gui.add(this.util.guiOptions, 'cameraY', -500, 500).step(1).listen() + gui.add(this.util.guiOptions, 'cameraZ', -500, 500).step(1).listen() + gui.add(this.util.guiOptions, 'targatX', -500, 500).step(1).listen() + gui.add(this.util.guiOptions, 'targatY', -500, 500).step(1).listen() + gui.add(this.util.guiOptions, 'targatZ', -500, 500).step(1).listen() + //gui.add(options, 'button'); + } + }, + initOptions: function (options) { + //初始化参数 + if (this.util.allMap[this.util.selectBuild].playSpeed) { + this.util.options.mapScale = this.util.allMap[this.util.selectBuild].hasOwnProperty('scale') ? parseInt(this.util.allMap[this.util.selectBuild].scale) : 18 + this.util.options.playSpeed = this.util.allMap[this.util.selectBuild].hasOwnProperty('playSpeed') ? parseInt(this.util.allMap[this.util.selectBuild].playSpeed) : 6 + this.util.options.collision = this.util.allMap[this.util.selectBuild].hasOwnProperty('collision') ? this.util.allMap[this.util.selectBuild].collision : true + this.util.options.navColor = this.util.allMap[this.util.selectBuild].hasOwnProperty('navColor') ? this.util.allMap[this.util.selectBuild].navColor : 0xee6a50 + this.util.options.aRadius = this.util.allMap[this.util.selectBuild].hasOwnProperty('aRadius') ? parseInt(this.util.allMap[this.util.selectBuild].aRadius) : 2 + this.util.options.boxShop = this.util.allMap[this.util.selectBuild].hasOwnProperty('boxShop') ? this.util.allMap[this.util.selectBuild].boxShop.split(',') : [] + this.util.options.shopStyle = this.util.allMap[this.util.selectBuild].hasOwnProperty('shopStyle') ? this.util.allMap[this.util.selectBuild].shopStyle : 'shopName' + this.util.options.modelIcon = this.util.allMap[this.util.selectBuild].hasOwnProperty('modelIcon') ? this.util.allMap[this.util.selectBuild].modelIcon : true + + 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.5 + 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.1 + + if (this.util.allMap[this.util.selectBuild].c_site && this.util.allMap[this.util.selectBuild].c_site.split(',')) { + this.util.guiOptions.cameraX = this.util.allMap[this.util.selectBuild].c_site.split(',')[0] || 0 + this.util.guiOptions.cameraY = this.util.allMap[this.util.selectBuild].c_site.split(',')[1] ?? 220 + this.util.guiOptions.cameraZ = this.util.allMap[this.util.selectBuild].c_site.split(',')[2] ?? 220 + } + if (this.util.allMap[this.util.selectBuild].m_site && this.util.allMap[this.util.selectBuild].m_site.split(',')) { + this.util.guiOptions.targatX = this.util.allMap[this.util.selectBuild].m_site.split(',')[0] || 0 + this.util.guiOptions.targatY = this.util.allMap[this.util.selectBuild].m_site.split(',')[1] || 0 + this.util.guiOptions.targatZ = this.util.allMap[this.util.selectBuild].m_site.split(',')[2] || 0 + } + if (this.util.allMap[this.util.selectBuild].m_zoom) { + this.util.m_zoom = this.util.allMap[this.util.selectBuild].m_zoom + } + } + let { + playSpeed = 6, + collision = true, + showStyle = false, + modelIcon = true, + shopStyle = 'shopName', + shadow = true, + otherPath = [], + navColor = 0xee6a50, + iconUrl = [], + overlap = false, + iconName = false, + camZoom = 3, + inArea = false, + pathColor = 0xb47834, + pathStyle = '3D' + } = options + this.util.options.playSpeed = playSpeed != 6 ? playSpeed : this.util.options.playSpeed + this.util.options.collision = !collision ? collision : this.util.options.collision + this.util.options.showStyle = showStyle ? showStyle : this.util.options.showStyle + this.util.options.modelIcon = !modelIcon ? modelIcon : this.util.options.modelIcon + this.util.options.shadow = !shadow ? shadow : this.util.options.shadow + this.util.options.shopStyle = shopStyle != 'shopName' ? shopStyle : this.util.options.shopStyle + this.util.options.otherPath = otherPath.length > 0 ? otherPath : [] + this.util.options.navColor = navColor != 0xee6a50 ? navColor : this.util.options.navColor + this.util.options.overlap = overlap ? overlap : this.util.options.overlap + this.util.options.iconName = iconName ? iconName : this.util.options.iconName + this.util.options.camZoom = camZoom != 3 ? camZoom : this.util.options.camZoom + this.util.options.inArea = inArea ? inArea : this.util.options.inArea + this.util.options.pathColor = pathColor != 0xb47834 ? pathColor : this.util.options.pathColor + this.util.options.pathStyle = pathStyle != '3D' ? pathStyle : this.util.options.pathStyle + this.util.iconUrl = 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 + } + } + } + } + }, + //加载全局模型 + 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.castShadow = _this.util.options.shadow + child.receiveShadow = _this.util.options.shadow + child.userData.opacity = child.material.opacity + if (_this.util.initModelArr[i].colorModel == 'gama') { + if (child.material.map) { + child.material.map.encoding = THREE.LinearEncoding //贴图需要转换成 线性编码 + } + child.material.color.convertGammaToLinear(0.9) + } + } + }) + 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 = 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' + if (_this.util.tipArr[u].type == 'out') { + _this.outModelGap.add(pointLabel2) + } else if (_this.util.tipArr[u].type == 'periphery') { + _this.peripheryGap.add(pointLabel2) + } + } + _this.initBuild() + } + } + } else { + _this.util.changeDist.inner = _this.util.options.maxDis + _this.initBuild() + } + }, + + initBuild: function (e) { + 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.gltf', function (collada2) { + collada2.scene.traverse(function (child2) { + if ( + child2.name == 'object_1' || + child2.name == 'object_2' || + child2.name == 'object_3' || + child2.name == 'object_4' || + child2.name == 'object_6' || + child2.name == 'object_11' || + child2.name == 'object_21' || + child2.name == 'object_31' || + child2.name == 'object_41' + ) { + child2.material = new THREE.MeshBasicMaterial({ color: 0xff464e, transparent: true }) + } + if (child2.name == 'object_5' || child2.name == 'object_51') { + child2.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }) + } + }) + collada2.scene.scale.x = collada2.scene.scale.y = collada2.scene.scale.z = 100 + collada2.scene.applyMatrix4(_this.buildObj.matrix) + collada2.scene.renderOrder = 200 + collada2.scene.name = 'Z-model' + _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(80, 80, 1) + _this.endIcon.center = new THREE.Vector2(0.5, 0) + _this.endIcon.position.set(0, 55, 0) + _this.endIcon.applyMatrix4(_this.buildObj.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 = 15 + collada.scene.rotation.x = (-90 * Math.PI) / -180 + collada.scene.renderOrder = 300 + _this.util.pathStateObj.elevator = collada.scene + collada.scene.children[0].traverse(function (child) { + if (child.isMesh && child.name == 'boli2') { + child.material.color = new THREE.Color(0xffffff) + child.material.opacity = 0.8 + } + if (child.isMesh && child.name == 'pidai') { + child.material.color = new THREE.Color(0xffffff) + child.material.opacity = 0.8 + } + }) + 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 = 15 + collada.scene.rotation.x = (-90 * Math.PI) / -180 + collada.scene.renderOrder = 300 + _this.util.pathStateObj.elevatorDown = collada.scene + collada.scene.traverse(function (child) { + if (child.isMesh && child.name == 'boli1') { + child.material.color = new THREE.Color(0xffffff) + child.material.opacity = 0.8 + } + if (child.isMesh && child.name == 'pidai') { + child.material.color = new THREE.Color(0xffffff) + child.material.opacity = 0.8 + } + }) + + 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 = 15 + collada.scene.rotation.x = (-90 * Math.PI) / -180 + collada.scene.renderOrder = 300 + _this.util.pathStateObj.straight = collada.scene + //console.log(Map_QM.util.pathStateObj.straight); + _this.util.pathStateObj.straight.traverse(function (child) { + if (child.isMesh && child.name == 'zhitiboli') { + child.material.color = new THREE.Color(0xffffff) + child.material.opacity = 0.6 + child.material.side = 1 + } + if (child.isMesh && child.name == 'zhitijiegou') { + child.material.color = new THREE.Color(0xffffff) + child.material.opacity = 0.8 + } + }) + _this.index = 0 + _this.initTreeModel() + }) + }) + }) + } else { + _this.index = 0 + _this.initTreeModel() + } + }, + loaderOver: function (e) { + this.cancelRender() + this.util.pathStateObj.basePath = null + this.renderer.dispose() + this.remove_child(this.sceneGap) + this.scene.remove(this.sceneGap) + this.sceneGap = new THREE.Group() + this.sceneGap.position.set(this.util.sceneGap.x, this.util.sceneGap.y, this.util.sceneGap.z) + 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() + this.buildObj.add(this.CSSObject) + this.buildObj.add(this.dtLineGroup) + this.initGuide() + this.controls.target.set(this.util.guiOptions.targatX, this.util.guiOptions.targatY, this.util.guiOptions.targatZ) + 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) + 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] = + 1000 + 600 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + if (this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.seldtFacNo) { + graphPathObj[facP][nP] = + 300 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + } else { + graphPathObj[facP][nP] = + 800 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + } + dtPathObj[facP][nP] = + 1000 + 100 * 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] = + 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + ftPathObj[facP][nP] = + 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + dtPathObj[facP][nP] = + 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + } else { + dtPathObj[facP][nP] = + 1000 + 600 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + if ( + this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.selupftFacNo || + this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.seldownftFacNo + ) { + graphPathObj[facP][nP] = + 300 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + } else { + graphPathObj[facP][nP] = + 800 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + } + ftPathObj[facP][nP] = + 1000 + 100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)) + } + } + } + } + } + } catch (e) { + console.log('交通设施点位问题: ' + e) + } + + this.util.pathStateObj.graphPath = graphPathObj + this.util.pathStateObj.ftPath = ftPathObj + this.util.pathStateObj.dtPath = dtPathObj + 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, (fIndex - parseInt(Map_QM.util.deviceObj.floor)) * Map_QM.util.options.fSpace, 0) + 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) + this.controls.minPan = new THREE.Vector3(this.w / -10, 0, this.h / -10) + this.controls.maxPan = new THREE.Vector3(this.w / 10, 0, this.h / 10) + 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) + ) + } 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)) { + 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) + ) + } + } + this.initFloor() + } else { + bIndex++ + fIndex = 0 + this.mapArr[bIndex] = [] + } + } + }, 50) + }, + initTreeModel: function () { + let url = Map_QM.util.beforPath + Map_QM.util.modelStr[this.index].url + this.gltfLoad(url) + }, + gltfLoad: function (url) { + let sopce = this + new THREE.GLTFLoader().load(url, function (object) { + //加载路径fbx文件 + object.scene.traverse(function (child) { + if (child.type === 'Mesh') { + child.castShadow = Map_QM.util.options.shadow + child.receiveShadow = Map_QM.util.options.shadow + if (child.material.map) { + child.material.map.encoding = THREE.LinearEncoding //贴图需要转换成 线性编码 + } + if (Map_QM.util.modelStr[sopce.index].colorModel === 'gama') { + child.material.color.convertGammaToLinear(0.6) + } + } + }) + object.scene.children[0].scale.set(Map_QM.util.modelStr[sopce.index].size.x, Map_QM.util.modelStr[sopce.index].size.y, Map_QM.util.modelStr[sopce.index].size.z) + Map_QM.util.fbxModels.push({ key: Map_QM.util.modelStr[sopce.index].key, obj: object.scene, operation: Map_QM.util.modelStr[sopce.index] }) + if (sopce.index < Map_QM.util.modelStr.length - 1) { + sopce.index++ + sopce.initTreeModel() + } else { + if (Map_QM.util.allMap && Map_QM.util.allMap.length > 0) { + Map_QM.loaderOver() + } + } + }) + }, + initGuide: function () { + new THREE.GLTFLoader().load(Map_QM.util.beforPath + 'static/img/runman.gltf', function (obj) { + obj.scene.scale.x = obj.scene.scale.y = obj.scene.scale.z = 15 + obj.scene.children[0].children[1].children[0].material.color = new THREE.Color(0xfe9219) + Map_QM.sceneGap.add(obj.scene) + 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() + Map_QM.mixers.push(mixer) + Map_QM.man_3d = obj.scene + Map_QM.guide = Map_QM.man_3d + }) + + new THREE.TextureLoader().load(Map_QM.util.beforPath + 'static/img/guide.png', textu => { + let planeMaterial = new THREE.MeshPhongMaterial({ + map: textu, + depthTest: true, + transparent: true, + alphaTest: 0.1 + }) + let planeGeometry = new THREE.PlaneGeometry(128, 128) + Map_QM.man_2d = new THREE.Mesh(planeGeometry, planeMaterial) + Map_QM.man_2d.center = new THREE.Vector2(0.5, 0.5) + Map_QM.man_2d.visible = false + Map_QM.sceneGap.add(Map_QM.man_2d) + }) + }, + initFloor: function () { + if (Map_QM.util.initModelArr && Map_QM.util.initModelArr.length > 0) { + this.buildObj.visible = false + } + Map_QM.changeBuild(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor) + Map_QM.controls.target.set(Map_QM.util.guiOptions.targatX, Map_QM.util.guiOptions.targatY, Map_QM.util.guiOptions.targatZ) + //初始化方向为第一人称方向 + let angle = Map_QM.util.options.deviceAng ? Map_QM.util.deviceObj.angle : 0 + Map_QM.rotationAngle(angle) + Map_QM.startRender() + setTimeout(() => { + Map_QM.cameraPerspective.position.set(parseInt(Map_QM.util.guiOptions.cameraX), parseInt(Map_QM.util.guiOptions.cameraY), parseInt(Map_QM.util.guiOptions.cameraZ)) + Map_QM.cameraPerspective.updateProjectionMatrix() //必须update + Map_QM.cameraOrtho.position.set(parseInt(Map_QM.util.guiOptions.cameraX), parseInt(Map_QM.util.guiOptions.cameraY), parseInt(Map_QM.util.guiOptions.cameraZ)) + Map_QM.controls.saveState() + Map_QM.controls.addEventListener('change', this.controlsChock, false) //控制器变化 + }, 100) + }, + /** + * 解析路径 + */ + convertPath: function (buildOrder, floorOrder) { + let mapData = this.util.allMap[buildOrder].buildArr[floorOrder].mapData + let pathData = mapData.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 + Map_QM.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 + } + Map_QM.util.pathStateObj.basePath += '"' + buildOrder + '_' + floorOrder + '_' + b + '":' + pathData.nodes[i]['list'][n].cost + ',' + } + if (pathData.nodes[i]['list'].length > 0) { + Map_QM.util.pathStateObj.basePath = Map_QM.util.pathStateObj.basePath.substr(0, Map_QM.util.pathStateObj.basePath.length - 1) + } + Map_QM.util.pathStateObj.basePath += '},' + } + } + + let mindt = -1, + minupft = -1, + mindownft = -1 ///Map_QM.util.pathStateObj.selupftFacNo, Map_QM.util.pathStateObj.seldownftFacNo, + if (buildOrder == this.util.deviceObj.build && floorOrder == this.util.deviceObj.floor) { + if (pathData && !this.util.deviceObj.xaxis && 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 + } + for (let h = 0; h < mapData.stairs.length; h++) { + if (mapData.stairs[h].state && mapData.stairs[h].no != '') { + 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 == 'dt') { + if (mindt == -1) { + mindt = ms + Map_QM.util.pathStateObj.seldtFacNo = mapData.stairs[h].no + } else { + if (mindt > ms) { + mindt = ms + Map_QM.util.pathStateObj.seldtFacNo = mapData.stairs[h].no + } + } + } else if (mapData.stairs[h].facCode == 'upft' || mapData.stairs[h].downState) { + //上扶梯 + if (minupft == -1) { + minupft = ms + Map_QM.util.pathStateObj.selupftFacNo = mapData.stairs[h].no + } else { + if (minupft > ms) { + minupft = ms + Map_QM.util.pathStateObj.selupftFacNo = mapData.stairs[h].no + } + } + } else if (mapData.stairs[h].facCode == 'upft' || mapData.stairs[h].downState) { + if (mindownft == -1) { + mindownft = ms + Map_QM.util.pathStateObj.seldownftFacNo = mapData.stairs[h].no + } else { + if (mindownft > ms) { + mindownft = ms + Map_QM.util.pathStateObj.seldownftFacNo = mapData.stairs[h].no + } + } + } + } + } + } + + let noHas + for (let j = 0; j < mapData.stairs.length; j++) { + if ((mapData.stairs[j].hasOwnProperty('state') && mapData.stairs[j].state) || !mapData.stairs[j].state) { + //排除禁用的设施 + noHas = true + for (let k = 0; k < Map_QM.util.pathStateObj.facAllArr.length; k++) { + //Map_QM.util.pathStateObj.facAllArr 记录遍历结果 + if ( + Map_QM.util.pathStateObj.facAllArr[k][0].no != '' && + Map_QM.util.pathStateObj.facAllArr[k][0].navCode != '' && + Map_QM.util.pathStateObj.facAllArr[k][0].no == mapData.stairs[j].no + ) { + if ( + Map_QM.util.pathStateObj.facAllArr[k][0].facCode == mapData.stairs[j].facCode || + (Map_QM.util.pathStateObj.facAllArr[k][0].facCode.search('ft') != -1 && mapData.stairs[j].facCode.search('ft') != -1) + ) { + noHas = false + mapData.stairs[j].floorOrder = floorOrder + mapData.stairs[j].buildOrder = buildOrder + Map_QM.util.pathStateObj.facAllArr[k].push(mapData.stairs[j]) + } + } + } + if (noHas) { + mapData.stairs[j].buildOrder = buildOrder + mapData.stairs[j].floorOrder = floorOrder + let array = [mapData.stairs[j]] + Map_QM.util.pathStateObj.facAllArr.push(array) + } + } + } + }, + /** + * @api {方法} changeMapState("3d") 地图状态切换 + * @apiGroup 地图显示 + * @apiDescription 地图展示状态切换 + * @apiVersion 2.0.0 + * @apiParam {string} state 地图状态 + * + * @apiSampleRequest off + * + * @apiParamExample {String} 请求示例 + * + * Map_QM.changeMapState("2d"); + * + */ + changeMapState: function (state) { + Map_QM.controls.reset() + 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.camera.updateProjectionMatrix() //必须update + Map_QM.camera.position.set(Map_QM.util.guiOptions.cameraX, Map_QM.util.guiOptions.cameraY, Map_QM.util.guiOptions.cameraZ) + 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.camera.updateProjectionMatrix() //必须update + Map_QM.controls.maxPolarAngle = 0 + Map_QM.changeIconState(state) + } + }, + + changeIconState: function (state) { + for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { + 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 + } else { + obj.visible = true + } + } + }) + } + if (Map_QM.dirIcon) { + Map_QM.dirIcon.visible = state == '2d' ? true : false + } + if (Map_QM.qiModel) { + Map_QM.qiModel.visible = state == '2d' ? false : true + } + if (Map_QM.qiIcon) { + Map_QM.qiIcon.visible = state == '2d' && Map_QM.util.pathStateObj.isPathState ? true : false + } + }, + + /** + * @api {方法} changeBuild(buildOrder,floorOrder) 楼栋切换 + * @apiGroup 地图交互 + * @apiDescription 楼栋切换 传入楼栋编号,楼层编号 + * @apiVersion 2.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.resetFloorState() + 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 + TweenMax.to(Map_QM.buildObj.position, 0.5, { + x: build * Map_QM.util.options.bSpace * -1, + onComplete: function () { + Map_QM.changeFloorInner(build, fIndex) //结束后切换楼层 + } + }) + }, + resetFloorState: function () { + 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.util.pathStateObj.forShopArr = { direction: '', wayList: [] } + Map_QM.resetMeDir() + 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 2.0.0 + * + * @apiParam {int} floorOrder 楼层编号 + * + * @apiSampleRequest off + * + * @apiParamExample {int} 请求示例 + * + * Map_QM.showFloor(1); + * + */ + showFloor: function (fIndex = -1, callBack = undefined) { + Map_QM.resetFloorState() + Map_QM.clearFloor(fIndex) + if (fIndex != -1) { + Map_QM.changeFloorInner(-1, fIndex, callBack) + } + }, + /** + * @api {方法} changeFloorByName(floorOrder) 通过楼层名称切换楼层 + * @apiGroup 地图交互 + * @apiDescription 楼层切换,传入楼层名称, + * @apiVersion 2.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 + } + } + }, + changeFloorInner: function (build = -1, fIndex = -1, callBack = undefined, endIndex = -1, midIndex = -1) { + let addFloor = fIndex - Map_QM.util.deviceObj.floor > 0 ? 1 : -1 + 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].labelObj.traverse(obj => { + obj.element && (obj.element.style.visibility = 'hidden') + }) + Map_QM.mapArr[t][i].tagObj.traverse(obj => { + obj.element && (obj.element.style.visibility = 'hidden') + }) + Map_QM.mapArr[t][i].showTagObj.traverse(obj => { + obj.element && (obj.element.style.visibility = 'hidden') + }) + } + } + if (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 || (i == midIndex && Map_QM.util.options.overlap) || (i == endIndex && Map_QM.util.options.overlap)) { + Map_QM.mapArr[build][i].allObj.visible = true + Map_QM.mapArr[build][i].labelObj.traverse(obj => { + obj.element && (obj.element.style.visibility = 'visible') + }) + Map_QM.mapArr[build][i].showTagObj.traverse(obj => { + obj.element && (obj.element.style.visibility = 'visible') + }) + } else { + Map_QM.mapArr[build][i].allObj.visible = false + } + if (i == Map_QM.mapArr[build].length - 1) { + if (Map_QM.util.options.overlap) { + //叠层 + if (midIndex === -1 && endIndex !== -1) { + //两层 + Map_QM.mapArr[build][fIndex].allObj.position.y = fIndex < endIndex ? -1 * Map_QM.util.options.fSpace : Map_QM.util.options.fSpace + Map_QM.mapArr[build][endIndex].allObj.position.y = fIndex > endIndex ? -1 * Map_QM.util.options.fSpace : Map_QM.util.options.fSpace + Map_QM.timeOutInit() + } else if (endIndex === -1) { + //一层 + if (build == Map_QM.util.selectBuild && fIndex == Map_QM.util.selectFloor) { + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y = 0 + Map_QM.timeOutInit() + if (callBack) callBack() + } else { + Map_QM.util.selectBuild = build + Map_QM.util.selectFloor = fIndex + if (Map_QM.util.options.shadow) { + TweenMax.fromTo( + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position, + 0.3, + { z: Map_QM.util.options.fSpace, y: 0 }, + { + z: 0, + y: 0, + ease: Cubic.easeIn, + onComplete: function () { + Map_QM.timeOutInit() + if (callBack) callBack() + } + } + ) + } else { + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y = 0 + Map_QM.timeOutInit() if (callBack) callBack() - } - } - } else { //三层 - Map_QM.mapArr[build][fIndex].allObj.position.y = 0; - Map_QM.mapArr[build][midIndex].allObj.position.y = 0; - Map_QM.mapArr[build][endIndex].allObj.position.y = 0; - let minF = Math.min(midIndex, fIndex, endIndex); - let maxF = Math.max(midIndex, fIndex, endIndex); - Map_QM.mapArr[build][minF].allObj.position.y = -1 * Map_QM.util.options.fSpace; - Map_QM.mapArr[build][maxF].allObj.position.y = Map_QM.util.options.fSpace; - } - } else { - if (build == Map_QM.util.selectBuild && fIndex == Map_QM.util.selectFloor) { - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y =0; - if (callBack) callBack(); - Map_QM.timeOutInit(); - } else { - Map_QM.util.selectBuild = build; - Map_QM.util.selectFloor = fIndex; - if (Map_QM.util.options.shadow) { - TweenMax.fromTo(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position, 0.3, { z: Map_QM.util.options.fSpace, y: 0 }, { - z: 0, y: 0, ease: Cubic.easeIn, onComplete: function () { - Map_QM.timeOutInit(); - if (callBack) callBack(); - } - }); - } else { - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y = 0; - Map_QM.timeOutInit() + } + } + } else { + //三层 + Map_QM.mapArr[build][fIndex].allObj.position.y = 0 + Map_QM.mapArr[build][midIndex].allObj.position.y = 0 + Map_QM.mapArr[build][endIndex].allObj.position.y = 0 + let minF = Math.min(midIndex, fIndex, endIndex) + let maxF = Math.max(midIndex, fIndex, endIndex) + Map_QM.mapArr[build][minF].allObj.position.y = -1 * Map_QM.util.options.fSpace + Map_QM.mapArr[build][maxF].allObj.position.y = Map_QM.util.options.fSpace + } + } else { + if (build == Map_QM.util.selectBuild && fIndex == Map_QM.util.selectFloor) { + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y = 0 + if (callBack) callBack() + Map_QM.timeOutInit() + } else { + Map_QM.util.selectBuild = build + Map_QM.util.selectFloor = fIndex + if (Map_QM.util.options.shadow) { + TweenMax.fromTo( + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position, + 0.3, + { z: Map_QM.util.options.fSpace, y: 0 }, + { + z: 0, + y: 0, + ease: Cubic.easeIn, + onComplete: function () { + Map_QM.timeOutInit() + if (callBack) callBack() + } + } + ) + } else { + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.y = 0 + Map_QM.timeOutInit() if (callBack) callBack() - } - } - } - } - } - }, - /** - * @api {方法} onShowMeDir() 我的方向 - * @apiGroup 地图显示 - * @apiDescription 我的方向 - * @apiVersion 2.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 () { - this.changeMapModel("2D"); - Map_QM.controls.maxPolarAngle = 0 - Map_QM.controls.minPolarAngle = 0 - if (Map_QM.util.pathStateObj.isPathState) { - this.dirIcon.visible = false; - } - if (Map_QM.util.deviceObj.xaxis) { - Map_QM.controls.object.position.set(Map_QM.util.deviceObj.xaxis * Map_QM.util.sceneGap.scale, 50, Map_QM.util.deviceObj.yaxis * Map_QM.util.sceneGap.scale) - Map_QM.controls.target = new THREE.Vector3(Map_QM.util.deviceObj.xaxis * Map_QM.util.sceneGap.scale, 0, Map_QM.util.deviceObj.yaxis * Map_QM.util.sceneGap.scale) - } else { - Map_QM.controls.object.position.set(0, 51, 0) - Map_QM.controls.target = new THREE.Vector3(0, 0, 0) - } - Map_QM.controls.setZoom(Map_QM.util.options.camZoom) - Map_QM.rotationAngle(Map_QM.util.deviceObj.angle) - Map_QM.controls.enableRotate = false - }, - changeMapModel: function (model) { - if (model == "2D") { - Map_QM.util.setModelState("2d"); - Map_QM.camera = Map_QM.cameraOrtho; - Map_QM.controls.object = Map_QM.camera; - Map_QM.shawLight.castShadow = false; - } else { - Map_QM.util.setModelState("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.reset(); - } - }, - - /** - * @api {方法} onShowLocalSite(0) 局部显示放大 - * @apiGroup 地图显示 - * @apiDescription 局部显示放大 point 传入放大目标点,zoom放大级别 1-5 - * @apiVersion 2.0.0 - * @apiParam {Object} point 放大的地图位置 - * @apiParam {int} zoom 放大倍数(默认 1) - * - * @apiSampleRequest off - * - * @apiParamExample {Object} 请求示例 - * - * Map_QM.onShowLocalSite({x:0,y:0},1); - * - */ - onShowLocalSite: function (centerPoint, zoom = 1) { - 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; - } - if (Map_QM.camera == Map_QM.cameraOrtho) { - Map_QM.util.setModelState('3d') - Map_QM.camera = Map_QM.cameraPerspective - Map_QM.controls.setZoom(zoom) - Map_QM.shawLight.castShadow = Map_QM.util.options.shadow; - Map_QM.controls.object = Map_QM.camera - Map_QM.controls.enabled = true - Map_QM.controls.enableRotate = true - } - let vat = Map_QM.mapBackToWorld(centerPoint.x, centerPoint.y, 0); - TweenMax.to(Map_QM.controls.object.position, 0.1, { - x: vat.x, delay: 0.1, onComplete: function () { - Map_QM.controls.maxDistance = Map_QM.util.options.maxDis; - } - }); - TweenMax.to(Map_QM.controls.target, 0.1, { x: vat.x, y: vat.y, z: vat.z }); - isJUZ = true; - }, - //底图二维坐标转 3D模型三维坐标 - mapBackToWorld: function (mapX, mapY, mapZ) { - 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); - return vct; - }, - /** - * @api {方法} onShowDeviceSite() 地图方向复位 - * @apiGroup 地图显示 - * @apiDescription 地图方向复位 - * @apiVersion 2.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.controls.object.position.set(0, 200, obj.y * Map_QM.util.sceneGap.scale); - Map_QM.controls.target = new THREE.Vector3(obj.x * Map_QM.util.sceneGap.scale, 0, obj.y * Map_QM.util.sceneGap.scale); //移动 - } - }, - /** - * 方向复位 - */ - resetMeDir: function () { - this.util.setModelState("3d"); - this.changeMapState("3d"); - this.controls.setZoom(1); - this.shawLight.castShadow = this.util.options.shadow; - this.controls.reset(); - }, - /** - * @api {方法} changePathDir(pathState) 切换导航方向 - * @apiGroup 地图交互 - * @apiDescription 切换导航方向 - * @apiVersion 2.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; - } - 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 2.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].allObj.children; - for (let k = 0; k < shopArr.length; k++) { - if (shopArr[k].name == ipName) { - return shopArr[k]; - } - } - } - } - return null; - }, - /** - * @api {方法} parseSelectShop() 设置选中店铺弹跳 - * @apiGroup 地图交互 - * @apiDescription 设置选中店铺弹跳 - * @apiVersion 2.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.onShowLocalSite(new Map_QM.util.Point(Map_QM.selectShop.xaxis, Map_QM.selectShop.yaxis)); - } - } - }, - /** - * @api {方法} cancelSelectShop() 取消店铺弹跳 - * @apiGroup 地图交互 - * @apiDescription 取消店铺弹跳效果 - * @apiVersion 2.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 2.0.0 - * - * @apiParam {boolean} isShow 店铺促销标签是否显示(默认 false) - * - * @apiSampleRequest off - * - * @apiParamExample {boolean} 请求示例 - * - * Map_QM.changeStateShopPro(true); - * - */ - changeStateShopPro: function (isShow = false) { - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].tagObj.traverse((obj) => { - obj.visible = isShow; - }); - }, - /** - * @api {方法} changeShowTagObjState(isShow) 自定义标签 - * @apiGroup 地图交互 - * @apiDescription 自定义标签展示/隐藏 - * @apiVersion 2.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 2.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 2.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","#2246d8") - * - */ - drawCurveLine: function (startShop, endShop, color = "#0099ff") { - let sp, ep, cp1, cp2; - if (Array.isArray(startShop) && Array.isArray(endShop)) { - return { "msg": "只能有一个数组" }; - } - if (Array.isArray(startShop)) { //如果是数组 - endShop = Map_QM.shopNumToNavPoint({ shopNum: endShop }, "shop"); - for (let i = 0; i < startShop.length; i++) { - startShop[i] = Map_QM.shopNumToNavPoint({ shopNum: 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.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)); - } - } else { - startShop = Map_QM.shopNumToNavPoint({ shopNum: startShop }, "shop"); - if (Array.isArray(endShop)) { //如果是数组 - for (let i = 0; i < endShop.length; i++) { - endShop[i] = Map_QM.shopNumToNavPoint({ shopNum: 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.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)); - } - } else { - endShop = Map_QM.shopNumToNavPoint({ shopNum: 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.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)); - } - } - }, - /** - * @api {方法} drawColumnar(source,property) 绘制柱状图 - * @apiGroup 地图交互 - * @apiDescription 绘制柱状图 - * @apiVersion 2.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 (shopNum, property) { - if (shopNum.trim() != "" && property) { - endShop = Map_QM.shopNumToNavPoint({ shopNum: shopNum }, "shop"); - let geometry = new THREE.BoxGeometry(property.width * 2, property.width * 2, property.width * 2); - let c = new THREE.Color(property.color); - let material = new THREE.ShaderMaterial({ - uniforms: { - targetColor: { value: new THREE.Vector3(c.r, c.g, c.b) }, - height: { value: property.height / 5 }, - }, - transparent: true, - opacity: property.opacity, - //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,(1.0 - modelPos.y/height)*(1.0 - modelPos.y/height));", - "}" - ].join("\n") - }); - //let material = new THREE.MeshPhongMaterial( { color: property.color, opacity: property.opacity, transparent:true, side: THREE.DoubleSide } ); - 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 material_line; - for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) { - let color2 = new THREE.Color(property.color) - if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) { - material_line = Map_QM.util.lineBasicMaterialArr[k]; - } - } - if (!material_line) { - material_line = new THREE.LineBasicMaterial({ - color: property.color - }); //材质对象lineColor - Map_QM.util.lineBasicMaterialArr.push(material_line); - } - 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 2.0.0 - * - * @apiParam type 传入删除的类型(默认 all) toLine--引导线 columer--柱状样式 all---所有 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.removeDrawEle("toLine") - * - */ - removeDrawEle: function (type = "all") { - 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]); - } - } - } - } - }, - /** - * @api {方法} rotationAngle(angle) 改变水平角度 - * @apiGroup 地图显示 - * @apiDescription 改变地图水平角度 angle>-180 && angle<180 - * @apiVersion 2.0.0 - * - * @apiParam {int} angle 旋转角度 - * - * @apiSampleRequest off - * - * @apiParamExample {int} 请求示例 - * - * Map_QM.rotationAngle(90); - * - */ - rotationAngle: function (angle) { - Map_QM.controls.setRotateHorizontal(angle / 180 * Math.PI); - }, - /** - * @api {方法} rotateAngle(angle) 改变垂直角度 - * @apiGroup 地图显示 - * @apiDescription 改变地图垂直角度 angle>-90 && angle<90 - * @apiVersion 2.0.0 - * - * @apiParam {int} angle 旋转角度 - * - * @apiSampleRequest off - * - * @apiParamExample {int} 请求示例 - * - * Map_QM.rotateAngle(-45); - * - */ - rotateAngle: function (angle) { - Map_QM.controls.rotate(angle / 180 * Math.PI); - }, - /** - * @api {方法} setCameraDist(cDist) 调整地图大小 - * @apiGroup 地图显示 - * @apiDescription 调整地图大小(值越小地图越大) Map_QM.util.options.minDis ~ Map_QM.util.options.maxDis - * @apiVersion 2.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 2.0.0 - * - * @apiSampleRequest off - * @apiParamExample 请求示例 - * - * Map_QM.startRender(); - * - */ - startRender: function () { - Map_QM.cancelRender(); - renderFrame = requestAnimationFrame(Map_QM.startRender); - let T = Map_QM.util._clock.getDelta(); - Map_QM.util.timeObj.timeS = Map_QM.util.timeObj.timeS + T; - // requestAnimationFrame默认调用render函数60次,通过时间判断,降低renderer.render执行频率 - if (Map_QM.util.timeObj.timeS > 0.03) { - if (Map_QM.qiModel) { - Map_QM.qiModel.rotateY(0.05); - } - if (Map_QM.endModel) { - Map_QM.endModel.rotateY(0.05); - } - if (debug) { - Map_QM.controls.object.position.x = Map_QM.util.guiOptions.cameraX; - Map_QM.controls.object.position.y = Map_QM.util.guiOptions.cameraY; - Map_QM.controls.object.position.z = Map_QM.util.guiOptions.cameraZ; - - Map_QM.controls.target.x = Map_QM.util.guiOptions.targatX; - Map_QM.controls.target.y = Map_QM.util.guiOptions.targatY; - Map_QM.controls.target.z = Map_QM.util.guiOptions.targatZ; - } - - Map_QM.controls.update(); - Map_QM.renderer.render(Map_QM.scene, Map_QM.camera); - Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera); - for (let item of Map_QM.mixers) { - item.update(T); - } - if (debug) { - stats.update(); - } - //timeS置0 - Map_QM.util.timeObj.timeS = 0; - } - }, - /** - * @api {方法} cancelRender() 取消地图渲染 - * @apiGroup 地图显示 - * @apiDescription 取消地图渲染 与 startRender 配合使用可节约资源 - * @apiVersion 2.0.0 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.cancelRender(); - * - */ - cancelRender: function () { - window.cancelAnimationFrame(renderFrame); - renderFrame = -1; - }, - - /** - * @api {方法} addElementLabel() 地图html标签 - * @apiGroup 地图交互 - * @apiDescription 地图显示Html标签,返回3d标签对象 - * @apiVersion 2.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; - Map_QM.elementDestroy(type); - 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.name = "shopInfo"; - Map_QM.CSSObject.add(shopInfo); - TweenMax.to(divObj.style, 0.2, { opacity: 1, delay: 0.1 }); - return shopInfo; - }, - /** - * @api {方法} updateElementPosition() 修改标签位置 - * @apiGroup 地图交互 - * @apiDescription 修改标签位置 - * @apiVersion 2.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 2.0.0 - * @apiParam {String} type docment元素自定义标识(默认 "shopInfo") - * - * @apiSampleRequest off - * - * @apiParamExample {Object} 请求示例 - * - * Map_QM.elementDestroy(); - * - */ - elementDestroy: function (type = "shopInfo") { - for (let i = Map_QM.CSSObject.children.length - 1; i >= 0; i--) { - if (Map_QM.CSSObject.children[i].userData && Map_QM.CSSObject.children[i].userData.type == type) { - Map_QM.CSSObject.remove(Map_QM.CSSObject.children[i]); - } - } - }, - /** - * @api {方法} changeShowShopName() 修改店铺显示名称 - * @apiGroup 地图显示 - * @apiDescription 通过店铺编号修改店铺显示名称 - * @apiVersion 2.0.0 - * @apiParam {Array} shopNum 店铺编号 - * @apiParam {Array} element html标签字符串 - * @apiSampleRequest off - * - * @apiParamExample {String} 请求示例 - * Map_QM.changeShowShopName(["L104"],['

肯德基

']) - */ - 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 {方法} unionShop() 店铺合并 - * @apiGroup 地图显示 - * @apiDescription 通过店铺编号合并店铺 合铺 - * @apiVersion 2.0.0 - * @apiParam {Array} shops 店铺编号数组 - * @apiParam {Object} data 新的店铺数据(默认 空数据) - * @apiSampleRequest off - * - * @apiParamExample {String} 请求示例 - * Map_QM.unionShop(["L105","L106","L107","L108"],{name:"新店",shopNum:"L104-L108",color:"#F4A460"}) - */ - unionShop: function (shops, data = { name: "", shopNum: "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].allObj.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].allObj.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]) { - 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.shopNum = data.name; - mesh.userData.entColor = data.color; - mesh.userData.type = "shop"; - if (data.name) { - mesh.name = data.name; - let shopDiv = document.createElement('div'); - shopDiv.style.cssText = css_LR; - 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.shopNum || data.name; - 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); - } - }, - - //////////////////////////////////////////////////////////////////////////////// - - /** - * @param {Object} e - * 地图BOX点击 - */ - onMouseClickBox: function (event) { - if (Map_QM.util.isInnerTouch) { - 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.util.selectBuild] && !Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor] ) { - 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; - //图标点击 - for (let i = 0; i < intersects.length; i++) { - //图标点击 - if (intersects[i].object.userData && (intersects[i].object.userData.type == 'icon' || intersects[i].object.parent.userData.type == 'icon' || intersects[i].object.parent.parent.userData.type == 'icon')) { - if (Map_QM.endModel && Map_QM.endModel.visible) { - Map_QM.endModel.visible = false; - } - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.clearPath(); - let buildOrder = intersects[i].object.userData.buildOrder || intersects[i].object.parent.userData.buildOrder || intersects[i].object.parent.parent.userData.buildOrder || 0 - let floorOrder = intersects[i].object.userData.floorOrder || intersects[i].object.parent.userData.floorOrder || intersects[i].object.parent.parent.userData.floorOrder || 0 - let navCode = intersects[i].object.userData.navCode || intersects[i].object.parent.userData.navCode || intersects[i].object.parent.parent.userData.navCode - let src = intersects[i].object.userData.src || intersects[i].object.parent.userData.src || intersects[i].object.parent.parent.userData.src - let facCode = intersects[i].object.userData.facCode || intersects[i].object.parent.userData.facCode || intersects[i].object.parent.parent.userData.facCode - let title = intersects[i].object.userData.title || intersects[i].object.parent.userData.title || intersects[i].object.parent.parent.userData.title - /** - * @api {事件} icon 点击设施图标 - * @apiGroup 地图事件 - * @apiDescription 用户点击设施图标后触发自定义事件 - * @apiVersion 2.0.0 - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * Map_QM.addEventListener("icon",onClickIcon,false); - */ - Map_QM.dispatchEvent({ - type: 'icon', - data: { "buildOrder": buildOrder, "floorOrder": floorOrder, "node": navCode, "src": src, "facCode": facCode, "title": title } - }) - console.log("触发 icon 事件 ", { - type: 'icon', - data: { "buildOrder": buildOrder, "floorOrder": floorOrder, "node": navCode, "src": src, "facCode": facCode, "title": title } - }); - return; - } - } - - for (let i = 0; i < intersects.length; i++) { - //店铺BOX点击 - if (intersects[i].object.userData && intersects[i].object.userData.type == "shop" && 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; - } - } - /** - * @api {事件} shop 点击已绑定品牌的店铺 - * @apiGroup 地图事件 - * @apiDescription 用户点击店铺后触发自定义事件 - * @apiVersion 2.0.0 - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * Map_QM.addEventListener("shop",onClickShop,false); - */ - if (clickShop && Map_QM.selectShop && Map_QM.selectShop.userData) { - if ((iot && Map_QM.selectShop.userData.shopData.hasOwnProperty("shopName")) || (!iot && Map_QM.selectShop.userData.shopData.hasOwnProperty("name"))) { - Map_QM.dispatchEvent({ - type: "shop", - data: Map_QM.selectShop.userData - }) - } else { - /** - * @api {事件} onlyShop 点击未绑定品牌的店铺 - * @apiGroup 地图事件 - * @apiDescription 用户点击空店铺后触发自定义事件 - * @apiVersion 2.0.0 - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * Map_QM.addEventListener("onlyShop",onClickShop,false); - */ - Map_QM.dispatchEvent({ - type: "onlyShop", - data: Map_QM.selectShop.userData - }) - } - } else { - Map_QM.dispatchEvent({ - type: "shop", - data: null - }) - } - }, - /** - * @api {方法} setSelectShopMatByName(shopNum) 设置box 选中 - * @apiGroup 地图交互 - * @apiDescription 地图box 选中 - * @apiVersion 2.0.0 - * @apiParam {String} shopNum 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); - }, - /** - * 初始化后调用 - */ - timeOutInit: 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); - 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 - }); - Map_QM.collLabel(); - }, - - 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.traverse) { - item.children.traverse((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; - } - } - }) - } - }); - } - } - } - }, - /** - * 碰撞检测 - * @param {Object} 传入检测楼层下标 - */ - controlsChock: function () { - Map_QM.autoChangeEleAngle(); - /** - * @api {事件} MapAngleChange 地图的方向改变 - * @apiGroup 地图事件 - * @apiDescription 用户操作地图时触发 - * @apiVersion 2.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) { - clearTimeout(shopTime); - shopTime = setTimeout(() => { - clearTimeout(shopTime); - isJUZ = false; - Map_QM.controls.reset() - }, 3000); - } - if (debug) { - Map_QM.util.guiOptions.cameraX = Map_QM.controls.object.position.x; - Map_QM.util.guiOptions.cameraY = Map_QM.controls.object.position.y; - Map_QM.util.guiOptions.cameraZ = Map_QM.controls.object.position.z; - - Map_QM.util.guiOptions.targatX = Map_QM.controls.target.x; - Map_QM.util.guiOptions.targatY = Map_QM.controls.target.y; - Map_QM.util.guiOptions.targatZ = Map_QM.controls.target.z; - } - if (Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) { //支持缩放切换 - let distance = Map_QM.controls.getDistance(); - if (distance <= Map_QM.util.changeDist.inner) { //切换到室内 - Map_QM.util.isInnerTouch = true; - if (Map_QM.outModelGap.visible) { - TweenMax.to(Map_QM.outModelGap.scale, 0.5, { - y: 0.01, ease: Quad.easeIn, onComplete: function () { - Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面 - } - }); - } - if (Map_QM.peripheryGap.visible) { - Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏周边 - } - if (!Map_QM.buildObj.userData.visible) { - Map_QM.buildObj.visible = true; - Map_QM.buildObj.userData.visible = true; - Map_QM.changeFloorInner(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor) - } - Map_QM.buildObj.traverse(obj => { - if (obj.isMesh) { - obj.material.opacity = obj.userData.opacity || 1; - obj.material.transparent = true - } - }) - } else if (distance > Map_QM.util.changeDist.outner && Map_QM.util.initModelArr.length > 1) { //周边 - Map_QM.util.isInnerTouch = false; - Map_QM.buildObj.userData.visible = false; - Map_QM.buildObj.visible = false; - Map_QM.changeFloorInner(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor) - - if (Map_QM.endModel && Map_QM.endModel.visible) { - Map_QM.endModel.visible = false - } - if (!Map_QM.peripheryGap.visible) { - TweenMax.to(Map_QM.peripheryGap.scale, 0.8, { y: 1 }); - } - Map_QM.hideObjecrGap(Map_QM.peripheryGap, true); - if (Map_QM.outModelGap.visible) { - TweenMax.to(Map_QM.outModelGap.scale, 0.5, { - y: 0.01, ease: Quad.easeIn, onComplete: function () { - Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面 - } - }); - } - } 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.util.isInnerTouch = false; - Map_QM.buildObj.userData.visible = false; - Map_QM.buildObj.visible = true; - if (Map_QM.endModel && Map_QM.endModel.visible) { - Map_QM.endModel.visible = false - } - if (!Map_QM.outModelGap.visible) { - TweenMax.to(Map_QM.outModelGap.scale, 0.8, { y: 1 }); - } - Map_QM.hideObjecrGap(Map_QM.outModelGap, true); - } - } - Map_QM.collLabel(); - }, - - hideObjecrGap: function (gap, isShow) { - gap.visible = isShow - gap.traverse(obj => { - if (obj.userData && obj.userData.type == "2d_IP") { - obj.element.style.visibility = isShow ? "visible" : "hidden" - } - if (obj.isMesh) { - obj.material.opacity = obj.userData.opacity; - obj.material.transparent = true - } - }) - }, - - //内部碰撞检测 - collLabel: function () { - if (!Map_QM || !Map_QM.util.options.collision) { - return; - } - clearTimeout(Map_QM.util.timeObj.collTime); - Map_QM.util.timeObj.collTime = setTimeout(() => { - clearTimeout(Map_QM.util.timeObj.collTime); - let checkList = []; - if (Map_QM.util.options.overlap) { - for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { - Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.traverse((obj) => { - if (obj.name == "floor" && Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.visible) { // - checkList.push(obj); - } - }); - } - } - if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.buildObj.visible) { - 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 && (!Map_QM.buildObj.userData.hasOwnProperty("visible") || Map_QM.buildObj.userData.visible)) { - let childs = Map_QM.mapArr[Map_QM.util.selectBuild][m].labelObj.children; - let len = childs.length; - for (let i = 0; i < len; i++) { - let obj = childs[i].element - if (childs[i].userData.mapShow) { - obj.style.visibility = "visible"; - } else { - obj.style.visibility = "hidden"; - } - if (obj.style.transform) { - obj.style.visibility = "visible" - let labP = obj.getBoundingClientRect(); - for (let j = 0; j < i; j++) { - if (childs[j].element.style.visibility == "visible") { - let pb = childs[j].element.getBoundingClientRect(); - let isCol = Map_QM.util.isCollision(labP, pb); - if (isCol) { - if (!childs[i].userData.mapShow) { - obj.style.visibility = "hidden" - break; - } else if (!childs[j].userData.mapShow) { - childs[j].element.style.visibility = "hidden" - } - } - } - } - } - } - - if (Map_QM.util.options.overlap) { - let renChild = Map_QM.mapArr[Map_QM.util.selectBuild][m].showTagObj.children; - const { left, top } = Map_QM.renderer.domElement.getBoundingClientRect(); - renChild.forEach((item) => { - if (item.element.style.visibility == "visible") { - let check = Map_QM.util.blocked(item.element, checkList, m, top, left); - if (check) { - item.element.style.visibility = "hidden"; - } - } - }); - childs.forEach((item) => { - if (item.element.style.visibility == "visible") { - let check = Map_QM.util.blocked(item.element, checkList, m, top, left); - if (check) { - item.element.style.visibility = "hidden"; - } - } - }); - } - } else { - let childs = Map_QM.mapArr[Map_QM.util.selectBuild][m].labelObj.children; - childs.forEach((item) => { - item.element.style.visibility = "hidden"; - }); - } - } - } - }, 500); - }, - - /** - * 寻路---------------------------------------------------------------------------------------------------------------------------------------- - */ - - /** - * @api {方法} bounceIcon({type:"xsj"}) 图标弹跳 - * @apiGroup 地图导航 - * @apiDescription 地图图标弹跳效果 - * @apiVersion 2.0.0 - * @apiParam {String} iconType 设施缩写 - * - * @apiSampleRequest off - * - * @apiParamExample {String} 请求示例 - * - * Map_QM.bounceIcon({type:"xsj"}); - * - */ - bounceIcon: function (iconType) { - let toFloor = parseInt(Map_QM.util.selectFloor); - let facs = Map_QM.mapArr[Map_QM.util.selectBuild][toFloor].serObj.children; //交通图标 - for (let i = 0; i < facs.length; i++) { - if (facs[i].type == "Sprite") { - facs[i].reSetSite(); - if (facs[i].facCode == iconType) { - facs[i].jumpIcon(); - } - } - } - }, - /** - * @api {方法} pathIcon({type:"xsj"}) 获取最近设施 - * @apiGroup 地图导航 - * @apiDescription 获取离当前楼层最近的设施 - * @apiVersion 2.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; - toIcon = iconType.type; - if (!Map_QM.util.startObj.build && parseInt(Map_QM.util.startObj.build) != 0) { - Map_QM.util.startObj.build = parseInt(Map_QM.util.deviceObj.build); - } - 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.graphPath, 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].facCode == iconType.type) { - let toNade = parseInt(Map_QM.util.deviceObj.build) + "_" + sers[n].floor + "_" + sers[n].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.floor, site: { x: selIcon.position.x, y: selIcon.position.y }, "node": selIcon.navCode, "no": selIcon.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].facCode == iconType.type) { - let toNade = parseInt(Map_QM.util.deviceObj.build) + "_" + sers[n].floor + "_" + sers[n].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.floor, "node": selIcon.navCode, site: { x: selIcon.position.x, y: selIcon.position.y }, "no": selIcon.no, "typeCode": Map_QM.util.getFacType(iconType.type) }; - } - } - }, - /** - * @api {方法} pathByStartAndOver(startObj,toObj,callBackFun) 地图路径规划 - * @apiGroup 地图导航 - * @apiDescription 根据传入的起、终点;直接导航 - * @apiVersion 2.0.0 - * @apiParam {String} startObj.shopNum 店铺编号/车位编号 - * @apiParam {String} startObj.type "shop"/"park" - * - * @apiParam {String} toObj.shopNum 店铺编号/车位编号 - * @apiParam {String} toObj.type "shop"/"park" - * - * @apiParam {Function} callBackFun 回调函数 - * - * @apiSampleRequest off - * - * @apiParamExample {String} 请求示例 - * - * Map_QM.pathByStartAndOver({"shopNum":"L102","type":"shop"},{"shopNum":"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) { - return "传入点位无法导航"; - } - }, - - /** - * @api {方法} changeStartPoint() 设置起始点位 - * @apiGroup 地图导航 - * @apiDescription 设置起始点位 - * @apiVersion 2.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(); - 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) - } - } - } - if (toObj && toObj.node) { - let pathData = this.util.allMap[parseInt(toObj.build)].buildArr[parseInt(toObj.floor)].mapData.path - this.util.deviceObj.xaxis = this.util.startObj.xaxis = pathData.nodes[parseInt(toObj.node)].x - this.util.deviceObj.yaxis = this.util.startObj.yaxis = pathData.nodes[parseInt(toObj.node)].y - this.util.deviceObj.build = this.util.startObj.build = parseInt(toObj.build); - this.util.deviceObj.floor = this.util.startObj.floor = parseInt(toObj.floor); - this.util.deviceObj.node = this.util.startObj.node = toObj.node; - this.util.deviceObj.angle = this.util.startObj.angle = toObj.angle || 0; - } else { - let pathData = this.util.allMap[parseInt(this.util.deviceObj.build)].buildArr[parseInt(this.util.deviceObj.floor)].mapData.path - pathData.nodes.sort(this.util.sortNode); - 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.startObj = this.util.deviceObj - } - 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) - ) - }, - - /** - * @api {方法} changeMapIPState(ipName,color) 改变POI颜色 - * @apiGroup 地图交互 - * @apiDescription 改变POI 颜色 - * @apiVersion 2.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].material = this.util.getMeshMaterial(color || 0xeab16e); - break; - } - } - } - }, - /** - * @api {方法} getMapIPData(ipName) 获取POI 基础数据 - * @apiGroup 地图交互 - * @apiDescription 获取POI 基础数据 - * @apiVersion 2.0.0 - * @apiParam {string} ipName POI名称 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.getMapIPData("L1001"); - * - * @apiSuccessExample 返回示例 - * { - * shopNum:店铺编号, 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].allObj.children; - for (let k = 0; k < shopArr.length; k++) { - if (shopArr[k].name == ipName) { - return shopArr[k].userData; - } - } - } - }, - - /** - * @api {方法} pathNode() 地图模拟导航 - * @apiGroup 地图导航 - * @apiDescription 地图路径模拟导航 - * @apiVersion 2.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) { - if (!toObj) { - return { direction: "", wayList: [] } - } - pathCameraState = Map_QM.util.options.pathStyle; - Map_QM.onShowDeviceSite() - Map_QM.clearFloor(-1, true); - Map_QM.selectShop = null; - Map_QM.util.pathStateObj.isPathState = true; - 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, shopNum: toObj.shopNum }; - if (Map_QM.util.overObj.node != "") { - Map_QM.cancelRender(); - this.onFindPathModel(); - if (Map_QM.util.options.overlap) { //叠层导航--固定地图仰角 - Map_QM.controls.maxPolarAngle = 1.17; - Map_QM.controls.minPolarAngle = 1.17; - } - if (callBackFun) { - Map_QM.parseForShopArr(); - const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr)); - callBackFun(data); - } - Map_QM.startRender(); - } - }, - 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.nameEn == "" ? item.wayShop[i].shop.name : item.wayShop[i].shop.nameEn; - Map_QM.util.pathStateObj.forShopArr.wayList.push({ isAddPrefix: false, name: "经过 " + item.wayShop[i].shop.name, nameEn: "PASS " + enTlite, logoPath: item.wayShop[i].shop.logoPath, code: item.wayShop[i].shop.code, shopNum: iot ? item.wayShop[i].shop.houseNumber : item.wayShop[i].shop.houseNum }); - } - } - if (item.hasOwnProperty("Facilities") && item.Facilities) { //设施 - Map_QM.util.pathStateObj.forShopArr.wayList.push({ - isAddPrefix: true, name: "乘坐 " + item.Facilities.userData.title + "到 " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, - nameEn: "BY " + item.Facilities.userData.title + "TO " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, logoPath: item.Facilities.imgUrl, code: (((Math.random()) * 0x1234567) | 0).toString(16).substring(0), shopNum: item.Facilities.userData.facCode + item.Facilities.userData.no - }); - } - }); - }, - /** - * @api {方法} getGapByPathNode() 获取实际距离 - * @apiGroup 地图导航 - * @apiDescription 通过点位获取距离 - * @apiVersion 2.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.graphPath, 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)} 米,预计${mint} 分钟`); // 21 是比例尺 - } catch (e) { - console.log(e) - } - return { dis: parseInt(path.cost / Map_QM.util.options.mapScale), time: minTime } - }, - /** - * @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 == "Sprite") { - let title = sers[n].userData.title || Map_QM.util.getFacName(sers[n].facCode); - let titleEn = Map_QM.util.iconEn[title]; - let type = sers[n].facCode; - let imgUrl = sers[n].imgUrl; - if (sers[n].facCode == "upft" || sers[n].facCode == "downft" || sers[n].facCode == "ft") { - if (title == "上扶梯" || title == "下扶梯") { title = "扶梯"; } - titleEn = Map_QM.util.iconEn["扶梯"]; - type = "ft"; - } - let icon = { type: type, floor: floorOrder, imgUrl: imgUrl, poid: sers[n].userData.poid, 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 == "Sprite") { - let title = sers[n].userData.title || Map_QM.util.getFacName(sers[n].facCode); - let titleEn = Map_QM.util.iconEn[title]; - let type = sers[n].facCode; - let imgUrl = sers[n].imgUrl; - if (sers[n].facCode == "upft" || sers[n].facCode == "downft" || sers[n].facCode == "ft") { - title = "扶梯"; - titleEn = Map_QM.util.iconEn[title]; - type = "ft"; - imgUrl = Map_QM.util.beforPath + "static/img/ft.png"; - } - let icon = { type: type, floor: i, imgUrl: imgUrl, poid: sers[n].userData.poid, title: title, titleEn: titleEn }; - iconArr.push(icon); - } - } - } - iconBuild.push(iconArr); - } - icons.push(iconBuild); - } - return icons; - }, - /** - * @api {方法} pathPark() 获取车位点位 - * @apiGroup 地图数据 - * @apiDescription 获取车位导航点 - * @apiVersion 2.0.0 - * @apiParam {String} shopNum 车位编号 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.pathPark({shopNum:"B1002"}); - * - * @apiSuccessExample 返回示例 - * { - * shopNum: 车位编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标 - * } - */ - pathPark: function (toObj) { - return this.shopNumToNavPoint(toObj, "park"); - }, - - /** - * @api {方法} pathShopByName() 获取店铺点位 - * @apiGroup 地图数据 - * @apiDescription 通过店铺名称获取点位 - * @apiVersion 2.0.0 - * @apiParam {String} shopName 店铺名称 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.pathShopByName("金拱门"); - * - * @apiSuccessExample 返回示例 - * { - * shopNum: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点 - * } - */ - pathShopByName: function (shopName) { - for (let item of Map_QM.util.shopData) { - if (item.name === shopName) { - let toObj = { "shopNum": iot ? item.houseNumber : item.houseNum, "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.shopNum) { - 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 {方法} shopNumToNavPoint() 获取导航点位 - * @apiGroup 地图导航 - * @apiDescription 通过店铺编号或车位获取导航点位 - * @apiVersion 2.0.0 - * @apiParam {Object} object build,floor,shopNum 楼栋编号,楼层编号,店铺或车位编号 - * @apiParam {String} type 店铺或车位标识 "shop" "park" - * - * @apiSampleRequest off - * - * @apiSuccessExample 返回示例 - * { - * shopNum: 店铺编号, 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.shopNum) { - reObj.floor = i; - reObj.build = h; - reObj.xaxis = shopArr[k].xaxis; - reObj.yaxis = shopArr[k].yaxis; - reObj.node = shopArr[k].shopNav; - reObj.shopNum = obj.shopNum; - 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 (parseInt(Map_QM.util.startObj.node) == -1) { - return; - } - 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); - } - } - Map_QM.forShopPath(usePath); - }, - forShopPath: function (usePath) { - 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; - try { - path = dijkstra.find_path(usePath, startNade, toNade); - } catch (e) { - console.log(e); - return; - } - - let PathPoint = path.nodes; - 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 2.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(); - } - }, - /** - * 途径店铺 - */ - foreignShop: function (pathArr, build, cFloor, m) { - let shopList = []; - let shops = Map_QM.mapArr[parseInt(build)][parseInt(cFloor)].allObj.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].navCode == fromFArr[2]) { - selectEle = { imgUrl: childs[i].imgUrl, userData: childs[i].userData, position: { x: childs[i].position.x, y: childs[i].position.y } } - break - } - } - return selectEle - }, - - /** - * 寻路动画方法 - */ - onFindPathToObj: function () { - outTime = -1; - Map_QM.util._indexPathFloor = 0; - Map_QM.callBackLoadOver = Map_QM.callBackForPathShop; //楼层初始化完成后回调 - - if (Map_QM.util.options.overlap) { - if (Map_QM.forShopArr.length == 2) { - Map_QM.changeFloorInner(-1, Map_QM.forShopArr[0].floor, () => { }, Map_QM.forShopArr[1].floor); - } else if (Map_QM.forShopArr.length == 3) { - Map_QM.changeFloorInner(-1, Map_QM.forShopArr[0].floor, () => { }, Map_QM.forShopArr[1].floor, Map_QM.forShopArr[2].floor); - } else { - Map_QM.changeFloorInner(-1, Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor); - } - } else { - 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.options.overlap) { - Map_QM.mapArr[Map_QM.util.overObj.build][Map_QM.util.overObj.floor].setOverSite(Map_QM.util.overObj.xaxis, Map_QM.util.overObj.yaxis, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.overObj.floor].allObj.position.y + parseInt(Map_QM.util.shopHeight)); - } else { - 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)); - } - } - - if (Map_QM.forShopArr.length > 0) { - document.addEventListener("pathOver", Map_QM.onFindPathFloor, true); - if (Map_QM.util.options.overlap && Map_QM.util._indexPathFloor == 0) {//叠层 - for (let pathObj of Map_QM.forShopArr) { - Map_QM.mapArr[pathObj.build][pathObj.floor].findPath.onFindPathAnimation(pathObj.PathPoint, pathObj.floor); //传入数组 - } - let extrudeSettings; - let vects = new THREE.CurvePath(); - let vects2 = new THREE.CurvePath(); - if (Map_QM.forShopArr.length == 2) { - vects.add(new THREE.LineCurve3(new THREE.Vector3(Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].x, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[0].floor].allObj.position.y, Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].y), - new THREE.Vector3(Map_QM.forShopArr[1].PathPoint[0].x, Map_QM.mapArr[Map_QM.forShopArr[1].build][Map_QM.forShopArr[1].floor].allObj.position.y, Map_QM.forShopArr[1].PathPoint[0].y))); - extrudeSettings = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects }; - let geometry = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings); - let lineDashed = new THREE.Mesh(geometry, Map_QM.util.tubeMaterial); - Map_QM.dtLineGroup.add(lineDashed); - } - if (Map_QM.forShopArr.length == 3) { - vects.add(new THREE.LineCurve3(new THREE.Vector3(Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].x, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[0].floor].allObj.position.y, Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].y), - new THREE.Vector3(Map_QM.forShopArr[1].PathPoint[0].x, Map_QM.mapArr[Map_QM.forShopArr[1].build][Map_QM.forShopArr[1].floor].allObj.position.y, Map_QM.forShopArr[1].PathPoint[0].y))); - - vects2.add(new THREE.LineCurve3(new THREE.Vector3(Map_QM.forShopArr[1].PathPoint[Map_QM.forShopArr[1].PathPoint.length - 1].x, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[1].floor].allObj.position.y, Map_QM.forShopArr[1].PathPoint[Map_QM.forShopArr[1].PathPoint.length - 1].y), - new THREE.Vector3(Map_QM.forShopArr[2].PathPoint[0].x, Map_QM.mapArr[Map_QM.forShopArr[2].build][Map_QM.forShopArr[2].floor].allObj.position.y, Map_QM.forShopArr[2].PathPoint[0].y))); - extrudeSettings = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects }; - extrudeSettings2 = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects2 }; - let geometry = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings); - let lineDashed = new THREE.Mesh(geometry, Map_QM.util.tubeMaterial); - Map_QM.dtLineGroup.add(lineDashed); - let geometry2 = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings2); - let lineDashed2 = new THREE.Mesh(geometry2, Map_QM.util.tubeMaterial); - Map_QM.dtLineGroup.add(lineDashed2); - } - } 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); //传入数组 - } - 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 2.0.0 - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * Map_QM.addEventListener("PathPlaying",onPathPlaying,false); - */ - Map_QM.dispatchEvent({ //寻路中返回小人当前所在点位 - type: 'PathPlaying', - data: { "shopNum": 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 = 7.5; - } - }); - } - - let zo = 2, tz = 2, boxT = 0, boxZ = 0; - let add = Map_QM.util.options.showStyle ? 80 : 40; - 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 = 27 - } else { - zo = (floorArr.length - 1) * add; - boxZ = 27 - } - - 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.visibility = "visible"; - Map_QM.moveFloorbg.element.style.width = (add + 8) + "px"; - Map_QM.moveFloorbg.element.style.height = (floorArr.length * add) + "px"; - Map_QM.moveFloorbg.position.set(x0, y0, 80); - Map_QM.moveFloorbg.applyMatrix4(Map_QM.mapArr[parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)][pathFloor].allObj.matrix); - Map_QM.moveFloorbg.applyMatrix4(Map_QM.sceneGap.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 (Map_QM.util.options.showStyle) { - span2.style.fontSize = '32px' - } - span2.style.width = add + '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.visibility = "hidden"; - if (!Map_QM.util.options.overlap) { - 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); - } else { - if (Map_QM.forShopArr > Map_QM.util._indexPathFloor) { - Map_QM.util.selectFloor = Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor; - } - Map_QM.clearFloor(-1, false); - Map_QM.callBackForPathShop(); - } - } - }); - 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 2.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.visibility = "hidden"; - } - 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 lines = Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj; - for (let j = lines.children.length - 1; j >= 0; j--) { - Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj.remove(lines.children[j]); - } - 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); - } - 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 2.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 2.0.0 - * - * @apiSampleRequest off - * - */ - pathRePlay: function () { - clearTimeout(Map_QM.util.timeObj.pathTime); - Map_QM.util.timeObj.pathTime = setTimeout(() => { - clearTimeout(Map_QM.util.timeObj.pathTime); - 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 2.0.0 - * - * @apiParam {function} callBack 回调函数 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.ChangePathByFt(function); - * - */ - ChangePathByFt: function (callBack) { - clearTimeout(Map_QM.util.timeObj.pathTime); - Map_QM.util.timeObj.pathTime = setTimeout(() => { - clearTimeout(Map_QM.util.timeObj.pathTime); - 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 2.0.0 - * - * @apiParam {function} callBack 回调函数 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.ChangePathByDt(function); - * - */ - ChangePathByDt: function (callBack) { - clearTimeout(Map_QM.util.timeObj.pathTime); - Map_QM.util.timeObj.pathTime = setTimeout(() => { - clearTimeout(Map_QM.util.timeObj.pathTime); - 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 2.0.0 - * - * @apiParam {function} callBack 回调函数 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.ChangePathByGood(function); - * - */ - ChangePathByGood: function (callBack) { - clearTimeout(Map_QM.util.timeObj.pathTime); - Map_QM.util.timeObj.pathTime = setTimeout(() => { - clearTimeout(Map_QM.util.timeObj.pathTime); - 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 ele = document.getElementById(options.containerId || "mapContainer"); - let w = parseInt(ele.clientWidth) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('width')) - let h = parseInt(ele.clientHeight) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('height')) - Map_QM.changeWindowResize(w, h); - }, - /** - * @api {方法} changeWindowResize() 窗口变化 - * @apiGroup 地图交互 - * @apiDescription 窗口变化 - * @apiVersion 2.0.0 - * - * @apiParam {int} width 窗口宽 - * @apiParam {int} height 窗口高 - * - * @apiSampleRequest off - * - * @apiParamExample 请求示例 - * - * Map_QM.changeWindowResize(1280,1080); - */ - changeWindowResize: function (width, height) { - Map_QM.aspect = width / height; - Map_QM.cameraPerspective.aspect = Map_QM.aspect; - Map_QM.cameraPerspective.updateProjectionMatrix(); - Map_QM.cameraOrtho.left = -150* Map_QM.aspect; - Map_QM.cameraOrtho.right = 150* Map_QM.aspect; - Map_QM.cameraOrtho.updateProjectionMatrix(); - Map_QM.renderer.setSize(width, height); - Map_QM.labelRenderer.setSize(width, height); - Map_QM.w = width; - Map_QM.h = height; - } + } + } + } + } + } + }, + /** + * @api {方法} onShowMeDir() 我的方向 + * @apiGroup 地图显示 + * @apiDescription 我的方向 + * @apiVersion 2.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 () { + this.changeMapModel('2D') + Map_QM.controls.maxPolarAngle = 0 + Map_QM.controls.minPolarAngle = 0 + if (Map_QM.util.pathStateObj.isPathState) { + this.dirIcon.visible = false + } + if (Map_QM.util.deviceObj.xaxis) { + Map_QM.controls.object.position.set(Map_QM.util.deviceObj.xaxis * Map_QM.util.sceneGap.scale, 50, Map_QM.util.deviceObj.yaxis * Map_QM.util.sceneGap.scale) + Map_QM.controls.target = new THREE.Vector3(Map_QM.util.deviceObj.xaxis * Map_QM.util.sceneGap.scale, 0, Map_QM.util.deviceObj.yaxis * Map_QM.util.sceneGap.scale) + } else { + Map_QM.controls.object.position.set(0, 51, 0) + Map_QM.controls.target = new THREE.Vector3(0, 0, 0) + } + Map_QM.controls.setZoom(Map_QM.util.options.camZoom) + Map_QM.rotationAngle(Map_QM.util.deviceObj.angle) + Map_QM.controls.enableRotate = false + }, + changeMapModel: function (model) { + if (model == '2D') { + Map_QM.util.setModelState('2d') + Map_QM.camera = Map_QM.cameraOrtho + Map_QM.controls.object = Map_QM.camera + Map_QM.shawLight.castShadow = false + } else { + Map_QM.util.setModelState('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.reset() + } + }, + + /** + * @api {方法} onShowLocalSite(0) 局部显示放大 + * @apiGroup 地图显示 + * @apiDescription 局部显示放大 point 传入放大目标点,zoom放大级别 1-5 + * @apiVersion 2.0.0 + * @apiParam {Object} point 放大的地图位置 + * @apiParam {int} zoom 放大倍数(默认 1) + * + * @apiSampleRequest off + * + * @apiParamExample {Object} 请求示例 + * + * Map_QM.onShowLocalSite({x:0,y:0},1); + * + */ + onShowLocalSite: function (centerPoint, zoom = 1) { + 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 + } + if (Map_QM.camera == Map_QM.cameraOrtho) { + Map_QM.util.setModelState('3d') + Map_QM.camera = Map_QM.cameraPerspective + Map_QM.controls.setZoom(zoom) + Map_QM.shawLight.castShadow = Map_QM.util.options.shadow + Map_QM.controls.object = Map_QM.camera + Map_QM.controls.enabled = true + Map_QM.controls.enableRotate = true + } + let vat = Map_QM.mapBackToWorld(centerPoint.x, centerPoint.y, 0) + TweenMax.to(Map_QM.controls.object.position, 0.1, { + x: vat.x, + delay: 0.1, + onComplete: function () { + Map_QM.controls.maxDistance = Map_QM.util.options.maxDis + } + }) + TweenMax.to(Map_QM.controls.target, 0.1, { x: vat.x, y: vat.y, z: vat.z }) + isJUZ = true + }, + //底图二维坐标转 3D模型三维坐标 + mapBackToWorld: function (mapX, mapY, mapZ) { + 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) + return vct + }, + /** + * @api {方法} onShowDeviceSite() 地图方向复位 + * @apiGroup 地图显示 + * @apiDescription 地图方向复位 + * @apiVersion 2.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.controls.object.position.set(0, 200, obj.y * Map_QM.util.sceneGap.scale) + Map_QM.controls.target = new THREE.Vector3(obj.x * Map_QM.util.sceneGap.scale, 0, obj.y * Map_QM.util.sceneGap.scale) //移动 + } + }, + /** + * 方向复位 + */ + resetMeDir: function () { + this.util.setModelState('3d') + this.changeMapState('3d') + this.controls.setZoom(1) + this.shawLight.castShadow = this.util.options.shadow + this.controls.reset() + }, + /** + * @api {方法} changePathDir(pathState) 切换导航方向 + * @apiGroup 地图交互 + * @apiDescription 切换导航方向 + * @apiVersion 2.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 + } + 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 2.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].allObj.children + for (let k = 0; k < shopArr.length; k++) { + if (shopArr[k].name == ipName) { + return shopArr[k] + } + } + } + } + return null + }, + /** + * @api {方法} parseSelectShop() 设置选中店铺弹跳 + * @apiGroup 地图交互 + * @apiDescription 设置选中店铺弹跳 + * @apiVersion 2.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.onShowLocalSite(new Map_QM.util.Point(Map_QM.selectShop.xaxis, Map_QM.selectShop.yaxis)) + } + } + }, + /** + * @api {方法} cancelSelectShop() 取消店铺弹跳 + * @apiGroup 地图交互 + * @apiDescription 取消店铺弹跳效果 + * @apiVersion 2.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 2.0.0 + * + * @apiParam {boolean} isShow 店铺促销标签是否显示(默认 false) + * + * @apiSampleRequest off + * + * @apiParamExample {boolean} 请求示例 + * + * Map_QM.changeStateShopPro(true); + * + */ + changeStateShopPro: function (isShow = false) { + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].tagObj.traverse(obj => { + obj.visible = isShow + }) + }, + /** + * @api {方法} changeShowTagObjState(isShow) 自定义标签 + * @apiGroup 地图交互 + * @apiDescription 自定义标签展示/隐藏 + * @apiVersion 2.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 2.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 2.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","#2246d8") + * + */ + drawCurveLine: function (startShop, endShop, color = '#0099ff') { + let sp, ep, cp1, cp2 + if (Array.isArray(startShop) && Array.isArray(endShop)) { + return { msg: '只能有一个数组' } + } + if (Array.isArray(startShop)) { + //如果是数组 + endShop = Map_QM.shopNumToNavPoint({ shopNum: endShop }, 'shop') + for (let i = 0; i < startShop.length; i++) { + startShop[i] = Map_QM.shopNumToNavPoint({ shopNum: 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.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)) + } + } else { + startShop = Map_QM.shopNumToNavPoint({ shopNum: startShop }, 'shop') + if (Array.isArray(endShop)) { + //如果是数组 + for (let i = 0; i < endShop.length; i++) { + endShop[i] = Map_QM.shopNumToNavPoint({ shopNum: 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.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)) + } + } else { + endShop = Map_QM.shopNumToNavPoint({ shopNum: 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.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)) + } + } + }, + /** + * @api {方法} drawColumnar(source,property) 绘制柱状图 + * @apiGroup 地图交互 + * @apiDescription 绘制柱状图 + * @apiVersion 2.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 (shopNum, property) { + if (shopNum.trim() != '' && property) { + endShop = Map_QM.shopNumToNavPoint({ shopNum: shopNum }, 'shop') + let geometry = new THREE.BoxGeometry(property.width * 2, property.width * 2, property.width * 2) + let c = new THREE.Color(property.color) + let material = new THREE.ShaderMaterial({ + uniforms: { + targetColor: { value: new THREE.Vector3(c.r, c.g, c.b) }, + height: { value: property.height / 5 } + }, + transparent: true, + opacity: property.opacity, + //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,(1.0 - modelPos.y/height)*(1.0 - modelPos.y/height));', + '}' + ].join('\n') + }) + //let material = new THREE.MeshPhongMaterial( { color: property.color, opacity: property.opacity, transparent:true, side: THREE.DoubleSide } ); + 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 material_line + for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) { + let color2 = new THREE.Color(property.color) + if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) { + material_line = Map_QM.util.lineBasicMaterialArr[k] + } + } + if (!material_line) { + material_line = new THREE.LineBasicMaterial({ + color: property.color + }) //材质对象lineColor + Map_QM.util.lineBasicMaterialArr.push(material_line) + } + 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 2.0.0 + * + * @apiParam type 传入删除的类型(默认 all) toLine--引导线 columer--柱状样式 all---所有 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.removeDrawEle("toLine") + * + */ + removeDrawEle: function (type = 'all') { + 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]) + } + } + } + } + }, + /** + * @api {方法} rotationAngle(angle) 改变水平角度 + * @apiGroup 地图显示 + * @apiDescription 改变地图水平角度 angle>-180 && angle<180 + * @apiVersion 2.0.0 + * + * @apiParam {int} angle 旋转角度 + * + * @apiSampleRequest off + * + * @apiParamExample {int} 请求示例 + * + * Map_QM.rotationAngle(90); + * + */ + rotationAngle: function (angle) { + Map_QM.controls.setRotateHorizontal((angle / 180) * Math.PI) + }, + /** + * @api {方法} rotateAngle(angle) 改变垂直角度 + * @apiGroup 地图显示 + * @apiDescription 改变地图垂直角度 angle>-90 && angle<90 + * @apiVersion 2.0.0 + * + * @apiParam {int} angle 旋转角度 + * + * @apiSampleRequest off + * + * @apiParamExample {int} 请求示例 + * + * Map_QM.rotateAngle(-45); + * + */ + rotateAngle: function (angle) { + Map_QM.controls.rotate((angle / 180) * Math.PI) + }, + /** + * @api {方法} setCameraDist(cDist) 调整地图大小 + * @apiGroup 地图显示 + * @apiDescription 调整地图大小(值越小地图越大) Map_QM.util.options.minDis ~ Map_QM.util.options.maxDis + * @apiVersion 2.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 2.0.0 + * + * @apiSampleRequest off + * @apiParamExample 请求示例 + * + * Map_QM.startRender(); + * + */ + startRender: function () { + Map_QM.cancelRender() + renderFrame = requestAnimationFrame(Map_QM.startRender) + let T = Map_QM.util._clock.getDelta() + Map_QM.util.timeObj.timeS = Map_QM.util.timeObj.timeS + T + // requestAnimationFrame默认调用render函数60次,通过时间判断,降低renderer.render执行频率 + if (Map_QM.util.timeObj.timeS > 0.03) { + if (Map_QM.qiModel) { + Map_QM.qiModel.rotateY(0.05) + } + if (Map_QM.endModel) { + Map_QM.endModel.rotateY(0.05) + } + if (debug) { + Map_QM.controls.object.position.x = Map_QM.util.guiOptions.cameraX + Map_QM.controls.object.position.y = Map_QM.util.guiOptions.cameraY + Map_QM.controls.object.position.z = Map_QM.util.guiOptions.cameraZ + + Map_QM.controls.target.x = Map_QM.util.guiOptions.targatX + Map_QM.controls.target.y = Map_QM.util.guiOptions.targatY + Map_QM.controls.target.z = Map_QM.util.guiOptions.targatZ + } + + Map_QM.controls.update() + Map_QM.renderer.render(Map_QM.scene, Map_QM.camera) + Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera) + for (let item of Map_QM.mixers) { + item.update(T) + } + if (debug) { + stats.update() + } + //timeS置0 + Map_QM.util.timeObj.timeS = 0 + } + }, + /** + * @api {方法} cancelRender() 取消地图渲染 + * @apiGroup 地图显示 + * @apiDescription 取消地图渲染 与 startRender 配合使用可节约资源 + * @apiVersion 2.0.0 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.cancelRender(); + * + */ + cancelRender: function () { + window.cancelAnimationFrame(renderFrame) + renderFrame = -1 + }, + + /** + * @api {方法} addElementLabel() 地图html标签 + * @apiGroup 地图交互 + * @apiDescription 地图显示Html标签,返回3d标签对象 + * @apiVersion 2.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 + Map_QM.elementDestroy(type) + 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.name = 'shopInfo' + Map_QM.CSSObject.add(shopInfo) + TweenMax.to(divObj.style, 0.2, { opacity: 1, delay: 0.1 }) + return shopInfo + }, + /** + * @api {方法} updateElementPosition() 修改标签位置 + * @apiGroup 地图交互 + * @apiDescription 修改标签位置 + * @apiVersion 2.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 2.0.0 + * @apiParam {String} type docment元素自定义标识(默认 "shopInfo") + * + * @apiSampleRequest off + * + * @apiParamExample {Object} 请求示例 + * + * Map_QM.elementDestroy(); + * + */ + elementDestroy: function (type = 'shopInfo') { + for (let i = Map_QM.CSSObject.children.length - 1; i >= 0; i--) { + if (Map_QM.CSSObject.children[i].userData && Map_QM.CSSObject.children[i].userData.type == type) { + Map_QM.CSSObject.remove(Map_QM.CSSObject.children[i]) + } + } + }, + /** + * @api {方法} changeShowShopName() 修改店铺显示名称 + * @apiGroup 地图显示 + * @apiDescription 通过店铺编号修改店铺显示名称 + * @apiVersion 2.0.0 + * @apiParam {Array} shopNum 店铺编号 + * @apiParam {Array} element html标签字符串 + * @apiSampleRequest off + * + * @apiParamExample {String} 请求示例 + * Map_QM.changeShowShopName(["L104"],['

肯德基

']) + */ + 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 {方法} unionShop() 店铺合并 + * @apiGroup 地图显示 + * @apiDescription 通过店铺编号合并店铺 合铺 + * @apiVersion 2.0.0 + * @apiParam {Array} shops 店铺编号数组 + * @apiParam {Object} data 新的店铺数据(默认 空数据) + * @apiSampleRequest off + * + * @apiParamExample {String} 请求示例 + * Map_QM.unionShop(["L105","L106","L107","L108"],{name:"新店",shopNum:"L104-L108",color:"#F4A460"}) + */ + unionShop: function (shops, data = { name: '', shopNum: '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].allObj.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].allObj.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]) { + 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.shopNum = data.name + mesh.userData.entColor = data.color + mesh.userData.type = 'shop' + if (data.name) { + mesh.name = data.name + let shopDiv = document.createElement('div') + shopDiv.style.cssText = css_LR + 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.shopNum || data.name + 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) + } + }, + + //////////////////////////////////////////////////////////////////////////////// + + /** + * @param {Object} e + * 地图BOX点击 + */ + onMouseClickBox: function (event) { + if (Map_QM.util.isInnerTouch) { + 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.util.selectBuild] && !Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) { + 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 + //图标点击 + for (let i = 0; i < intersects.length; i++) { + //图标点击 + if ( + intersects[i].object.userData && + (intersects[i].object.userData.type == 'icon' || + intersects[i].object.parent.userData.type == 'icon' || + intersects[i].object.parent.parent.userData.type == 'icon') + ) { + if (Map_QM.endModel && Map_QM.endModel.visible) { + Map_QM.endModel.visible = false + } + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.clearPath() + let buildOrder = + intersects[i].object.userData.buildOrder || intersects[i].object.parent.userData.buildOrder || intersects[i].object.parent.parent.userData.buildOrder || 0 + let floorOrder = + intersects[i].object.userData.floorOrder || intersects[i].object.parent.userData.floorOrder || intersects[i].object.parent.parent.userData.floorOrder || 0 + let navCode = intersects[i].object.userData.navCode || intersects[i].object.parent.userData.navCode || intersects[i].object.parent.parent.userData.navCode + let src = intersects[i].object.userData.src || intersects[i].object.parent.userData.src || intersects[i].object.parent.parent.userData.src + let facCode = intersects[i].object.userData.facCode || intersects[i].object.parent.userData.facCode || intersects[i].object.parent.parent.userData.facCode + let title = intersects[i].object.userData.title || intersects[i].object.parent.userData.title || intersects[i].object.parent.parent.userData.title + /** + * @api {事件} icon 点击设施图标 + * @apiGroup 地图事件 + * @apiDescription 用户点击设施图标后触发自定义事件 + * @apiVersion 2.0.0 + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * Map_QM.addEventListener("icon",onClickIcon,false); + */ + Map_QM.dispatchEvent({ + type: 'icon', + data: { buildOrder: buildOrder, floorOrder: floorOrder, node: navCode, src: src, facCode: facCode, title: title } + }) + console.log('触发 icon 事件 ', { + type: 'icon', + data: { buildOrder: buildOrder, floorOrder: floorOrder, node: navCode, src: src, facCode: facCode, title: title } + }) + return + } + } + + for (let i = 0; i < intersects.length; i++) { + //店铺BOX点击 + if (intersects[i].object.userData && intersects[i].object.userData.type == 'shop' && 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 + } + } + /** + * @api {事件} shop 点击已绑定品牌的店铺 + * @apiGroup 地图事件 + * @apiDescription 用户点击店铺后触发自定义事件 + * @apiVersion 2.0.0 + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * Map_QM.addEventListener("shop",onClickShop,false); + */ + if (clickShop && Map_QM.selectShop && Map_QM.selectShop.userData) { + if ((iot && Map_QM.selectShop.userData.shopData.hasOwnProperty('shopName')) || (!iot && Map_QM.selectShop.userData.shopData.hasOwnProperty('name'))) { + Map_QM.dispatchEvent({ + type: 'shop', + data: Map_QM.selectShop.userData + }) + } else { + /** + * @api {事件} onlyShop 点击未绑定品牌的店铺 + * @apiGroup 地图事件 + * @apiDescription 用户点击空店铺后触发自定义事件 + * @apiVersion 2.0.0 + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * Map_QM.addEventListener("onlyShop",onClickShop,false); + */ + Map_QM.dispatchEvent({ + type: 'onlyShop', + data: Map_QM.selectShop.userData + }) + } + } else { + Map_QM.dispatchEvent({ + type: 'shop', + data: null + }) + } + }, + /** + * @api {方法} setSelectShopMatByName(shopNum) 设置box 选中 + * @apiGroup 地图交互 + * @apiDescription 地图box 选中 + * @apiVersion 2.0.0 + * @apiParam {String} shopNum 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) + }, + /** + * 初始化后调用 + */ + timeOutInit: 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) + 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 + }) + Map_QM.collLabel() + }, + + 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.traverse) { + item.children.traverse(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 + } + } + }) + } + }) + } + } + } + }, + /** + * 碰撞检测 + * @param {Object} 传入检测楼层下标 + */ + controlsChock: function () { + Map_QM.autoChangeEleAngle() + /** + * @api {事件} MapAngleChange 地图的方向改变 + * @apiGroup 地图事件 + * @apiDescription 用户操作地图时触发 + * @apiVersion 2.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) { + clearTimeout(shopTime) + shopTime = setTimeout(() => { + clearTimeout(shopTime) + isJUZ = false + Map_QM.controls.reset() + }, 3000) + } + if (debug) { + Map_QM.util.guiOptions.cameraX = Map_QM.controls.object.position.x + Map_QM.util.guiOptions.cameraY = Map_QM.controls.object.position.y + Map_QM.util.guiOptions.cameraZ = Map_QM.controls.object.position.z + + Map_QM.util.guiOptions.targatX = Map_QM.controls.target.x + Map_QM.util.guiOptions.targatY = Map_QM.controls.target.y + Map_QM.util.guiOptions.targatZ = Map_QM.controls.target.z + } + if (Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) { + //支持缩放切换 + let distance = Map_QM.controls.getDistance() + if (distance <= Map_QM.util.changeDist.inner) { + //切换到室内 + Map_QM.util.isInnerTouch = true + if (Map_QM.outModelGap.visible) { + TweenMax.to(Map_QM.outModelGap.scale, 0.5, { + y: 0.01, + ease: Quad.easeIn, + onComplete: function () { + Map_QM.hideObjecrGap(Map_QM.outModelGap, false) //隐藏外立面 + } + }) + } + if (Map_QM.peripheryGap.visible) { + Map_QM.hideObjecrGap(Map_QM.peripheryGap, false) //隐藏周边 + } + if (!Map_QM.buildObj.userData.visible) { + Map_QM.buildObj.visible = true + Map_QM.buildObj.userData.visible = true + Map_QM.changeFloorInner(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor) + } + Map_QM.buildObj.traverse(obj => { + if (obj.isMesh) { + obj.material.opacity = obj.userData.opacity || 1 + obj.material.transparent = true + } + }) + } else if (distance > Map_QM.util.changeDist.outner && Map_QM.util.initModelArr.length > 1) { + //周边 + Map_QM.util.isInnerTouch = false + Map_QM.buildObj.userData.visible = false + Map_QM.buildObj.visible = false + Map_QM.changeFloorInner(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor) + + if (Map_QM.endModel && Map_QM.endModel.visible) { + Map_QM.endModel.visible = false + } + if (!Map_QM.peripheryGap.visible) { + TweenMax.to(Map_QM.peripheryGap.scale, 0.8, { y: 1 }) + } + Map_QM.hideObjecrGap(Map_QM.peripheryGap, true) + if (Map_QM.outModelGap.visible) { + TweenMax.to(Map_QM.outModelGap.scale, 0.5, { + y: 0.01, + ease: Quad.easeIn, + onComplete: function () { + Map_QM.hideObjecrGap(Map_QM.outModelGap, false) //隐藏外立面 + } + }) + } + } 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.util.isInnerTouch = false + Map_QM.buildObj.userData.visible = false + Map_QM.buildObj.visible = true + if (Map_QM.endModel && Map_QM.endModel.visible) { + Map_QM.endModel.visible = false + } + if (!Map_QM.outModelGap.visible) { + TweenMax.to(Map_QM.outModelGap.scale, 0.8, { y: 1 }) + } + Map_QM.hideObjecrGap(Map_QM.outModelGap, true) + } + } + Map_QM.collLabel() + }, + + hideObjecrGap: function (gap, isShow) { + gap.visible = isShow + gap.traverse(obj => { + if (obj.userData && obj.userData.type == '2d_IP') { + obj.element.style.visibility = isShow ? 'visible' : 'hidden' + } + if (obj.isMesh) { + obj.material.opacity = obj.userData.opacity + obj.material.transparent = true + } + }) + }, + + //内部碰撞检测 + collLabel: function () { + if (!Map_QM || !Map_QM.util.options.collision) { + return + } + clearTimeout(Map_QM.util.timeObj.collTime) + Map_QM.util.timeObj.collTime = setTimeout(() => { + clearTimeout(Map_QM.util.timeObj.collTime) + let checkList = [] + if (Map_QM.util.options.overlap) { + for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { + Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.traverse(obj => { + if (obj.name == 'floor' && Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.visible) { + // + checkList.push(obj) + } + }) + } + } + if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.buildObj.visible) { + 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 && (!Map_QM.buildObj.userData.hasOwnProperty('visible') || Map_QM.buildObj.userData.visible)) { + let childs = Map_QM.mapArr[Map_QM.util.selectBuild][m].labelObj.children + let len = childs.length + for (let i = 0; i < len; i++) { + let obj = childs[i].element + if (childs[i].userData.mapShow) { + obj.style.visibility = 'visible' + } else { + obj.style.visibility = 'hidden' + } + if (obj.style.transform) { + obj.style.visibility = 'visible' + let labP = obj.getBoundingClientRect() + for (let j = 0; j < i; j++) { + if (childs[j].element.style.visibility == 'visible') { + let pb = childs[j].element.getBoundingClientRect() + let isCol = Map_QM.util.isCollision(labP, pb) + if (isCol) { + if (!childs[i].userData.mapShow) { + obj.style.visibility = 'hidden' + break + } else if (!childs[j].userData.mapShow) { + childs[j].element.style.visibility = 'hidden' + } + } + } + } + } + } + + if (Map_QM.util.options.overlap) { + let renChild = Map_QM.mapArr[Map_QM.util.selectBuild][m].showTagObj.children + const { left, top } = Map_QM.renderer.domElement.getBoundingClientRect() + renChild.forEach(item => { + if (item.element.style.visibility == 'visible') { + let check = Map_QM.util.blocked(item.element, checkList, m, top, left) + if (check) { + item.element.style.visibility = 'hidden' + } + } + }) + childs.forEach(item => { + if (item.element.style.visibility == 'visible') { + let check = Map_QM.util.blocked(item.element, checkList, m, top, left) + if (check) { + item.element.style.visibility = 'hidden' + } + } + }) + } + } else { + let childs = Map_QM.mapArr[Map_QM.util.selectBuild][m].labelObj.children + childs.forEach(item => { + item.element.style.visibility = 'hidden' + }) + } + } + } + }, 500) + }, + + /** + * 寻路---------------------------------------------------------------------------------------------------------------------------------------- + */ + + /** + * @api {方法} bounceIcon({type:"xsj"}) 图标弹跳 + * @apiGroup 地图导航 + * @apiDescription 地图图标弹跳效果 + * @apiVersion 2.0.0 + * @apiParam {String} iconType 设施缩写 + * + * @apiSampleRequest off + * + * @apiParamExample {String} 请求示例 + * + * Map_QM.bounceIcon({type:"xsj"}); + * + */ + bounceIcon: function (iconType) { + let toFloor = parseInt(Map_QM.util.selectFloor) + let facs = Map_QM.mapArr[Map_QM.util.selectBuild][toFloor].serObj.children //交通图标 + for (let i = 0; i < facs.length; i++) { + if (facs[i].type == 'Sprite') { + facs[i].reSetSite() + if (facs[i].facCode == iconType) { + facs[i].jumpIcon() + } + } + } + }, + /** + * @api {方法} pathIcon({type:"xsj"}) 获取最近设施 + * @apiGroup 地图导航 + * @apiDescription 获取离当前楼层最近的设施 + * @apiVersion 2.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 + toIcon = iconType.type + if (!Map_QM.util.startObj.build && parseInt(Map_QM.util.startObj.build) != 0) { + Map_QM.util.startObj.build = parseInt(Map_QM.util.deviceObj.build) + } + 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.graphPath, 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].facCode == iconType.type) { + let toNade = parseInt(Map_QM.util.deviceObj.build) + '_' + sers[n].floor + '_' + sers[n].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.floor, + site: { x: selIcon.position.x, y: selIcon.position.y }, + node: selIcon.navCode, + no: selIcon.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].facCode == iconType.type) { + let toNade = parseInt(Map_QM.util.deviceObj.build) + '_' + sers[n].floor + '_' + sers[n].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.floor, + node: selIcon.navCode, + site: { x: selIcon.position.x, y: selIcon.position.y }, + no: selIcon.no, + typeCode: Map_QM.util.getFacType(iconType.type) + } + } + } + }, + /** + * @api {方法} pathByStartAndOver(startObj,toObj,callBackFun) 地图路径规划 + * @apiGroup 地图导航 + * @apiDescription 根据传入的起、终点;直接导航 + * @apiVersion 2.0.0 + * @apiParam {String} startObj.shopNum 店铺编号/车位编号 + * @apiParam {String} startObj.type "shop"/"park" + * + * @apiParam {String} toObj.shopNum 店铺编号/车位编号 + * @apiParam {String} toObj.type "shop"/"park" + * + * @apiParam {Function} callBackFun 回调函数 + * + * @apiSampleRequest off + * + * @apiParamExample {String} 请求示例 + * + * Map_QM.pathByStartAndOver({"shopNum":"L102","type":"shop"},{"shopNum":"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) { + return '传入点位无法导航' + } + }, + + /** + * @api {方法} changeStartPoint() 设置起始点位 + * @apiGroup 地图导航 + * @apiDescription 设置起始点位 + * @apiVersion 2.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() + 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) + } + } + } + if (toObj && toObj.node) { + let pathData = this.util.allMap[parseInt(toObj.build)].buildArr[parseInt(toObj.floor)].mapData.path + this.util.deviceObj.xaxis = this.util.startObj.xaxis = pathData.nodes[parseInt(toObj.node)].x + this.util.deviceObj.yaxis = this.util.startObj.yaxis = pathData.nodes[parseInt(toObj.node)].y + this.util.deviceObj.build = this.util.startObj.build = parseInt(toObj.build) + this.util.deviceObj.floor = this.util.startObj.floor = parseInt(toObj.floor) + this.util.deviceObj.node = this.util.startObj.node = toObj.node + this.util.deviceObj.angle = this.util.startObj.angle = toObj.angle || 0 + } else { + let pathData = this.util.allMap[parseInt(this.util.deviceObj.build)].buildArr[parseInt(this.util.deviceObj.floor)].mapData.path + pathData.nodes.sort(this.util.sortNode) + 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.startObj = this.util.deviceObj + } + 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) + ) + }, + + /** + * @api {方法} changeMapIPState(ipName,color) 改变POI颜色 + * @apiGroup 地图交互 + * @apiDescription 改变POI 颜色 + * @apiVersion 2.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].material = this.util.getMeshMaterial(color || 0xeab16e) + break + } + } + } + }, + /** + * @api {方法} getMapIPData(ipName) 获取POI 基础数据 + * @apiGroup 地图交互 + * @apiDescription 获取POI 基础数据 + * @apiVersion 2.0.0 + * @apiParam {string} ipName POI名称 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.getMapIPData("L1001"); + * + * @apiSuccessExample 返回示例 + * { + * shopNum:店铺编号, 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].allObj.children + for (let k = 0; k < shopArr.length; k++) { + if (shopArr[k].name == ipName) { + return shopArr[k].userData + } + } + } + }, + + /** + * @api {方法} pathNode() 地图模拟导航 + * @apiGroup 地图导航 + * @apiDescription 地图路径模拟导航 + * @apiVersion 2.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) { + if (!toObj) { + return { direction: '', wayList: [] } + } + pathCameraState = Map_QM.util.options.pathStyle + Map_QM.onShowDeviceSite() + Map_QM.clearFloor(-1, true) + Map_QM.selectShop = null + Map_QM.util.pathStateObj.isPathState = true + 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, shopNum: toObj.shopNum } + if (Map_QM.util.overObj.node != '') { + Map_QM.cancelRender() + this.onFindPathModel() + if (Map_QM.util.options.overlap) { + //叠层导航--固定地图仰角 + Map_QM.controls.maxPolarAngle = 1.17 + Map_QM.controls.minPolarAngle = 1.17 + } + if (callBackFun) { + Map_QM.parseForShopArr() + const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr)) + callBackFun(data) + } + Map_QM.startRender() + } + }, + 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.nameEn == '' ? item.wayShop[i].shop.name : item.wayShop[i].shop.nameEn + Map_QM.util.pathStateObj.forShopArr.wayList.push({ + isAddPrefix: false, + name: '经过 ' + item.wayShop[i].shop.name, + nameEn: 'PASS ' + enTlite, + logoPath: item.wayShop[i].shop.logoPath, + code: item.wayShop[i].shop.code, + shopNum: iot ? item.wayShop[i].shop.houseNumber : item.wayShop[i].shop.houseNum + }) + } + } + if (item.hasOwnProperty('Facilities') && item.Facilities) { + //设施 + Map_QM.util.pathStateObj.forShopArr.wayList.push({ + isAddPrefix: true, + name: '乘坐 ' + item.Facilities.userData.title + '到 ' + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, + nameEn: 'BY ' + item.Facilities.userData.title + 'TO ' + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, + logoPath: item.Facilities.imgUrl, + code: ((Math.random() * 0x1234567) | 0).toString(16).substring(0), + shopNum: item.Facilities.userData.facCode + item.Facilities.userData.no + }) + } + }) + }, + /** + * @api {方法} getGapByPathNode() 获取实际距离 + * @apiGroup 地图导航 + * @apiDescription 通过点位获取距离 + * @apiVersion 2.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.graphPath, 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)} 米,预计${mint} 分钟`) // 21 是比例尺 + } catch (e) { + console.log(e) + } + return { dis: parseInt(path.cost / Map_QM.util.options.mapScale), time: minTime } + }, + /** + * @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 == 'Sprite') { + let title = sers[n].userData.title || Map_QM.util.getFacName(sers[n].facCode) + let titleEn = Map_QM.util.iconEn[title] + let type = sers[n].facCode + let imgUrl = sers[n].imgUrl + if (sers[n].facCode == 'upft' || sers[n].facCode == 'downft' || sers[n].facCode == 'ft') { + if (title == '上扶梯' || title == '下扶梯') { + title = '扶梯' + } + titleEn = Map_QM.util.iconEn['扶梯'] + type = 'ft' + } + let icon = { type: type, floor: floorOrder, imgUrl: imgUrl, poid: sers[n].userData.poid, 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 == 'Sprite') { + let title = sers[n].userData.title || Map_QM.util.getFacName(sers[n].facCode) + let titleEn = Map_QM.util.iconEn[title] + let type = sers[n].facCode + let imgUrl = sers[n].imgUrl + if (sers[n].facCode == 'upft' || sers[n].facCode == 'downft' || sers[n].facCode == 'ft') { + title = '扶梯' + titleEn = Map_QM.util.iconEn[title] + type = 'ft' + } + let icon = { type: type, floor: i, imgUrl: imgUrl, poid: sers[n].userData.poid, title: title, titleEn: titleEn } + iconArr.push(icon) + } + } + } + iconBuild.push(iconArr) + } + icons.push(iconBuild) + } + return icons + }, + /** + * @api {方法} pathPark() 获取车位点位 + * @apiGroup 地图数据 + * @apiDescription 获取车位导航点 + * @apiVersion 2.0.0 + * @apiParam {String} shopNum 车位编号 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.pathPark({shopNum:"B1002"}); + * + * @apiSuccessExample 返回示例 + * { + * shopNum: 车位编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标 + * } + */ + pathPark: function (toObj) { + return this.shopNumToNavPoint(toObj, 'park') + }, + + /** + * @api {方法} pathShopByName() 获取店铺点位 + * @apiGroup 地图数据 + * @apiDescription 通过店铺名称获取点位 + * @apiVersion 2.0.0 + * @apiParam {String} shopName 店铺名称 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.pathShopByName("金拱门"); + * + * @apiSuccessExample 返回示例 + * { + * shopNum: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点 + * } + */ + pathShopByName: function (shopName) { + for (let item of Map_QM.util.shopData) { + if (item.name === shopName) { + let toObj = { shopNum: iot ? item.houseNumber : item.houseNum, 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.shopNum) { + 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 {方法} shopNumToNavPoint() 获取导航点位 + * @apiGroup 地图导航 + * @apiDescription 通过店铺编号或车位获取导航点位 + * @apiVersion 2.0.0 + * @apiParam {Object} object build,floor,shopNum 楼栋编号,楼层编号,店铺或车位编号 + * @apiParam {String} type 店铺或车位标识 "shop" "park" + * + * @apiSampleRequest off + * + * @apiSuccessExample 返回示例 + * { + * shopNum: 店铺编号, 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.shopNum) { + reObj.floor = i + reObj.build = h + reObj.xaxis = shopArr[k].xaxis + reObj.yaxis = shopArr[k].yaxis + reObj.node = shopArr[k].shopNav + reObj.shopNum = obj.shopNum + 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 (parseInt(Map_QM.util.startObj.node) == -1) { + return + } + 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) + } + } + Map_QM.forShopPath(usePath) + }, + forShopPath: function (usePath) { + 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 + try { + path = dijkstra.find_path(usePath, startNade, toNade) + } catch (e) { + console.log(e) + return + } + + let PathPoint = path.nodes + 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 2.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() + } + }, + /** + * 途径店铺 + */ + foreignShop: function (pathArr, build, cFloor, m) { + let shopList = [] + let shops = Map_QM.mapArr[parseInt(build)][parseInt(cFloor)].allObj.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].navCode == fromFArr[2]) { + selectEle = { imgUrl: childs[i].imgUrl, userData: childs[i].userData, position: { x: childs[i].position.x, y: childs[i].position.y } } + break + } + } + return selectEle + }, + + /** + * 寻路动画方法 + */ + onFindPathToObj: function () { + outTime = -1 + Map_QM.util._indexPathFloor = 0 + Map_QM.callBackLoadOver = Map_QM.callBackForPathShop //楼层初始化完成后回调 + + if (Map_QM.util.options.overlap) { + if (Map_QM.forShopArr.length == 2) { + Map_QM.changeFloorInner(-1, Map_QM.forShopArr[0].floor, () => {}, Map_QM.forShopArr[1].floor) + } else if (Map_QM.forShopArr.length == 3) { + Map_QM.changeFloorInner(-1, Map_QM.forShopArr[0].floor, () => {}, Map_QM.forShopArr[1].floor, Map_QM.forShopArr[2].floor) + } else { + Map_QM.changeFloorInner(-1, Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor) + } + } else { + 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.options.overlap) { + Map_QM.mapArr[Map_QM.util.overObj.build][Map_QM.util.overObj.floor].setOverSite( + Map_QM.util.overObj.xaxis, + Map_QM.util.overObj.yaxis, + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.overObj.floor].allObj.position.y + parseInt(Map_QM.util.shopHeight) + ) + } else { + 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) + ) + } + } + + if (Map_QM.forShopArr.length > 0) { + document.addEventListener('pathOver', Map_QM.onFindPathFloor, true) + if (Map_QM.util.options.overlap && Map_QM.util._indexPathFloor == 0) { + //叠层 + for (let pathObj of Map_QM.forShopArr) { + Map_QM.mapArr[pathObj.build][pathObj.floor].findPath.onFindPathAnimation(pathObj.PathPoint, pathObj.floor) //传入数组 + } + let extrudeSettings + let vects = new THREE.CurvePath() + let vects2 = new THREE.CurvePath() + if (Map_QM.forShopArr.length == 2) { + vects.add( + new THREE.LineCurve3( + new THREE.Vector3( + Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].x, + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[0].floor].allObj.position.y, + Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].y + ), + new THREE.Vector3( + Map_QM.forShopArr[1].PathPoint[0].x, + Map_QM.mapArr[Map_QM.forShopArr[1].build][Map_QM.forShopArr[1].floor].allObj.position.y, + Map_QM.forShopArr[1].PathPoint[0].y + ) + ) + ) + extrudeSettings = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects } + let geometry = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings) + let lineDashed = new THREE.Mesh(geometry, Map_QM.util.tubeMaterial) + Map_QM.dtLineGroup.add(lineDashed) + } + if (Map_QM.forShopArr.length == 3) { + vects.add( + new THREE.LineCurve3( + new THREE.Vector3( + Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].x, + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[0].floor].allObj.position.y, + Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].y + ), + new THREE.Vector3( + Map_QM.forShopArr[1].PathPoint[0].x, + Map_QM.mapArr[Map_QM.forShopArr[1].build][Map_QM.forShopArr[1].floor].allObj.position.y, + Map_QM.forShopArr[1].PathPoint[0].y + ) + ) + ) + + vects2.add( + new THREE.LineCurve3( + new THREE.Vector3( + Map_QM.forShopArr[1].PathPoint[Map_QM.forShopArr[1].PathPoint.length - 1].x, + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[1].floor].allObj.position.y, + Map_QM.forShopArr[1].PathPoint[Map_QM.forShopArr[1].PathPoint.length - 1].y + ), + new THREE.Vector3( + Map_QM.forShopArr[2].PathPoint[0].x, + Map_QM.mapArr[Map_QM.forShopArr[2].build][Map_QM.forShopArr[2].floor].allObj.position.y, + Map_QM.forShopArr[2].PathPoint[0].y + ) + ) + ) + extrudeSettings = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects } + extrudeSettings2 = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects2 } + let geometry = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings) + let lineDashed = new THREE.Mesh(geometry, Map_QM.util.tubeMaterial) + Map_QM.dtLineGroup.add(lineDashed) + let geometry2 = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings2) + let lineDashed2 = new THREE.Mesh(geometry2, Map_QM.util.tubeMaterial) + Map_QM.dtLineGroup.add(lineDashed2) + } + } 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 + ) //传入数组 + } + 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 2.0.0 + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * Map_QM.addEventListener("PathPlaying",onPathPlaying,false); + */ + Map_QM.dispatchEvent({ + //寻路中返回小人当前所在点位 + type: 'PathPlaying', + data: { + shopNum: 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 = 7.5 + } + }) + } + + let zo = 2, + tz = 2, + boxT = 0, + boxZ = 0 + let add = Map_QM.util.options.showStyle ? 80 : 40 + 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 = 27 + } else { + zo = (floorArr.length - 1) * add + boxZ = 27 + } + + 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.visibility = 'visible' + Map_QM.moveFloorbg.element.style.width = add + 8 + 'px' + Map_QM.moveFloorbg.element.style.height = floorArr.length * add + 'px' + Map_QM.moveFloorbg.position.set(x0, y0, 80) + Map_QM.moveFloorbg.applyMatrix4(Map_QM.mapArr[parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)][pathFloor].allObj.matrix) + Map_QM.moveFloorbg.applyMatrix4(Map_QM.sceneGap.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 (Map_QM.util.options.showStyle) { + span2.style.fontSize = '32px' + } + span2.style.width = add + '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.visibility = 'hidden' + if (!Map_QM.util.options.overlap) { + 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) + } else { + if (Map_QM.forShopArr > Map_QM.util._indexPathFloor) { + Map_QM.util.selectFloor = Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor + } + Map_QM.clearFloor(-1, false) + Map_QM.callBackForPathShop() + } + } + } + ) + 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 2.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.visibility = 'hidden' + } + 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 lines = Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj + for (let j = lines.children.length - 1; j >= 0; j--) { + Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj.remove(lines.children[j]) + } + 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) + } + 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 2.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 2.0.0 + * + * @apiSampleRequest off + * + */ + pathRePlay: function () { + clearTimeout(Map_QM.util.timeObj.pathTime) + Map_QM.util.timeObj.pathTime = setTimeout(() => { + clearTimeout(Map_QM.util.timeObj.pathTime) + 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 2.0.0 + * + * @apiParam {function} callBack 回调函数 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.ChangePathByFt(function); + * + */ + ChangePathByFt: function (callBack) { + clearTimeout(Map_QM.util.timeObj.pathTime) + Map_QM.util.timeObj.pathTime = setTimeout(() => { + clearTimeout(Map_QM.util.timeObj.pathTime) + 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 2.0.0 + * + * @apiParam {function} callBack 回调函数 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.ChangePathByDt(function); + * + */ + ChangePathByDt: function (callBack) { + clearTimeout(Map_QM.util.timeObj.pathTime) + Map_QM.util.timeObj.pathTime = setTimeout(() => { + clearTimeout(Map_QM.util.timeObj.pathTime) + 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 2.0.0 + * + * @apiParam {function} callBack 回调函数 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.ChangePathByGood(function); + * + */ + ChangePathByGood: function (callBack) { + clearTimeout(Map_QM.util.timeObj.pathTime) + Map_QM.util.timeObj.pathTime = setTimeout(() => { + clearTimeout(Map_QM.util.timeObj.pathTime) + 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 ele = document.getElementById(options.containerId || 'mapContainer') + let w = parseInt(ele.clientWidth) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('width')) + let h = parseInt(ele.clientHeight) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('height')) + Map_QM.changeWindowResize(w, h) + }, + /** + * @api {方法} changeWindowResize() 窗口变化 + * @apiGroup 地图交互 + * @apiDescription 窗口变化 + * @apiVersion 2.0.0 + * + * @apiParam {int} width 窗口宽 + * @apiParam {int} height 窗口高 + * + * @apiSampleRequest off + * + * @apiParamExample 请求示例 + * + * Map_QM.changeWindowResize(1280,1080); + */ + changeWindowResize: function (width, height) { + Map_QM.aspect = width / height + Map_QM.cameraPerspective.aspect = Map_QM.aspect + Map_QM.cameraPerspective.updateProjectionMatrix() + Map_QM.cameraOrtho.left = -150 * Map_QM.aspect + Map_QM.cameraOrtho.right = 150 * Map_QM.aspect + Map_QM.cameraOrtho.updateProjectionMatrix() + Map_QM.renderer.setSize(width, height) + Map_QM.labelRenderer.setSize(width, height) + Map_QM.w = width + Map_QM.h = height + } } /** - * @api {方法} init(callBack,options) 地图初始化 - * @apiGroup 地图数据 - * @apiDescription 初始化地图赋值 Map_QM - * @apiVersion 2.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 动画播放速度 默认值6 - * @apiParam {boolean} options.collision 是否支持名称的碰撞检测 默认值 true - * @apiParam {boolean} options.showStyle 是否4K显示 默认值false - * @apiParam {boolean} options.modelIcon 交通设施是否使用模型 默认值 true - * @apiParam {Array} options.otherPath 人为干预的路线 默认值 []; - * @apiParam {int} options.fSpace 双叠层状态下楼层的间距 默认值 500 - * @apiParam {uint} options.navColor 途径店铺颜色 默认值 0xEE6A50 - * @apiParam {boolean} options.overlap 是否叠层 默认值 false - * @apiParam {boolean} options.shadow 是否显示阴影 默认值 true - * @apiParam {boolean} options.iconName 图标名称是否显示 默认值false - * @apiParam {uint} options.pathColor 导航路径颜色 默认值 0xb47834, - * @apiParam {string} options.pathStyle 导航第一视角 默认值 "2D", - * @apiParam {string} options.shopStyle 店铺显示字段编号(shopNum)名称(shopName) 默认值 "shopName", - * @apiParam {int} options.camZoom 地图显示我的方向状态的放大倍数 默认值 3 - * @apiParam {boolean} options.inArea 地图点击后是否聚焦到当前位置 默认值 false - * @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"}); + * @api {方法} init(callBack,options) 地图初始化 + * @apiGroup 地图数据 + * @apiDescription 初始化地图赋值 Map_QM + * @apiVersion 2.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 动画播放速度 默认值6 + * @apiParam {boolean} options.collision 是否支持名称的碰撞检测 默认值 true + * @apiParam {boolean} options.showStyle 是否4K显示 默认值false + * @apiParam {boolean} options.modelIcon 交通设施是否使用模型 默认值 true + * @apiParam {Array} options.otherPath 人为干预的路线 默认值 []; + * @apiParam {int} options.fSpace 双叠层状态下楼层的间距 默认值 500 + * @apiParam {uint} options.navColor 途径店铺颜色 默认值 0xEE6A50 + * @apiParam {boolean} options.overlap 是否叠层 默认值 false + * @apiParam {boolean} options.shadow 是否显示阴影 默认值 true + * @apiParam {boolean} options.iconName 图标名称是否显示 默认值false + * @apiParam {uint} options.pathColor 导航路径颜色 默认值 0xb47834, + * @apiParam {string} options.pathStyle 导航第一视角 默认值 "2D", + * @apiParam {string} options.shopStyle 店铺显示字段编号(shopNum)名称(shopName) 默认值 "shopName", + * @apiParam {int} options.camZoom 地图显示我的方向状态的放大倍数 默认值 3 + * @apiParam {boolean} options.inArea 地图点击后是否聚焦到当前位置 默认值 false + * @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) { - Map_QM = new MainMap_QM(callBack, options); - return Map_QM; + Map_QM = new MainMap_QM(callBack, options) + return Map_QM } -Object.assign(MainMap_QM.prototype, THREE.EventDispatcher.prototype); +Object.assign(MainMap_QM.prototype, THREE.EventDispatcher.prototype) //////////////////////////////////////-------------------------------FloorMap 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.labelObj = new THREE.Group(); - this.labelObj.renderOrder = 100; - this.iconLabel = new THREE.Group(); - this.iconLabel.renderOrder = 100; - - this.floorOrder = fIndex; - this.buildOrder = bIndex - this.floorName = floorName; - - //存放设施图标 - this.serObj = new THREE.Object3D(); - //存放车位box - this.parkObj = new THREE.Group(); - //标签 - this.tagObj = new THREE.Group(); - this.tagObj.renderOrder = 100; - this.devObj = new THREE.Group(); - //存放设施图标 - this.svgObj = new THREE.Group(); - //店铺 - this.shopObj = new THREE.Group(); - this.allObj.add(this.shopObj); - this.allObj.add(this.svgObj); - this.allObj.add(this.serObj); - this.allObj.add(this.devObj); - this.allObj.add(this.labelObj); - this.allObj.add(this.iconLabel); - this.allObj.add(this.tagObj); - //标签 - this.showTagObj = new THREE.Group(); - this.showTagObj.renderOrder = 100; - this.allObj.add(this.showTagObj); - - //线条 - this.lineObj = new THREE.Group(); - this.lineObj.renderOrder = 100; - this.allObj.add(this.lineObj); - - this.startIcon; + 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.labelObj = new THREE.Group() + this.labelObj.renderOrder = 100 + this.iconLabel = new THREE.Group() + this.iconLabel.renderOrder = 100 + + this.floorOrder = fIndex + this.buildOrder = bIndex + this.floorName = floorName + + //存放设施图标 + this.serObj = new THREE.Object3D() + //存放车位box + this.parkObj = new THREE.Group() + //标签 + this.tagObj = new THREE.Group() + this.tagObj.renderOrder = 100 + this.devObj = new THREE.Group() + //存放设施图标 + this.svgObj = new THREE.Group() + //店铺 + this.shopObj = new THREE.Group() + this.allObj.add(this.shopObj) + this.allObj.add(this.svgObj) + this.allObj.add(this.serObj) + this.allObj.add(this.devObj) + this.allObj.add(this.labelObj) + this.allObj.add(this.iconLabel) + this.allObj.add(this.tagObj) + //标签 + this.showTagObj = new THREE.Group() + this.showTagObj.renderOrder = 100 + this.allObj.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].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.receiveShadow = Map_QM.util.options.shadow; - child.castShadow = Map_QM.util.options.shadow; - 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); - obj.rotateY(Map_QM.util.modelArr[i].list[t].rot.y); - obj.rotateZ(Map_QM.util.modelArr[i].list[t].rot.z); - 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].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; - 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.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); - 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++) { - hows_f.push(Map_QM.util.changeAreaToString(mapData.hollowArea[m])); - } - if (floor) { - entColor = parseInt(mapData.floorArea.entColor.replace("#", "0x"), 16); - borderColor = parseInt(mapData.floorArea.borderColor.replace("#", "0x"), 16); - floorH = parseInt(mapData.floorArea.toHeight); - let mash = this.Model_QM.MyModelShape(floor, hows_f, mapData.floorArea, entColor, borderColor, 10); - 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 = parseInt(mapData.buildArea[i].entColor.replace("#", "0x"), 16); - borderColor = parseInt(mapData.buildArea[i].borderColor.replace("#", "0x"), 16); - Map_QM.util.buildHeight = Math.max(parseInt(mapData.buildArea[i].toHeight), Map_QM.util.buildHeight); - buildH = parseInt(mapData.buildArea[i].toHeight); - let mash = this.Model_QM.MyModelShape(build, hows, mapData.buildArea[i], entColor, borderColor, 30); - mash.receiveShadow = true; - mash.castShadow = false; - mash.userData = { - "type": "build", - "order": this.floorOrder - }; - mash.userData.opacity = mapData.buildArea[i].alphaModle / 100 || 0; - mash.name = "floor"; - this.allObj.add(mash); - } - //店铺 - let sLen = mapData.shopArea.length; - let show = (showE = ""); - let showLeb = ""; - let logo = "", navRecommend = false, shopD = {}, type = "deco"; - let shopData = Map_QM.util.shopData; - for (let i = 0; i < sLen; i++) { - if (Map_QM.util.changeAreaToString(mapData.shopArea[i]) != "") { - 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++) { - let houseNum = iot ? shopData[h].houseNumber : shopData[h].houseNum; - if (shopData[h].buildingOrder == this.buildOrder && shopData[h].floorOrder == this.floorOrder) { - if (houseNum == mapData.shopArea[i].name) { - if(houseNum == "FB130B"){ - console.log(mapData.shopArea[i],shopData[h]); - } - show = shopData[h].shopName || shopData[h].name; - showLeb = houseNum; - showE = shopData[h].shopNameEn || shopData[h].nameEn; - logo = shopData[h].logoPath || shopData[h].logoUrl; - mapShow = shopData[h].mapShow ?? false; - if (shopData[h].navRecommend || shopData[h].isPass) { - navRecommend = shopData[h].navRecommend || shopData[h].isPass; - } else { - navRecommend = false; - } - shopD = shopData[h]; - if (shopData[h].isNewStore) { //新店 - mapData.shopArea[i].type = "new-shop"; - this.addTagLabel(mapData.shopArea[i], { "node": mapData.shopArea[i].shopNav, "floor": this.floorOrder, "build": this.buildOrder }); - } - if ((shopData[h].shopActList && shopData[h].shopActList.length > 0)) { //促销 - mapData.shopArea[i].type = "promotion"; - this.addTagLabel(mapData.shopArea[i], { "node": mapData.shopArea[i].shopNav, "floor": this.floorOrder, "build": this.buildOrder }); - } - if (shopData[h].formatColor) { - entColor = shopData[h].formatColor; - } - if (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, 100); - mahc.node = mapData.shopArea[i].shopNav; - mahc.userData = { - "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", - "entColor": entColor, - "shopNum": mapData.shopArea[i].name, - "shopName": show, - "logo": logo, - "borderColor": borderColor - }; - mahc.userData.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) + parseInt(mapData.shopArea[i].site || 0) + 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 )&&show != "shop") { - showLeb = mapData.shopArea[i].name; - let shopDiv = document.createElement('div'); - shopDiv.style.cssText = css_LR; - shopDiv.innerHTML = Map_QM.util.options.shopStyle == "shopName" ? show : mapData.shopArea[i].name; - shopDiv.dataset.name = show; - shopDiv.dataset.nameEn = showE; - shopDiv.style.visibility = "hidden"; - 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; - 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 = 200; - shopDiv.style.width = "3.125vw"; - let shopLabel = new THREE.CSS2DObject(shopDiv); - shopLabel.userData = userData; - shopLabel.position.set(obj.xaxis >> 0, -1 * obj.yaxis >> 0, Map_QM.util.shopHeight); - 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) { - 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) { - 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) { - 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) { - 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++) { - if (mapData.decos[i].gid && mapData.decos[i].gid == mapData.groupArea[k]._name && Map_QM.util.changeAreaToString(mapData.decos[i]) != "") { - let arr = Map_QM.util.changeAreaToString(mapData.decos[i]); - entColor = parseInt(mapData.decos[i].entColor.replace("#", "0x"), 16); - borderColor = parseInt(mapData.decos[i].borderColor.replace("#", "0x"), 16); - 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, 240); - 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++) { - if ((!mapData.decos[i].gid || mapData.decos[i].gid == "") && Map_QM.util.changeAreaToString(mapData.decos[i]) != "") { - let arr = Map_QM.util.changeAreaToString(mapData.decos[i]); - entColor = parseInt(mapData.decos[i].entColor.replace("#", "0x"), 16); - borderColor = parseInt(mapData.decos[i].borderColor.replace("#", "0x"), 16); - 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, 240); - 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; - 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, - "shopNum": 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 = Map_QM.endIcon.scale.y = Map_QM.endIcon.scale.z = 100; - 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) { - console.log("traverse") - } - - let loader2 = new THREE.GLTFLoader(); - loader2.load(Map_QM.util.beforPath + "static/img/zhong.gltf", function (collada2) { - collada2.scene.traverse(function (child2) { - if (child2.name == "object_1" || child2.name == "object_2" || child2.name == "object_3" || child2.name == "object_4" || child2.name == "object_6" || child2.name == "object_11" || child2.name == "object_21" || child2.name == "object_31" || child2.name == "object_41") { - child2.material = new THREE.MeshBasicMaterial({ color: 0xFF464E, transparent: true }); - } - if (child2.name == "object_5" || child2.name == "object_51") { - child2.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }); - } - }); - 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.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, 100, 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.qiModel.position.set(shopX, -1 * shopY, shopZ); - _this.allObj.add(Map_QM.qiModel) - Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ); - _this.allObj.add(Map_QM.qiIcon) - Map_QM.dirIcon.position.set(shopX, -1 * shopY, 100); - _this.allObj.add(Map_QM.dirIcon) - } else { - new THREE.GLTFLoader().load(Map_QM.util.beforPath + "static/img/qi.gltf", function (collada) { - collada.scene.traverse(function (child) { - if (child.name == "object_1" || child.name == "object_3" || child.name == "object_4" || child.name == "object_31" || child.name == "object_41") { - child.material = new THREE.MeshBasicMaterial({ color: 0xFFAE43, transparent: true }); - } - if (child.name == "object_2" || child.name == "object_21") { - child.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }); - } - }); - collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = 100; - collada.scene.rotateX(Math.PI / 2); - if (shopX != 0 && shopY != 0) { - collada.scene.position.set(shopX, -1 * shopY, parseInt(Map_QM.util.buildHeight) + 5); //x,z,y - } - 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(80, 80, 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); - - let spriteMap2 = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/site.png"); - let spriteMaterial2 = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 - map: spriteMap2, - depthTest: true, - transparent: true, - alphaTest: 0.5 - }); - Map_QM.dirIcon = new MySprite_QM(spriteMaterial2); - Map_QM.dirIcon.scale.set(320, 320, 1); - Map_QM.dirIcon.center = new THREE.Vector2(0.5, 0.5); - Map_QM.dirIcon.position.set(shopX, -1 * shopY, 100); - Map_QM.dirIcon.renderOrder = 500; - Map_QM.dirIcon.visible = false; - Map_QM.dirIcon.userData.type = "start"; - _this.allObj.add(Map_QM.dirIcon); - - }); - } - }, - /** - * 查找线 - * @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 = 0; k < arr.length; k++) { - shape.lineTo(arr[k][2], -1 * arr[k][3]); - } - 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 % 10 == 0) { - let shopDiv = document.createElement('div'); - shopDiv.style.cssText = css_LR; - shopDiv.style.visibility = "hidden"; - shopDiv.textContent = mapData.parkArea[i].parkNum; - let shopLabel = new THREE.CSS2DObject(shopDiv); - 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, borderColor); - this.parkObj.add(mahc); - } - } + 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].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.receiveShadow = Map_QM.util.options.shadow + child.castShadow = Map_QM.util.options.shadow + 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) + obj.rotateY(Map_QM.util.modelArr[i].list[t].rot.y) + obj.rotateZ(Map_QM.util.modelArr[i].list[t].rot.z) + 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].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 + 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.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) + 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++) { + hows_f.push(Map_QM.util.changeAreaToString(mapData.hollowArea[m])) + } + if (floor) { + entColor = parseInt(mapData.floorArea.entColor.replace('#', '0x'), 16) + borderColor = parseInt(mapData.floorArea.borderColor.replace('#', '0x'), 16) + floorH = parseInt(mapData.floorArea.toHeight) + let mash = this.Model_QM.MyModelShape(floor, hows_f, mapData.floorArea, entColor, borderColor, 10) + 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 = parseInt(mapData.buildArea[i].entColor.replace('#', '0x'), 16) + borderColor = parseInt(mapData.buildArea[i].borderColor.replace('#', '0x'), 16) + Map_QM.util.buildHeight = Math.max(parseInt(mapData.buildArea[i].toHeight), Map_QM.util.buildHeight) + buildH = parseInt(mapData.buildArea[i].toHeight) + let mash = this.Model_QM.MyModelShape(build, hows, mapData.buildArea[i], entColor, borderColor, 30) + mash.receiveShadow = true + mash.castShadow = false + mash.userData = { + type: 'build', + order: this.floorOrder + } + mash.userData.opacity = mapData.buildArea[i].alphaModle / 100 || 0 + mash.name = 'floor' + this.allObj.add(mash) + } + //店铺 + let sLen = mapData.shopArea.length + let show = (showE = '') + let showLeb = '' + let logo = '', + navRecommend = false, + shopD = {}, + type = 'deco' + let shopData = Map_QM.util.shopData + for (let i = 0; i < sLen; i++) { + if (Map_QM.util.changeAreaToString(mapData.shopArea[i]) != '') { + 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++) { + let houseNum = iot ? shopData[h].houseNumber : shopData[h].houseNum + if (shopData[h].buildingOrder == this.buildOrder && shopData[h].floorOrder == this.floorOrder) { + if (houseNum == mapData.shopArea[i].name) { + if (houseNum == 'FB130B') { + console.log(mapData.shopArea[i], shopData[h]) + } + show = shopData[h].shopName || shopData[h].name + showLeb = houseNum + showE = shopData[h].shopNameEn || shopData[h].nameEn + logo = shopData[h].logoPath || shopData[h].logoUrl + mapShow = shopData[h].mapShow ?? false + if (shopData[h].navRecommend || shopData[h].isPass) { + navRecommend = shopData[h].navRecommend || shopData[h].isPass + } else { + navRecommend = false + } + shopD = shopData[h] + if (shopData[h].isNewStore) { + //新店 + mapData.shopArea[i].type = 'new-shop' + this.addTagLabel(mapData.shopArea[i], { node: mapData.shopArea[i].shopNav, floor: this.floorOrder, build: this.buildOrder }) + } + if (shopData[h].shopActList && shopData[h].shopActList.length > 0) { + //促销 + mapData.shopArea[i].type = 'promotion' + this.addTagLabel(mapData.shopArea[i], { node: mapData.shopArea[i].shopNav, floor: this.floorOrder, build: this.buildOrder }) + } + if (shopData[h].formatColor) { + entColor = shopData[h].formatColor + } + if (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, 100) + mahc.node = mapData.shopArea[i].shopNav + mahc.userData = { + 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', + entColor: entColor, + shopNum: mapData.shopArea[i].name, + shopName: show, + logo: logo, + borderColor: borderColor + } + mahc.userData.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) + parseInt(mapData.shopArea[i].site || 0) + 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) && show != 'shop') { + showLeb = mapData.shopArea[i].name + let shopDiv = document.createElement('div') + shopDiv.style.cssText = css_LR + shopDiv.innerHTML = Map_QM.util.options.shopStyle == 'shopName' ? show : mapData.shopArea[i].name + shopDiv.dataset.name = show + shopDiv.dataset.nameEn = showE + shopDiv.style.visibility = 'hidden' + 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 + 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 = 200 + shopDiv.style.width = '3.125vw' + let shopLabel = new THREE.CSS2DObject(shopDiv) + shopLabel.userData = userData + shopLabel.position.set(obj.xaxis >> 0, (-1 * obj.yaxis) >> 0, Map_QM.util.shopHeight) + 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) { + 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) { + 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) { + 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) { + 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++) { + if (mapData.decos[i].gid && mapData.decos[i].gid == mapData.groupArea[k]._name && Map_QM.util.changeAreaToString(mapData.decos[i]) != '') { + let arr = Map_QM.util.changeAreaToString(mapData.decos[i]) + entColor = parseInt(mapData.decos[i].entColor.replace('#', '0x'), 16) + borderColor = parseInt(mapData.decos[i].borderColor.replace('#', '0x'), 16) + 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, 240) + 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++) { + if ((!mapData.decos[i].gid || mapData.decos[i].gid == '') && Map_QM.util.changeAreaToString(mapData.decos[i]) != '') { + let arr = Map_QM.util.changeAreaToString(mapData.decos[i]) + entColor = parseInt(mapData.decos[i].entColor.replace('#', '0x'), 16) + borderColor = parseInt(mapData.decos[i].borderColor.replace('#', '0x'), 16) + 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, 240) + 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 + 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, + shopNum: 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 = Map_QM.endIcon.scale.y = Map_QM.endIcon.scale.z = 100 + 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) { + console.log('traverse') + } + + let loader2 = new THREE.GLTFLoader() + loader2.load(Map_QM.util.beforPath + 'static/img/zhong.gltf', function (collada2) { + collada2.scene.traverse(function (child2) { + if ( + child2.name == 'object_1' || + child2.name == 'object_2' || + child2.name == 'object_3' || + child2.name == 'object_4' || + child2.name == 'object_6' || + child2.name == 'object_11' || + child2.name == 'object_21' || + child2.name == 'object_31' || + child2.name == 'object_41' + ) { + child2.material = new THREE.MeshBasicMaterial({ color: 0xff464e, transparent: true }) + } + if (child2.name == 'object_5' || child2.name == 'object_51') { + child2.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }) + } + }) + 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.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, 100, 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.qiModel.position.set(shopX, -1 * shopY, shopZ) + _this.allObj.add(Map_QM.qiModel) + Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ) + _this.allObj.add(Map_QM.qiIcon) + Map_QM.dirIcon.position.set(shopX, -1 * shopY, 100) + _this.allObj.add(Map_QM.dirIcon) + } else { + new THREE.GLTFLoader().load(Map_QM.util.beforPath + 'static/img/qi.gltf', function (collada) { + collada.scene.traverse(function (child) { + if (child.name == 'object_1' || child.name == 'object_3' || child.name == 'object_4' || child.name == 'object_31' || child.name == 'object_41') { + child.material = new THREE.MeshBasicMaterial({ color: 0xffae43, transparent: true }) + } + if (child.name == 'object_2' || child.name == 'object_21') { + child.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }) + } + }) + collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = 100 + collada.scene.rotateX(Math.PI / 2) + if (shopX != 0 && shopY != 0) { + collada.scene.position.set(shopX, -1 * shopY, parseInt(Map_QM.util.buildHeight) + 5) //x,z,y + } + 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(80, 80, 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) + + let spriteMap2 = new THREE.TextureLoader().load(Map_QM.util.beforPath + 'static/img/site.png') + let spriteMaterial2 = new THREE.SpriteMaterial({ + //sizeAttenuation: false 禁止跟随鼠标缩放 + map: spriteMap2, + depthTest: true, + transparent: true, + alphaTest: 0.5 + }) + Map_QM.dirIcon = new MySprite_QM(spriteMaterial2) + Map_QM.dirIcon.scale.set(320, 320, 1) + Map_QM.dirIcon.center = new THREE.Vector2(0.5, 0.5) + Map_QM.dirIcon.position.set(shopX, -1 * shopY, 100) + Map_QM.dirIcon.renderOrder = 500 + Map_QM.dirIcon.visible = false + Map_QM.dirIcon.userData.type = 'start' + _this.allObj.add(Map_QM.dirIcon) + }) + } + }, + /** + * 查找线 + * @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 = 0; k < arr.length; k++) { + shape.lineTo(arr[k][2], -1 * arr[k][3]) + } + 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 % 10 == 0) { + let shopDiv = document.createElement('div') + shopDiv.style.cssText = css_LR + shopDiv.style.visibility = 'hidden' + shopDiv.textContent = mapData.parkArea[i].parkNum + let shopLabel = new THREE.CSS2DObject(shopDiv) + 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, borderColor) + this.parkObj.add(mahc) + } + } } /** -* 渲染3D模型类 -* 传入区域点list -* 镂空点 howllowArr -* 模型对象 options -*/ + * 渲染3D模型类 + * 传入区域点list + * 镂空点 howllowArr + * 模型对象 options + */ MyModel_QM = function () { - this.xaxis = 0; - this.yaxis = 0; - this.node = 0; + this.xaxis = 0 + this.yaxis = 0 + this.node = 0 } MyModel_QM.prototype.MyParkShape = function (shapes, materials, toHeight = 5, borderColor = 0xaaaaaa) { - let scanGeometry = new THREE.ShapeBufferGeometry(shapes, 1); - let material; - for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) { - let color2 = new THREE.Color(borderColor) - if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) { - material = Map_QM.util.lineBasicMaterialArr[k]; - } - } - if (!material) { - material = new THREE.LineBasicMaterial({ - color: borderColor - }); //材质对象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; + let scanGeometry = new THREE.ShapeBufferGeometry(shapes, 1) + let material + for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) { + let color2 = new THREE.Color(borderColor) + if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) { + material = Map_QM.util.lineBasicMaterialArr[k] + } + } + if (!material) { + material = new THREE.LineBasicMaterial({ + color: borderColor + }) //材质对象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; - 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 - }); //材质对象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: 24 - }; - - scanGeometry = new THREE.ExtrudeGeometry(shape, options); - for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) { - let color2 = new THREE.Color(entityColor); - if (Map_QM.util.meshMaterialArr[e].color.equals(color2) && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) { - meshMaterial = Map_QM.util.meshMaterialArr[e]; - } - } - if (!meshMaterial) { - meshMaterial = new THREE.MeshPhongMaterial({ //MeshStandardMaterial MeshPhongMaterial - color: entityColor, - transparent: true, - opacity: alphaModle, - side: THREE.DoubleSide, - depthTest: true - }); - //meshMaterial.color.convertLinearToGamma(0.4); - 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); - if (!Map_QM.util.toMapModel && 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; + 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 + }) //材质对象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: 24 + } + + scanGeometry = new THREE.ExtrudeGeometry(shape, options) + for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) { + let color2 = new THREE.Color(entityColor) + if (Map_QM.util.meshMaterialArr[e].color.equals(color2) && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) { + meshMaterial = Map_QM.util.meshMaterialArr[e] + } + } + if (!meshMaterial) { + meshMaterial = new THREE.MeshPhongMaterial({ + //MeshStandardMaterial MeshPhongMaterial + color: entityColor, + transparent: true, + opacity: alphaModle, + side: THREE.DoubleSide, + depthTest: true + }) + //meshMaterial.color.convertLinearToGamma(0.4); + 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) + if (!Map_QM.util.toMapModel && 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.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.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) + } - 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.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); - for (let j = 0; j < shapes.length; j++) { - const shape = shapes[j]; - const geometry = new THREE.ExtrudeBufferGeometry(shape, { - depth: svgArea.toHeight, - bevelEnabled: false, - curveSegments: 24 - }); - const mesh = new THREE.Mesh(geometry, meshMaterial); - mesh.renderOrder = 50; - mesh.name = svgArea.name || ""; - mesh.position.set(-svgArea.width / 2, -svgArea.height / 2, 0); - group.add(mesh); - } - } - return group; + for (let i = 0; i < paths.length; i++) { + const path = paths[i] + let shapes = path.toShapes(true) + for (let j = 0; j < shapes.length; j++) { + const shape = shapes[j] + const geometry = new THREE.ExtrudeBufferGeometry(shape, { + depth: svgArea.toHeight, + bevelEnabled: false, + curveSegments: 24 + }) + const mesh = new THREE.Mesh(geometry, meshMaterial) + mesh.renderOrder = 50 + mesh.name = svgArea.name || '' + mesh.position.set(-svgArea.width / 2, -svgArea.height / 2, 0) + group.add(mesh) + } + } + return group } /** * 公共设施 */ 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 + } +} - 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; +MySprite_QM.prototype = Object.create(THREE.Sprite.prototype) +MySprite_QM.prototype.constructor = MySprite_QM /** * 渲染公共设施 */ -Facilities_QM = function () { } +Facilities_QM = function () {} Facilities_QM.prototype.renderIcon = function (obj, _this, isShow = true, ele = null) { - if (obj) { - let spriteMaterial; - let url = Map_QM.util.beforPath + "static/img/" + obj.facCode + ".png"; - 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.beforPath + "static/offline" + Map_QM.util.iconUrl[i].filePath - } - } - } - for (let m = 0; m < Map_QM.util.spriteMaterialArr.length; m++) { - if (Map_QM.util.spriteMaterialArr[m].name == obj.facCode) { - spriteMaterial = Map_QM.util.spriteMaterialArr[m]; - } - } - if (!spriteMaterial) { - let spriteMap = new THREE.TextureLoader().load(url); - spriteMaterial = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 - map: spriteMap, - depthTest: true, - transparent: true, - }); - spriteMaterial.name = obj.facCode; - Map_QM.util.spriteMaterialArr.push(spriteMaterial); - } - - let sprite = new MySprite_QM(spriteMaterial, obj); - sprite.scale.set(64, 64, 1); - sprite.imgUrl = url; - sprite.center = new THREE.Vector2(0.5, 0); - sprite.userData = obj; - sprite.userData.type = "icon"; - sprite.userData.use = ele ? "2d" : "all"; - sprite.userData.model = ele; - sprite.userData.src = url; - sprite.userData.title = obj.title; - sprite.position.set(obj.x, -1 * obj.y, Math.max(55, parseInt(obj.site) || 0)); - sprite.renderOrder = 300; - sprite.visible = isShow; - _this.serObj.add(sprite); - if (Map_QM.util.options.iconName) { - let shopDiv = document.createElement('div'); - shopDiv.style.cssText = css_LR; - shopDiv.innerText = obj.title; - shopDiv.dataset.name = obj.title; - shopDiv.dataset.nameEn = Map_QM.util.iconEn[obj.title]; - let shopLabel = new THREE.CSS2DObject(shopDiv); - shopLabel.position.set(obj.x, -1 * obj.y, 30); - _this.iconLabel.add(shopLabel); - } - } + if (obj) { + let spriteMaterial + let url = Map_QM.util.beforPath + 'static/img/' + obj.facCode + '.png' + 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.beforPath + 'static/offline' + Map_QM.util.iconUrl[i].filePath + } + } + } + for (let m = 0; m < Map_QM.util.spriteMaterialArr.length; m++) { + if (Map_QM.util.spriteMaterialArr[m].name == obj.facCode) { + spriteMaterial = Map_QM.util.spriteMaterialArr[m] + } + } + if (!spriteMaterial) { + let spriteMap = new THREE.TextureLoader().load(url) + spriteMaterial = new THREE.SpriteMaterial({ + //sizeAttenuation: false 禁止跟随鼠标缩放 + map: spriteMap, + depthTest: true, + transparent: true + }) + spriteMaterial.name = obj.facCode + Map_QM.util.spriteMaterialArr.push(spriteMaterial) + } + + let sprite = new MySprite_QM(spriteMaterial, obj) + sprite.scale.set(64, 64, 1) + sprite.imgUrl = url + sprite.center = new THREE.Vector2(0.5, 0) + sprite.userData = obj + sprite.userData.type = 'icon' + sprite.userData.use = ele ? '2d' : 'all' + sprite.userData.model = ele + sprite.userData.src = url + sprite.userData.title = obj.title + sprite.position.set(obj.x, -1 * obj.y, Math.max(55, parseInt(obj.site) || 0)) + sprite.renderOrder = 300 + sprite.visible = isShow + _this.serObj.add(sprite) + if (Map_QM.util.options.iconName) { + let shopDiv = document.createElement('div') + shopDiv.style.cssText = css_LR + shopDiv.innerText = obj.title + shopDiv.dataset.name = obj.title + shopDiv.dataset.nameEn = Map_QM.util.iconEn[obj.title] + let shopLabel = new THREE.CSS2DObject(shopDiv) + shopLabel.position.set(obj.x, -1 * obj.y, 30) + _this.iconLabel.add(shopLabel) + } + } } /** * 店铺LOGO地图展示类 */ 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 - }); - 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); - }); - } - } + 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 + }) + 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) + }) + } + } } -MySprite_QM.prototype.constructor = MySprite_QM; +MySprite_QM.prototype.constructor = MySprite_QM -var _selfFindPath; +var _selfFindPath FindPath_QM = function () { - this.pathArr = []; - this.lineDashed; - this.lineDashed_old; - //路线指引箭头皮肤 - this.planeGeometry = new THREE.PlaneGeometry(128, 128); - - 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(); - } - } - } + this.pathArr = [] + this.lineDashed + this.lineDashed_old + //路线指引箭头皮肤 + this.planeGeometry = new THREE.PlaneGeometry(128, 128) + + 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"; + 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 @@ -5819,169 +6283,175 @@ FindPath_QM.prototype.clearPath = function () { * @param {Object} callBack 回调函数 */ FindPath_QM.prototype.onFindPathAnimation = function (pathArray, floorOrder = -1) { - if (pathArray && pathArray.length > 0) { - this.pathArr = []; - for (let j = 0; j < pathArray.length; j++) { - this.pathArr.push(pathArray[j]); - } - this.pathState = "isPlay"; - this._index = 0; - if (floorOrder === -1) { - floorOrder = Map_QM.util.selectFloor; - } - this.drawPath(floorOrder); - } + if (pathArray && pathArray.length > 0) { + this.pathArr = [] + for (let j = 0; j < pathArray.length; j++) { + this.pathArr.push(pathArray[j]) + } + this.pathState = 'isPlay' + this._index = 0 + if (floorOrder === -1) { + floorOrder = Map_QM.util.selectFloor + } + this.drawPath(floorOrder) + } } FindPath_QM.prototype.drawPath = function (floorOrder) { - let linePath = [] - 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]) - } - } - //this.lineDashed.name = 'lineDash' - this.lineDashed_old = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 1, 'rgb(169,181,211)', 'rgb(189, 192, 203)', true) - this.lineDashed_old.renderOrder = 128 - Map_QM.mapArr[Map_QM.util.selectBuild][floorOrder].allObj.add(this.lineDashed_old) - - //////////////////////////////////////////////////////// + let linePath = [] + 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]) + } + } + //this.lineDashed.name = 'lineDash' + this.lineDashed_old = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 1, 'rgb(169,181,211)', 'rgb(189, 192, 203)', true) + this.lineDashed_old.renderOrder = 128 + Map_QM.mapArr[Map_QM.util.selectBuild][floorOrder].allObj.add(this.lineDashed_old) + + //////////////////////////////////////////////////////// } FindPath_QM.prototype.updateClearPath = function () { - 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) { + 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 + } } FindPath_QM.prototype.updateDrawPath = function () { - this.updateClearPath(); - let linePath = [] - linePath.push([Map_QM.guide.position.x, Map_QM.guide.position.y]); - for (let i = this._index; i < this.pathArr.length; i++) { - if (i < this.pathArr.length) { - linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]) - } - } - this.lineDashed = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 2, 'rgb(110, 149, 254)', 'rgb(110,125,254)', false) - this.lineDashed.renderOrder = 130 - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.add(this.lineDashed); + this.updateClearPath() + let linePath = [] + linePath.push([Map_QM.guide.position.x, Map_QM.guide.position.y]) + for (let i = this._index; i < this.pathArr.length; i++) { + if (i < this.pathArr.length) { + linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]) + } + } + this.lineDashed = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 2, 'rgb(110, 149, 254)', 'rgb(110,125,254)', false) + this.lineDashed.renderOrder = 130 + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.add(this.lineDashed) } 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; - } + 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); - 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 = iot ? shop_.houseNumber : shop_.houseNum; - let shops = Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop.floorOrder)].allObj.children; - for (let i = 0; i < shops.length; i++) { - let _shop = shops[i].userData.shopData; - if (_shop && (iot ? _shop.houseNumber : _shop.houseNum) === 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: { "shopNum": 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 }); - _selfFindPath.updateDrawPath() //实时绘制有效路径 await 修是 promise - } - - 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.updateClearPath(); - _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"; - } - } -} + 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) + 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 = iot ? shop_.houseNumber : shop_.houseNum + let shops = Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop.floorOrder)].allObj.children + for (let i = 0; i < shops.length; i++) { + let _shop = shops[i].userData.shopData + if (_shop && (iot ? _shop.houseNumber : _shop.houseNum) === 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: { shopNum: 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 }) + _selfFindPath.updateDrawPath() //实时绘制有效路径 await 修是 promise + } + 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.updateClearPath() + _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' + } + } +} diff --git a/src/composables/useInitMap.js b/src/composables/useInitMap.js index 3d6d308..937f100 100644 --- a/src/composables/useInitMap.js +++ b/src/composables/useInitMap.js @@ -9,6 +9,7 @@ export const useInitMap = function () { Promise.all([getMap(), getFacilityList()]) .then(([{ data }, { data: facs }]) => { + facs = facs.map(fac => ({ ...fac, filePath: fac.navFilePath })) store.SET_MAP_DATA(JSON.parse(data.mapData)) //初始化地图 onReady(store.currentFloor, data, store.shopList, facs, () => {