index.js 35 KB

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