index.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. (() => {
  2. // 初始地图
  3. const initMap = (map) => {
  4. let cacheCanvas
  5. const ctrl = {
  6. map,
  7. async loadImage(args) {
  8. ctrl.remove()
  9. const { file, minWidth, minHeight } = args
  10. args.img = args.img ?
  11. args.img :
  12. await blobImageLoad(file, minWidth, minHeight)
  13. cacheCanvas = loadImageLayer(map, args)
  14. return cacheCanvas
  15. },
  16. remove() {
  17. if (cacheCanvas && cacheCanvas.__layer) {
  18. map.removeLayer(cacheCanvas.__layer)
  19. }
  20. cacheCanvas = null
  21. },
  22. screenToLatlan({ x, y }) {
  23. const real = map.getCoordinateFromPixel([x, y])
  24. // const latlan = ol.proj.transform(real, 'EPSG:3857', 'EPSG:99999', 'EPSG:99999')
  25. var latlan = proj4("EPSG:3857", "EPSG:4490", real);
  26. return latlan
  27. }
  28. }
  29. return ctrl
  30. }
  31. function toArray(quaternion) {
  32. var rot90 = (new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0, 0, 1), THREE.Math.degToRad(-90)) //add 转入时旋转90度
  33. ,
  34. rot90Invert = rot90.clone().inverse() //add 转出时旋回90度
  35. var t1 = quaternion.clone().multiply(rot90Invert);
  36. var e = t1.toArray();
  37. return [e[3], e[0], e[1], e[2]]
  38. }
  39. function getQuaternion(angle) { //angle:0-360 角度
  40. var quaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, 0, THREE.Math.degToRad(-angle)));
  41. return toArray(quaternion)
  42. }
  43. function getSize(imgWidth, scale) { //imgWidth:图片宽度, scale缩放值(x==y)
  44. var level = imgWidth / 1024; //以1024为基准
  45. return 95.54628610610962 * level * scale;
  46. }
  47. const loadImageLayer = (map, args) => {
  48. const {
  49. lon,
  50. lat
  51. } = args
  52. const itude = ol.proj.fromLonLat([lon, lat])
  53. const { image: imageLayer, canvas } = loadImage(map, args, itude)
  54. map.addLayer(imageLayer);
  55. // map.removeLayer(imageLayer);
  56. map.getView().setCenter(
  57. ol.proj.fromLonLat([lon, lat])
  58. );
  59. map.getView().setZoom(19)
  60. return canvas
  61. }
  62. // 经纬度转canvas坐标
  63. const itudeToCanvasPos = (map, extent, itude) => {
  64. //Canvas四至范围不同于当前地图四至范围,计算出南北方向与东西方向的偏移
  65. const mapExtent = map.getView()
  66. .calculateExtent(map.getSize())
  67. //当前底图视图范围的投影坐标
  68. const canvasOrigin = map.getPixelFromCoordinate(
  69. [extent[0], extent[3]]
  70. );
  71. //添加到地图上的canvas图像的左上角
  72. const mapOrigin = map.getPixelFromCoordinate(
  73. [mapExtent[0], mapExtent[3]]
  74. );
  75. const delta = [
  76. mapOrigin[0] - canvasOrigin[0],
  77. mapOrigin[1] - canvasOrigin[1]
  78. ];
  79. const leftTop = map.getPixelFromCoordinate(itude)
  80. return {
  81. x: leftTop[0] + delta[0],
  82. y: leftTop[1] + delta[1]
  83. }
  84. }
  85. // 平移,旋转,放大当前canvas
  86. const transformCanvasCall = (
  87. canvas,
  88. transform,
  89. oper,
  90. center = {
  91. x: 0,
  92. y: 0
  93. }
  94. ) => {
  95. const ctx = canvas.getContext('2d')
  96. const {
  97. translate,
  98. scale,
  99. rotate
  100. } = transform
  101. ctx.translate(center.x, center.y)
  102. translate && ctx.translate(translate.x, translate.y)
  103. rotate && ctx.rotate(rotate * (Math.PI / 180))
  104. scale && ctx.scale(scale[0], scale[1])
  105. oper && oper()
  106. // scale && ctx.scale(1 / scale, 1 / scale)
  107. // rotate && ctx.rotate(-rotate * (Math.PI / 180))
  108. // translate && ctx.translate(-translate.x, -translate.y)
  109. ctx.translate(-center.x, -center.y)
  110. }
  111. const genImgCanvasItudeToReal = (map, canvas, extent) =>
  112. (itude) => {
  113. return genImgCanvasPosToReal(map, canvas)(
  114. itudeToCanvasPos(map, extent, itude)
  115. )
  116. }
  117. const genImgCanvasPosToReal = (map, canvas) =>
  118. (pos) => {
  119. const $real = map.getViewport()
  120. const offsetWidth = (canvas.width - $real.offsetWidth) / 2
  121. const offsetHeight = (canvas.height - $real.offsetHeight) / 2
  122. return {
  123. x: pos.x - offsetWidth,
  124. y: pos.y - offsetHeight
  125. }
  126. }
  127. const genImgCanvasTransfrom = (canvas, arrayImgs, scale, initPos) =>
  128. (transform) => {
  129. console.log(scale)
  130. const ctx = canvas.getContext('2d');
  131. const dscale = transform.scale || [1, 1]
  132. const resize = 1 / (scale * 10)
  133. const doScale = [
  134. resize * dscale[0],
  135. resize * dscale[1]
  136. ]
  137. const imgData = { width: 0, height: 0 }
  138. arrayImgs.forEach(imgs => {
  139. let height = 0
  140. imgs.forEach(([img]) => height += img.height)
  141. imgData.width += imgs[0][0].width
  142. if (imgData.height < height) {
  143. imgData.height = height
  144. }
  145. })
  146. initPos.x -= imgData.width / 2
  147. initPos.y -= imgData.height / 2
  148. // , translate: { x: -(imgData.width / 2) * doScale[0], y: -(imgData.height / 2) * doScale[1] }
  149. ctx.fillStyle = 'rgba(0,0,0,0.1)'
  150. ctx.fillRect(0, 0, canvas.width, canvas.height)
  151. transformCanvasCall(
  152. canvas, {...transform, scale: doScale },
  153. () => {
  154. transform.draw && transform.draw(ctx)
  155. let width = 0
  156. arrayImgs.forEach(imgs => {
  157. let height = 0
  158. imgs.forEach(([img]) => {
  159. ctx.drawImage(img, width, height)
  160. height += img.height
  161. })
  162. width += imgs[0][0].width
  163. })
  164. },
  165. transform.center
  166. )
  167. const move = {
  168. x: transform.translate.x - initPos.x,
  169. y: transform.translate.y - initPos.y,
  170. }
  171. const start = {
  172. x: initPos.x + move.x,
  173. y: initPos.y + move.y,
  174. }
  175. const end = {
  176. x: start.x + imgData.width * doScale[0],
  177. y: start.y + imgData.height * doScale[1],
  178. }
  179. canvas.position = [
  180. start,
  181. end,
  182. Math.abs(start.x - end.x) / resize,
  183. Math.abs(start.y - end.y) / resize
  184. ]
  185. canvas.resize = resize
  186. canvas.imgData = imgData
  187. canvas.imgBox = [
  188. canvas.posToReal(start),
  189. canvas.posToReal(end),
  190. Math.abs(start.x - end.x),
  191. Math.abs(start.y - end.y)
  192. ]
  193. }
  194. // 加载url
  195. const canvas = document.createElement('canvas')
  196. const loadImage = (map, args, itude) => {
  197. const imageCanvas = new ol.source.ImageCanvas({
  198. canvasFunction(extent, scale, _2, size) {
  199. const pos = itudeToCanvasPos(map, extent, itude)
  200. const imgData = { width: 0, height: 0 }
  201. args.img.forEach(imgs => {
  202. let height = 0
  203. imgs.forEach(([img]) => height += img.height)
  204. imgData.width += imgs[0][0].width
  205. if (imgData.height < height) {
  206. imgData.height = height
  207. }
  208. })
  209. console.log(scale, size)
  210. // pos.x -= imgData.width / 2 * scale
  211. // pos.y -= imgData.height / 2 * scale
  212. canvas.width = size[0];
  213. canvas.height = size[1]
  214. canvas.posToReal = genImgCanvasPosToReal(map, canvas);
  215. canvas.transform = genImgCanvasTransfrom(canvas, args.img, scale, pos, imageCanvas);
  216. canvas.itudeToReal = genImgCanvasItudeToReal(map, canvas, extent)
  217. canvas.transform({
  218. ...args,
  219. translate: {
  220. x: (args.translate ? args.translate.x : 0) + pos.x,
  221. y: (args.translate ? args.translate.y : 0) + pos.y
  222. }
  223. })
  224. return canvas;
  225. }
  226. })
  227. const image = new ol.layer.Image({ source: imageCanvas })
  228. canvas.imageLayer = imageCanvas
  229. canvas.__layer = image
  230. return {
  231. image,
  232. canvas
  233. }
  234. }
  235. // 返回本地url
  236. const blobImageLoad = (arrayImages, minWidth, minHeight) => {
  237. const analysis = (blob) => new Promise((resolve, reject) => {
  238. const url = typeof blob !== 'string' ?
  239. window.URL.createObjectURL(blob) :
  240. blob
  241. const img = new Image()
  242. img.onload = () => {
  243. if (img.width < minWidth || img.height < minHeight) {
  244. reject('图片宽高需要大于512')
  245. } else {
  246. resolve([img, url, blob])
  247. }
  248. }
  249. img.src = url
  250. })
  251. let arrasPromises = []
  252. for (let images of arrayImages) {
  253. let analys = []
  254. for (let bolb of images) {
  255. analys.push(analysis(bolb))
  256. }
  257. arrasPromises.push(
  258. Promise.all(analys)
  259. )
  260. }
  261. return Promise.all(arrasPromises)
  262. }
  263. // 获取逆转矩阵
  264. const getCanvasInverImatrix = $canvas => {
  265. const ctx = $canvas.getContext('2d')
  266. const transform = ctx.getTransform()
  267. return transform.invertSelf();
  268. }
  269. // canvas坐标转屏幕坐标
  270. const getCanvasToScreenPos = ($canvas, { x, y }) => {
  271. const {
  272. a,
  273. b,
  274. c,
  275. d,
  276. e,
  277. f
  278. } = getCanvasInverImatrix($canvas)
  279. const screenX = (c * y - d * x + d * e - c * f) / (b * c - a * d)
  280. const screenY = (y - screenX * b - f) / d
  281. return {
  282. x: Math.round(screenX),
  283. y: Math.round(screenY),
  284. }
  285. }
  286. // 屏幕坐标转canvas坐标
  287. const getScreenToCanvasPos = ($canvas, { x, y }) => {
  288. const {
  289. a,
  290. b,
  291. c,
  292. d,
  293. e,
  294. f
  295. } = getCanvasInverImatrix($canvas)
  296. return {
  297. x: Math.round(x * a + y * c + e),
  298. y: Math.round(x * b + y * d + f)
  299. };
  300. }
  301. const sceneName = window.location.pathname.split('/')[2]
  302. const isDev = !sceneName || sceneName === 'addDataSet.html'
  303. const sceneCode = isDev ? 't-l03EZNS' : window.location.pathname.split('/')[2]
  304. const root = isDev ? `https://testlaser.4dkankan.com` : ''
  305. // const root = 'http://192.168.0.135:9294'
  306. const request = {
  307. uploadFiles(files) {
  308. const fromData = new FormData()
  309. files.forEach(({ dir, file }) => {
  310. fromData.append(dir, file)
  311. })
  312. return axios({
  313. headers: { 'Content-Type': 'multipart/form-data' },
  314. method: 'POST',
  315. data: fromData,
  316. url: `${root}/indoor/${sceneCode}/api/mapSmall/upload`
  317. })
  318. },
  319. getDetail() {
  320. return axios.post(`${root}/indoor/${sceneCode}/api/mapSmall/detail`)
  321. },
  322. updateCoord(data) {
  323. return axios.post(`${root}/indoor/${sceneCode}/api/update/coord`, { param: data })
  324. },
  325. updateTiled(data) {
  326. return axios.put(`${root}/indoor/${sceneCode}/api/tiled_maps`, {
  327. location: data.location,
  328. map_size_m: data.map_size_m,
  329. orientation: data.orientation,
  330. })
  331. },
  332. getSceneInfo() {
  333. return axios.get(`${root}/indoor/${sceneCode}/api/datasets`)
  334. }
  335. }
  336. const analysisFiles = (files) => {
  337. const imagesArray = []
  338. const formatError = () => {
  339. alert('目录不规范 请上传 z/x/y.png 格式目录,且在最底级目录放置图片文件')
  340. }
  341. let imagesXYZ = {}
  342. for (let dir in files) {
  343. let file = files[dir]
  344. let locals = dir.split(/[\\|//]/)
  345. if (locals.length < 3) return formatError()
  346. let current = imagesXYZ
  347. for (let i = 0; i < locals.length; i++) {
  348. let dir = locals[i]
  349. if (i !== locals.length - 1) {
  350. if (!current[dir]) {
  351. current[dir] = i === locals.length - 2 ? [] : {}
  352. }
  353. current = current[dir]
  354. if (i === locals.length - 3) {
  355. current.key = 'z'
  356. }
  357. }
  358. if (i === locals.length - 1 && Array.isArray(current)) {
  359. current.push(file)
  360. }
  361. }
  362. }
  363. (function analysis(updateXYZ) {
  364. if (updateXYZ.key === 'z') {
  365. imagesXYZ = updateXYZ
  366. return;
  367. }
  368. const names = Object.keys(updateXYZ).sort((a, b) => b - a)
  369. names.forEach(key => {
  370. if (key !== names[0]) {
  371. delete updateXYZ[key]
  372. }
  373. })
  374. analysis(updateXYZ[names[0]])
  375. })(imagesXYZ);
  376. if (!(imagesXYZ && imagesXYZ.key === 'z' && !Array.isArray(imagesXYZ))) {
  377. return formatError()
  378. }
  379. for (let key in imagesXYZ) {
  380. if (!Array.isArray(imagesXYZ[key]) && key !== 'key') {
  381. return formatError()
  382. }
  383. }
  384. delete imagesXYZ.key
  385. const getNameNum = (str) => {
  386. let rg = str.match(/[\/\\]([^\/\\]*)?\.[^\/\\]*$/)
  387. return weight = rg ? parseInt(rg[1]) : 999
  388. }
  389. Object.keys(imagesXYZ).sort((a, b) => a - b).forEach(key => {
  390. imagesArray.push(
  391. imagesXYZ[key].sort((a, b) => {
  392. let wa = typeof a === 'string' ?
  393. getNameNum(a) :
  394. parseInt(a.name)
  395. let wb = typeof b === 'string' ?
  396. getNameNum(b) :
  397. parseInt(b.name)
  398. return wa - wb
  399. })
  400. )
  401. })
  402. return imagesArray
  403. }
  404. // 目录:<input type="file" @change="imageChange" directory webkitdirectory multiple>
  405. Vue.component('imageTranform', {
  406. props: ['mapOl'],
  407. name: 'imageTranform',
  408. template: `
  409. <div class="transform-layer" @mousemove.stop.prevent="moveHandle" @mouseup="upMove">
  410. <div class="upload-layer" v-show="false">
  411. 单文件:<input type="file" @change="imageChange" ref="updom">
  412. </div>
  413. <div class="ctrls" :style="boxStyle" @mousedown.stop.prevent="startMove($event, 'move')"></div>
  414. <div class="cctrls" v-if="box.tl">
  415. <span class="tl" :style="{left: box.tl.x + 'px', top: box.tl.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tl')"></span>
  416. <span class="tr" :style="{left: box.tr.x + 'px', top: box.tr.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tr')"></span>
  417. <!--
  418. <span class="tc" :style="{left: box.tc.x + 'px', top: box.tc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tc')"></span>
  419. <span class="rc" :style="{left: box.rc.x + 'px', top: box.rc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'rc')"></span>
  420. <span class="bc" :style="{left: box.bc.x + 'px', top: box.bc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'bc')"></span>
  421. <span class="lc" :style="{left: box.lc.x + 'px', top: box.lc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'lc')"></span>
  422. -->
  423. <span class="br" :style="{left: box.br.x + 'px', top: box.br.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'br')"></span>
  424. <span class="bl" :style="{left: box.bl.x + 'px', top: box.bl.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'bl')"></span>
  425. <span class="cc" :style="{left: box.cc.x + 'px', top: box.cc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'rotate')"></span>
  426. </div>
  427. <div class="box-info" v-if="boxPos.tl">
  428. <div v-for="(item, key) in boxPos" :key="key">
  429. <span>{{key}}</span>
  430. <span>{{item}}</span>
  431. </div>
  432. </div>
  433. </div>
  434. `,
  435. data() {
  436. return {
  437. isHover: false,
  438. box: {},
  439. left: 0,
  440. top: 0
  441. }
  442. },
  443. methods: {
  444. imageChange(e) {
  445. const files = e.target.files;
  446. if (files && files[0]) {
  447. const file = files[0];
  448. // onload 里面不能用this
  449. let img = new Image();
  450. img.src = window.URL.createObjectURL(file);
  451. img.onload = async() => {
  452. if (img.width % 256 == 0 && img.height % 256 == 0) {
  453. let imagesArray = []
  454. if (e.target.files.length > 1) {
  455. const files = {}
  456. for (let file of e.target.files) {
  457. files[file.webkitRelativePath] = file
  458. }
  459. imagesArray = analysisFiles(files)
  460. } else {
  461. imagesArray = [
  462. [e.target.files[0]]
  463. ]
  464. }
  465. if (this.imgCanvas) {
  466. ctx = this.imgCanvas.getContext('2d')
  467. ctx.clearRect(-10000, -10000, 10000, 10000)
  468. this.imgCanvas.imageLayer.refresh()
  469. }
  470. await this.drawCanvas(imagesArray, [], {
  471. lat: this.lat,
  472. lon: this.lon
  473. })
  474. } else {
  475. alert('图片宽高需为256的倍数')
  476. }
  477. };
  478. }
  479. },
  480. async drawCanvas(imagesArray, transfroms, { lat, lon } = {}) {
  481. try {
  482. this.transfroms = transfroms || []
  483. this.args = {
  484. draw: (ctx) => {
  485. this.drawIng = false
  486. this.transfroms.forEach(transform => {
  487. transform.forEach(({ translate, scale, rotate, center }) => {
  488. // 设置绘制颜色
  489. center && ctx.translate(center.x, center.y)
  490. translate && ctx.translate(translate.x, translate.y)
  491. rotate && ctx.rotate(rotate * (Math.PI / 180))
  492. scale && ctx.scale(scale[0], scale[1])
  493. center && ctx.translate(-center.x, -center.y)
  494. // if (center) {
  495. // ctx.fillStyle = "geend";
  496. // // 绘制成矩形
  497. // ctx.fillRect(center.x, center.y, 100, 100);
  498. // }
  499. })
  500. })
  501. setTimeout(() => {
  502. this.updateBox(this.imgCanvas.imgBox)
  503. })
  504. },
  505. file: imagesArray,
  506. lon: lon || 113.59963069739054,
  507. lat: lat || 22.364821730960752,
  508. translate: { x: 0, y: 0 },
  509. scale: [1, 1],
  510. direction: 0
  511. }
  512. this.imgCanvas = await this.map.loadImage(this.args)
  513. } catch (e) {
  514. console.error(e)
  515. alert(e)
  516. }
  517. },
  518. updateBox() {
  519. const calcPos = pos => getCanvasToScreenPos(this.imgCanvas, pos)
  520. this.box = {
  521. tl: this.imgCanvas.posToReal(calcPos({ x: 0, y: 0 })),
  522. tc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width / 2, y: 0 })),
  523. tr: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width, y: 0 })),
  524. rc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width, y: this.imgCanvas.imgData.height / 2 })),
  525. lc: this.imgCanvas.posToReal(calcPos({ x: 0, y: this.imgCanvas.imgData.height / 2 })),
  526. br: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width, y: this.imgCanvas.imgData.height })),
  527. bl: this.imgCanvas.posToReal(calcPos({ x: 0, y: this.imgCanvas.imgData.height })),
  528. bc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width / 2, y: this.imgCanvas.imgData.height })),
  529. cc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width / 2, y: this.imgCanvas.imgData.height / 2 })),
  530. }
  531. let maxX = this.box.tl.x
  532. let minX = this.box.tl.x
  533. let maxY = this.box.tl.y
  534. let minY = this.box.tl.y
  535. Object.values(this.box).forEach(({ x, y }) => {
  536. x > maxX && (maxX = x)
  537. y > maxY && (maxY = y)
  538. x < minX && (minX = x)
  539. y < minY && (minY = y)
  540. })
  541. this.box.width = Math.abs(maxX - minX)
  542. this.box.height = Math.abs(maxY - minY)
  543. },
  544. mapStartHandle() {
  545. this.mapDown = true
  546. },
  547. moveHandle(e) {
  548. if (!this.imgCanvas || !this.imgCanvas.imgBox) {
  549. return;
  550. }
  551. if (this.moveing && this.oper) {
  552. if (!this.time && !this.drawIng) {
  553. this.move(e)
  554. this.time = null
  555. }
  556. } else {
  557. this.mapDown && this.imgCanvas.imageLayer.refresh()
  558. // const [start, end] = this.box
  559. // this.isHover = e.clientX > start.x && e.clientX < end.x &&
  560. // e.clientY > start.y && e.clientY < end.y
  561. }
  562. },
  563. startMove(ev, oper, dir) {
  564. this.startTransform = {
  565. ...this.args
  566. }
  567. this.transfroms.push([])
  568. this.moveing = true
  569. this.oper = oper
  570. this.dir = dir
  571. this.startMovePos = {
  572. x: ev.clientX,
  573. y: ev.clientY
  574. }
  575. },
  576. move(ev) {
  577. if (!this.moveing || this.drawIng) return;
  578. const transfrom = this.transfroms[this.transfroms.length - 1]
  579. const start = getScreenToCanvasPos(
  580. this.imgCanvas,
  581. this.startMovePos
  582. )
  583. const end = getScreenToCanvasPos(
  584. this.imgCanvas, { x: ev.clientX, y: ev.clientY }
  585. )
  586. const move = {
  587. x: end.x - start.x,
  588. y: end.y - start.y
  589. }
  590. if (this.oper === 'move') {
  591. transfrom.length = 0
  592. transfrom.push({ translate: move })
  593. } else if (this.oper === 'scale') {
  594. const doScale = (transfrom && transfrom[0] && transfrom[0].scale) || [1, 1]
  595. move.x = move.x * doScale[0]
  596. move.y = move.y * doScale[1]
  597. const width = this.imgCanvas.position[2]
  598. const height = this.imgCanvas.position[3]
  599. let xScale, yScale
  600. switch (this.dir) {
  601. case 'tl':
  602. xScale = (width - move.x) / width
  603. yScale = (height - move.y) / height
  604. if (xScale < yScale) {
  605. yScale = xScale
  606. } else {
  607. xScale = yScale
  608. }
  609. if (xScale > 0 && yScale > 0) {
  610. transfrom.length = 0
  611. transfrom.push({
  612. scale: [xScale, yScale],
  613. center: { x: this.imgCanvas.position[2], y: this.imgCanvas.position[3] }
  614. })
  615. }
  616. break;
  617. case 'tc':
  618. yScale = (height - move.y) / height
  619. if (yScale > 0) {
  620. transfrom.length = 0
  621. transfrom.push({
  622. scale: [1, yScale],
  623. center: { x: 0, y: this.imgCanvas.position[3] }
  624. })
  625. }
  626. break;
  627. case 'tr':
  628. xScale = (width + move.x) / width
  629. yScale = (height - move.y) / height
  630. if (xScale > yScale) {
  631. yScale = xScale
  632. } else {
  633. xScale = yScale
  634. }
  635. if (xScale > 0 && yScale > 0) {
  636. transfrom.length = 0
  637. transfrom.push({
  638. scale: [xScale, yScale],
  639. center: { x: 0, y: this.imgCanvas.position[3] }
  640. })
  641. }
  642. break;
  643. case 'rc':
  644. xScale = (width + move.x) / width
  645. if (xScale > 0) {
  646. transfrom.length = 0
  647. transfrom.push({
  648. scale: [xScale, 1],
  649. center: { x: 0, y: this.imgCanvas.position[3] }
  650. })
  651. }
  652. break;
  653. case 'lc':
  654. xScale = (width - move.x) / width
  655. if (xScale > 0) {
  656. transfrom.length = 0
  657. transfrom.push({
  658. scale: [xScale, 1],
  659. center: { x: this.imgCanvas.position[2], y: this.imgCanvas.position[3] }
  660. })
  661. }
  662. break;
  663. case 'br':
  664. xScale = (width + move.x) / width
  665. yScale = (height + move.y) / height
  666. if (xScale < yScale) {
  667. yScale = xScale
  668. } else {
  669. xScale = yScale
  670. }
  671. if (xScale > 0 && yScale > 0) {
  672. transfrom.length = 0
  673. transfrom.push({
  674. scale: [xScale, yScale],
  675. center: { x: 0, y: 0 }
  676. })
  677. }
  678. break;
  679. case 'bl':
  680. xScale = (width - move.x) / width
  681. yScale = (height + move.y) / height
  682. if (xScale < yScale) {
  683. yScale = xScale
  684. } else {
  685. xScale = yScale
  686. }
  687. if (xScale > 0 && yScale > 0) {
  688. transfrom.length = 0
  689. transfrom.push({
  690. scale: [xScale, yScale],
  691. center: { x: this.imgCanvas.position[2], y: 0 }
  692. })
  693. }
  694. break;
  695. case 'bc':
  696. yScale = (height + move.y) / height
  697. if (yScale > 0) {
  698. transfrom.length = 0
  699. transfrom.push({
  700. scale: [1, yScale],
  701. center: { x: 0, y: 0 }
  702. })
  703. }
  704. break;
  705. }
  706. } else if (this.oper === 'rotate') {
  707. let move = ev.clientX - this.startMovePos.x
  708. let height = this.imgCanvas.position[3]
  709. let width = this.imgCanvas.position[2]
  710. let center = { x: width / 2, y: height / 2 }
  711. // let zrotate = transfrom.
  712. transfrom.length = 0
  713. transfrom.push({
  714. rotate: move / 3,
  715. center: center
  716. })
  717. }
  718. // this.startMovePos = {
  719. // x: ev.clientX,
  720. // y: ev.clientY
  721. // }
  722. this.drawIng = true
  723. this.imgCanvas.imageLayer.refresh()
  724. },
  725. upMove() {
  726. this.moveing = false
  727. this.mapDown = false
  728. this.oper = null
  729. this.dir = null
  730. this.startMovePos = null
  731. },
  732. uploadTiled() {
  733. return request.updateTiled(this.boxPos)
  734. },
  735. uploadData() {
  736. if (!this.args) {
  737. return Promise.resolve(true)
  738. }
  739. const promises = []
  740. const files = []
  741. for (let i = 0; i < this.args.img.length; i++) {
  742. const images = this.args.img[i]
  743. for (let j = 0; j < images.length; j++) {
  744. const file = images[j][2]
  745. if (typeof file !== 'string') {
  746. const suffix = file.type.substr(file.type.indexOf('/') + 1)
  747. files.push({ dir: `${i}/${j}.${suffix}`, file })
  748. }
  749. }
  750. }
  751. if (files.length) {
  752. if (files.length === 1) {
  753. const file = files[0]
  754. files.length = 0
  755. files.push({
  756. ...file,
  757. dir: file.file.name
  758. })
  759. }
  760. promises.push(
  761. request.uploadFiles(files)
  762. )
  763. }
  764. promises.push(
  765. request.updateCoord({
  766. ...this.boxPos,
  767. transfroms: this.transfroms,
  768. })
  769. )
  770. return Promise.all(promises)
  771. },
  772. getInfo() {
  773. return {
  774. pos: this.boxPos,
  775. img: this.args.img
  776. }
  777. },
  778. readyUpload() {
  779. this.$refs.updom.click()
  780. },
  781. },
  782. computed: {
  783. boxStyle() {
  784. if (this.box && Object.keys(this.box).length) {
  785. const box = this.box
  786. return {
  787. width: box.width + 20 + 'px',
  788. height: box.height + 20 + 'px',
  789. left: box.cc.x + 'px',
  790. top: box.cc.y + 'px'
  791. }
  792. } else {
  793. return {}
  794. }
  795. },
  796. boxPos() {
  797. if (this.box && Object.keys(this.box).length) {
  798. const ret = {}
  799. for (let key in this.box) {
  800. if (key !== 'width' && key !== 'height') {
  801. ret[key] = this.map.screenToLatlan(this.box[key])
  802. }
  803. }
  804. let rotate = 0
  805. let scale = { x: 1, y: 1 }
  806. this.transfroms.forEach(items => {
  807. items.forEach(item => {
  808. if (item.rotate) {
  809. rotate = Number((rotate + Number(item.rotate)).toFixed(2))
  810. }
  811. if (item.scale) {
  812. scale.x *= item.scale[0]
  813. scale.y *= item.scale[1]
  814. }
  815. })
  816. })
  817. ret.rotate = rotate
  818. ret.scale = scale
  819. let ctx = this.imgCanvas.getContext('2d')
  820. let key = ['a', 'b', 'c', 'd', 'e', 'f']
  821. let imatrix = ctx.getTransform()
  822. ret.imatrix = {}
  823. key.forEach(k => ret.imatrix[k] = imatrix[k])
  824. // 缩放,坐标,角度
  825. ret.map_size_m = getSize(this.imgCanvas.position[2], scale.x),
  826. ret.location = ret.cc,
  827. ret.orientation = getQuaternion(rotate)
  828. return ret
  829. } else {
  830. return {}
  831. }
  832. },
  833. },
  834. destroyed() {
  835. this.map.remove()
  836. },
  837. mounted() {
  838. Promise.all([
  839. request.getDetail(),
  840. request.getSceneInfo()
  841. ]).then(async([res1, res2]) => {
  842. const {
  843. path,
  844. position
  845. } = res1.data.data
  846. const { location } = res2.data[0]
  847. if (path && path.length > 0) {
  848. const files = {}
  849. path.forEach(path => (files[path] = root + path))
  850. await this.drawCanvas(
  851. analysisFiles(files),
  852. position ? position.transfroms : [], {
  853. lat: location[1],
  854. lon: location[0],
  855. }
  856. )
  857. }
  858. this.lat = location[1]
  859. this.lon = location[0]
  860. })
  861. document.documentElement.addEventListener('mousemove', ev => {
  862. ev.stopPropagation()
  863. ev.preventDefault()
  864. this.moveHandle.bind(this)(ev)
  865. // this.move.bind(this)(ev)
  866. })
  867. document.documentElement.addEventListener('mousedown', ev => {
  868. this.mapStartHandle.bind(this)(ev)
  869. })
  870. document.documentElement.addEventListener('mouseup', ev => {
  871. ev.stopPropagation()
  872. ev.preventDefault()
  873. this.upMove.bind(this)()
  874. })
  875. this.$nextTick(() => {
  876. this.map = initMap(this.mapOl)
  877. })
  878. },
  879. })
  880. })();