|
@@ -0,0 +1,907 @@
|
|
|
+(() => {
|
|
|
+ // 初始地图
|
|
|
+ const initMap = (map) => {
|
|
|
+ return {
|
|
|
+ map,
|
|
|
+ async loadImage(args) {
|
|
|
+ const { file, minWidth, minHeight } = args
|
|
|
+ args.img = args.img ?
|
|
|
+ args.img :
|
|
|
+ await blobImageLoad(file, minWidth, minHeight)
|
|
|
+
|
|
|
+ return loadImageLayer(map, args)
|
|
|
+ },
|
|
|
+ screenToLatlan({ x, y }) {
|
|
|
+ const real = map.getCoordinateFromPixel([x, y])
|
|
|
+ const latlan = ol.proj.transform(real, 'EPSG:4326', 'EPSG:99999')
|
|
|
+ return latlan
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const loadImageLayer = (map, args) => {
|
|
|
+ const {
|
|
|
+ lon,
|
|
|
+ lat
|
|
|
+ } = args
|
|
|
+ const itude = ol.proj.fromLonLat([lon, lat])
|
|
|
+ const { image: imageLayer, canvas } = loadImage(map, args, itude)
|
|
|
+
|
|
|
+ map.addLayer(imageLayer);
|
|
|
+ map.getView().setCenter(
|
|
|
+ ol.proj.fromLonLat([lon, lat])
|
|
|
+ );
|
|
|
+ map.getView().setZoom(19)
|
|
|
+
|
|
|
+ return canvas
|
|
|
+ }
|
|
|
+
|
|
|
+ // 经纬度转canvas坐标
|
|
|
+ const itudeToCanvasPos = (map, extent, itude) => {
|
|
|
+ //Canvas四至范围不同于当前地图四至范围,计算出南北方向与东西方向的偏移
|
|
|
+ const mapExtent = map.getView()
|
|
|
+ .calculateExtent(map.getSize())
|
|
|
+
|
|
|
+ //当前底图视图范围的投影坐标
|
|
|
+ const canvasOrigin = map.getPixelFromCoordinate(
|
|
|
+ [extent[0], extent[3]]
|
|
|
+ );
|
|
|
+
|
|
|
+ //添加到地图上的canvas图像的左上角
|
|
|
+ const mapOrigin = map.getPixelFromCoordinate(
|
|
|
+ [mapExtent[0], mapExtent[3]]
|
|
|
+ );
|
|
|
+
|
|
|
+ const delta = [
|
|
|
+ mapOrigin[0] - canvasOrigin[0],
|
|
|
+ mapOrigin[1] - canvasOrigin[1]
|
|
|
+ ];
|
|
|
+
|
|
|
+ const leftTop = map.getPixelFromCoordinate(itude)
|
|
|
+
|
|
|
+ return {
|
|
|
+ x: leftTop[0] + delta[0],
|
|
|
+ y: leftTop[1] + delta[1]
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 平移,旋转,放大当前canvas
|
|
|
+ const transformCanvasCall = (
|
|
|
+ canvas,
|
|
|
+ transform,
|
|
|
+ oper,
|
|
|
+ center = {
|
|
|
+ x: 0,
|
|
|
+ y: 0
|
|
|
+ }
|
|
|
+ ) => {
|
|
|
+ const ctx = canvas.getContext('2d')
|
|
|
+ const {
|
|
|
+ translate,
|
|
|
+ scale,
|
|
|
+ rotate
|
|
|
+ } = transform
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ ctx.translate(center.x, center.y)
|
|
|
+ translate && ctx.translate(translate.x, translate.y)
|
|
|
+ rotate && ctx.rotate(rotate * (Math.PI / 180))
|
|
|
+ scale && ctx.scale(scale[0], scale[1])
|
|
|
+ oper && oper()
|
|
|
+ // scale && ctx.scale(1 / scale, 1 / scale)
|
|
|
+ // rotate && ctx.rotate(-rotate * (Math.PI / 180))
|
|
|
+ // translate && ctx.translate(-translate.x, -translate.y)
|
|
|
+ ctx.translate(-center.x, -center.y)
|
|
|
+ }
|
|
|
+
|
|
|
+ const genImgCanvasItudeToReal = (map, canvas, extent) =>
|
|
|
+ (itude) => {
|
|
|
+ return genImgCanvasPosToReal(map, canvas)(
|
|
|
+ itudeToCanvasPos(map, extent, itude)
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ const genImgCanvasPosToReal = (map, canvas) =>
|
|
|
+ (pos) => {
|
|
|
+ const $real = map.getViewport()
|
|
|
+ const offsetWidth = (canvas.width - $real.offsetWidth) / 2
|
|
|
+ const offsetHeight = (canvas.height - $real.offsetHeight) / 2
|
|
|
+
|
|
|
+ return {
|
|
|
+ x: pos.x - offsetWidth,
|
|
|
+ y: pos.y - offsetHeight
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const genImgCanvasTransfrom = (canvas, arrayImgs, scale, initPos) =>
|
|
|
+ (transform) => {
|
|
|
+ console.log(scale)
|
|
|
+ const ctx = canvas.getContext('2d');
|
|
|
+ const dscale = transform.scale || [1, 1]
|
|
|
+ const resize = 1 / (scale * 10)
|
|
|
+ const doScale = [
|
|
|
+ resize * dscale[0],
|
|
|
+ resize * dscale[1]
|
|
|
+ ]
|
|
|
+ const imgData = { width: 0, height: 0 }
|
|
|
+
|
|
|
+ arrayImgs.forEach(imgs => {
|
|
|
+ let height = 0
|
|
|
+ imgs.forEach(([img]) => height += img.height)
|
|
|
+ imgData.width += imgs[0][0].width
|
|
|
+ if (imgData.height < height) {
|
|
|
+ imgData.height = height
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ initPos.x -= imgData.width / 2
|
|
|
+ initPos.y -= imgData.height / 2
|
|
|
+
|
|
|
+ // , translate: { x: -(imgData.width / 2) * doScale[0], y: -(imgData.height / 2) * doScale[1] }
|
|
|
+ ctx.fillStyle = 'rgba(0,0,0,0.1)'
|
|
|
+ ctx.fillRect(0, 0, canvas.width, canvas.height)
|
|
|
+ transformCanvasCall(
|
|
|
+ canvas, { ...transform, scale: doScale },
|
|
|
+ () => {
|
|
|
+ transform.draw && transform.draw(ctx)
|
|
|
+ let width = 0
|
|
|
+ arrayImgs.forEach(imgs => {
|
|
|
+ let height = 0
|
|
|
+ imgs.forEach(([img]) => {
|
|
|
+ ctx.drawImage(img, width, height)
|
|
|
+ height += img.height
|
|
|
+ })
|
|
|
+ width += imgs[0][0].width
|
|
|
+ })
|
|
|
+ },
|
|
|
+ transform.center
|
|
|
+ )
|
|
|
+
|
|
|
+ const move = {
|
|
|
+ x: transform.translate.x - initPos.x,
|
|
|
+ y: transform.translate.y - initPos.y,
|
|
|
+ }
|
|
|
+ const start = {
|
|
|
+ x: initPos.x + move.x,
|
|
|
+ y: initPos.y + move.y,
|
|
|
+ }
|
|
|
+ const end = {
|
|
|
+ x: start.x + imgData.width * doScale[0],
|
|
|
+ y: start.y + imgData.height * doScale[1],
|
|
|
+ }
|
|
|
+
|
|
|
+ canvas.position = [
|
|
|
+ start,
|
|
|
+ end,
|
|
|
+ Math.abs(start.x - end.x) / resize,
|
|
|
+ Math.abs(start.y - end.y) / resize
|
|
|
+ ]
|
|
|
+
|
|
|
+ canvas.resize = resize
|
|
|
+ canvas.imgData = imgData
|
|
|
+ canvas.imgBox = [
|
|
|
+ canvas.posToReal(start),
|
|
|
+ canvas.posToReal(end),
|
|
|
+ Math.abs(start.x - end.x),
|
|
|
+ Math.abs(start.y - end.y)
|
|
|
+ ]
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 加载url
|
|
|
+ const canvas = document.createElement('canvas')
|
|
|
+ const loadImage = (map, args, itude) => {
|
|
|
+ const imageCanvas = new ol.source.ImageCanvas({
|
|
|
+ canvasFunction(extent, scale, _2, size) {
|
|
|
+ const pos = itudeToCanvasPos(map, extent, itude)
|
|
|
+ const imgData = { width: 0, height: 0 }
|
|
|
+ args.img.forEach(imgs => {
|
|
|
+ let height = 0
|
|
|
+ imgs.forEach(([img]) => height += img.height)
|
|
|
+ imgData.width += imgs[0][0].width
|
|
|
+ if (imgData.height < height) {
|
|
|
+ imgData.height = height
|
|
|
+ }
|
|
|
+ })
|
|
|
+ console.log(scale, size)
|
|
|
+ // pos.x -= imgData.width / 2 * scale
|
|
|
+ // pos.y -= imgData.height / 2 * scale
|
|
|
+ canvas.width = size[0];
|
|
|
+ canvas.height = size[1]
|
|
|
+ canvas.posToReal = genImgCanvasPosToReal(map, canvas);
|
|
|
+ canvas.transform = genImgCanvasTransfrom(canvas, args.img, scale, pos, imageCanvas);
|
|
|
+ canvas.itudeToReal = genImgCanvasItudeToReal(map, canvas, extent)
|
|
|
+ canvas.transform({
|
|
|
+ ...args,
|
|
|
+ translate: {
|
|
|
+ x: (args.translate ? args.translate.x : 0) + pos.x,
|
|
|
+ y: (args.translate ? args.translate.y : 0) + pos.y
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return canvas;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const image = new ol.layer.Image({ source: imageCanvas })
|
|
|
+ canvas.imageLayer = imageCanvas
|
|
|
+ return {
|
|
|
+ image,
|
|
|
+ canvas
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 返回本地url
|
|
|
+ const blobImageLoad = (arrayImages, minWidth, minHeight) => {
|
|
|
+ const analysis = (blob) => new Promise((resolve, reject) => {
|
|
|
+ const url = typeof blob !== 'string' ?
|
|
|
+ window.URL.createObjectURL(blob) :
|
|
|
+ blob
|
|
|
+ const img = new Image()
|
|
|
+
|
|
|
+ img.onload = () => {
|
|
|
+ if (img.width < minWidth || img.height < minHeight) {
|
|
|
+ reject('图片宽高需要大于512')
|
|
|
+ } else {
|
|
|
+ resolve([img, url, blob])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ img.src = url
|
|
|
+ })
|
|
|
+
|
|
|
+ let arrasPromises = []
|
|
|
+ for (let images of arrayImages) {
|
|
|
+ let analys = []
|
|
|
+ for (let bolb of images) {
|
|
|
+ analys.push(analysis(bolb))
|
|
|
+ }
|
|
|
+ arrasPromises.push(
|
|
|
+ Promise.all(analys)
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ return Promise.all(arrasPromises)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 获取逆转矩阵
|
|
|
+ const getCanvasInverImatrix = $canvas => {
|
|
|
+ const ctx = $canvas.getContext('2d')
|
|
|
+ const transform = ctx.getTransform()
|
|
|
+ return transform.invertSelf();
|
|
|
+ }
|
|
|
+
|
|
|
+ // canvas坐标转屏幕坐标
|
|
|
+ const getCanvasToScreenPos = ($canvas, { x, y }) => {
|
|
|
+ const {
|
|
|
+ a,
|
|
|
+ b,
|
|
|
+ c,
|
|
|
+ d,
|
|
|
+ e,
|
|
|
+ f
|
|
|
+ } = getCanvasInverImatrix($canvas)
|
|
|
+
|
|
|
+ const screenX = (c * y - d * x + d * e - c * f) / (b * c - a * d)
|
|
|
+ const screenY = (y - screenX * b - f) / d
|
|
|
+
|
|
|
+ return {
|
|
|
+ x: Math.round(screenX),
|
|
|
+ y: Math.round(screenY),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 屏幕坐标转canvas坐标
|
|
|
+ const getScreenToCanvasPos = ($canvas, { x, y }) => {
|
|
|
+ const {
|
|
|
+ a,
|
|
|
+ b,
|
|
|
+ c,
|
|
|
+ d,
|
|
|
+ e,
|
|
|
+ f
|
|
|
+ } = getCanvasInverImatrix($canvas)
|
|
|
+
|
|
|
+ return {
|
|
|
+ x: Math.round(x * a + y * c + e),
|
|
|
+ y: Math.round(x * b + y * d + f)
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ const sceneName = window.location.pathname.split('/')[2]
|
|
|
+ const isDev = !sceneName || sceneName === 'addDataSet.html'
|
|
|
+
|
|
|
+ const sceneCode = isDev ? 't-kJ2PEjZ' : window.location.pathname.split('/')[2]
|
|
|
+ const root = isDev ? `https://testlaser.4dkankan.com` : ''
|
|
|
+ // const root = 'http://192.168.0.135:9294'
|
|
|
+ const request = {
|
|
|
+ uploadFiles(files) {
|
|
|
+ const fromData = new FormData()
|
|
|
+ files.forEach(({ dir, file }) => {
|
|
|
+ fromData.append(dir, file)
|
|
|
+ })
|
|
|
+ return axios({
|
|
|
+ headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
+ method: 'POST',
|
|
|
+ data: fromData,
|
|
|
+ url: `${root}/indoor/${sceneCode}/api/mapSmall/upload`
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getDetail() {
|
|
|
+ return axios.post(`${root}/indoor/${sceneCode}/api/mapSmall/detail`)
|
|
|
+ },
|
|
|
+ updateCoord(data) {
|
|
|
+ return axios.post(
|
|
|
+ `${root}/indoor/${sceneCode}/api/update/coord`, { param: data }
|
|
|
+ )
|
|
|
+ },
|
|
|
+ getSceneInfo() {
|
|
|
+ return axios.get(`${root}/indoor/${sceneCode}/api/datasets`)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const analysisFiles = (files) => {
|
|
|
+ const imagesArray = []
|
|
|
+ const formatError = () => {
|
|
|
+ alert('目录不规范 请上传 z/x/y.png 格式目录,且在最底级目录放置图片文件')
|
|
|
+ }
|
|
|
+
|
|
|
+ let imagesXYZ = {}
|
|
|
+ for (let dir in files) {
|
|
|
+ let file = files[dir]
|
|
|
+ let locals = dir.split(/[\\|//]/)
|
|
|
+ if (locals.length < 3) return formatError()
|
|
|
+ let current = imagesXYZ
|
|
|
+ for (let i = 0; i < locals.length; i++) {
|
|
|
+ let dir = locals[i]
|
|
|
+
|
|
|
+ if (i !== locals.length - 1) {
|
|
|
+ if (!current[dir]) {
|
|
|
+ current[dir] = i === locals.length - 2 ? [] : {}
|
|
|
+ }
|
|
|
+ current = current[dir]
|
|
|
+
|
|
|
+ if (i === locals.length - 3) {
|
|
|
+ current.key = 'z'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i === locals.length - 1 && Array.isArray(current)) {
|
|
|
+ current.push(file)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ (function analysis(updateXYZ) {
|
|
|
+ if (updateXYZ.key === 'z') {
|
|
|
+ imagesXYZ = updateXYZ
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const names = Object.keys(updateXYZ).sort((a, b) => b - a)
|
|
|
+ names.forEach(key => {
|
|
|
+ if (key !== names[0]) {
|
|
|
+ delete updateXYZ[key]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ analysis(updateXYZ[names[0]])
|
|
|
+ })(imagesXYZ);
|
|
|
+
|
|
|
+ if (!(imagesXYZ && imagesXYZ.key === 'z' && !Array.isArray(imagesXYZ))) {
|
|
|
+ return formatError()
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let key in imagesXYZ) {
|
|
|
+ if (!Array.isArray(imagesXYZ[key]) && key !== 'key') {
|
|
|
+ return formatError()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ delete imagesXYZ.key
|
|
|
+
|
|
|
+ const getNameNum = (str) => {
|
|
|
+ let rg = str.match(/[\/\\]([^\/\\]*)?\.[^\/\\]*$/)
|
|
|
+ return weight = rg ? parseInt(rg[1]) : 999
|
|
|
+ }
|
|
|
+
|
|
|
+ Object.keys(imagesXYZ).sort((a, b) => a - b).forEach(key => {
|
|
|
+ imagesArray.push(
|
|
|
+ imagesXYZ[key].sort((a, b) => {
|
|
|
+ let wa = typeof a === 'string'
|
|
|
+ ? getNameNum(a)
|
|
|
+ : parseInt(a.name)
|
|
|
+
|
|
|
+ let wb = typeof b === 'string'
|
|
|
+ ? getNameNum(b)
|
|
|
+ : parseInt(b.name)
|
|
|
+ return wa - wb
|
|
|
+ })
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+ return imagesArray
|
|
|
+ }
|
|
|
+ // 目录:<input type="file" @change="imageChange" directory webkitdirectory multiple>
|
|
|
+ Vue.component('imageTranform', {
|
|
|
+ props: ['mapOl'],
|
|
|
+ name: 'imageTranform',
|
|
|
+ template: `
|
|
|
+ <div class="transform-layer" @mousemove.stop.prevent="moveHandle" @mouseup="upMove">
|
|
|
+ <div class="upload-layer">
|
|
|
+
|
|
|
+ 单文件:<input type="file" @change="imageChange">
|
|
|
+ </div>
|
|
|
+ <div class="ctrls" :style="boxStyle" @mousedown.stop.prevent="startMove($event, 'move')"></div>
|
|
|
+ <div class="cctrls" v-if="box.tl">
|
|
|
+ <span class="tl" :style="{left: box.tl.x + 'px', top: box.tl.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tl')"></span>
|
|
|
+ <span class="tc" :style="{left: box.tc.x + 'px', top: box.tc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tc')"></span>
|
|
|
+ <span class="tr" :style="{left: box.tr.x + 'px', top: box.tr.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tr')"></span>
|
|
|
+ <span class="rc" :style="{left: box.rc.x + 'px', top: box.rc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'rc')"></span>
|
|
|
+ <span class="lc" :style="{left: box.lc.x + 'px', top: box.lc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'lc')"></span>
|
|
|
+ <span class="br" :style="{left: box.br.x + 'px', top: box.br.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'br')"></span>
|
|
|
+ <span class="bl" :style="{left: box.bl.x + 'px', top: box.bl.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'bl')"></span>
|
|
|
+ <span class="bc" :style="{left: box.bc.x + 'px', top: box.bc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'bc')"></span>
|
|
|
+ <span class="cc" :style="{left: box.cc.x + 'px', top: box.cc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'rotate')"></span>
|
|
|
+ </div>
|
|
|
+ <div class="box-info" v-if="boxPos.tl">
|
|
|
+ <div v-for="(item, key) in boxPos" :key="key">
|
|
|
+ <span>{{key}}</span>
|
|
|
+ <span>{{item}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `,
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ isHover: false,
|
|
|
+ box: {},
|
|
|
+ left: 0,
|
|
|
+ top: 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ imageChange(e) {
|
|
|
+ const files = e.target.files;
|
|
|
+ if (files && files[0]) {
|
|
|
+ const file = files[0];
|
|
|
+ // onload 里面不能用this
|
|
|
+ let img = new Image();
|
|
|
+ img.src = window.URL.createObjectURL(file);
|
|
|
+ img.onload = async () => {
|
|
|
+ if (img.width % 256 == 0 && img.height % 256 == 0) {
|
|
|
+ let imagesArray = []
|
|
|
+
|
|
|
+ if (e.target.files.length > 1) {
|
|
|
+ const files = {}
|
|
|
+ for (let file of e.target.files) {
|
|
|
+ files[file.webkitRelativePath] = file
|
|
|
+ }
|
|
|
+ imagesArray = analysisFiles(files)
|
|
|
+ } else {
|
|
|
+ imagesArray = [
|
|
|
+ [e.target.files[0]]
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ if (this.imgCanvas) {
|
|
|
+ ctx = this.imgCanvas.getContext('2d')
|
|
|
+ ctx.clearRect(-10000, -10000, 10000, 10000)
|
|
|
+ this.imgCanvas.imageLayer.refresh()
|
|
|
+ }
|
|
|
+ await this.drawCanvas(imagesArray, [], {
|
|
|
+ lat: this.lat,
|
|
|
+ lon: this.lon
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ alert('图片宽高需为256的倍数')
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+ async drawCanvas(imagesArray, transfroms, { lat, lon } = {}) {
|
|
|
+ try {
|
|
|
+ this.transfroms = transfroms || []
|
|
|
+ this.args = {
|
|
|
+ draw: (ctx) => {
|
|
|
+ this.drawIng = false
|
|
|
+ this.transfroms.forEach(transform => {
|
|
|
+ transform.forEach(({ translate, scale, rotate, center }) => {
|
|
|
+ // 设置绘制颜色
|
|
|
+ center && ctx.translate(center.x, center.y)
|
|
|
+ translate && ctx.translate(translate.x, translate.y)
|
|
|
+ rotate && ctx.rotate(rotate * (Math.PI / 180))
|
|
|
+ scale && ctx.scale(scale[0], scale[1])
|
|
|
+ center && ctx.translate(-center.x, -center.y)
|
|
|
+ // if (center) {
|
|
|
+ // ctx.fillStyle = "geend";
|
|
|
+ // // 绘制成矩形
|
|
|
+ // ctx.fillRect(center.x, center.y, 100, 100);
|
|
|
+ // }
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ this.updateBox(this.imgCanvas.imgBox)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ file: imagesArray,
|
|
|
+ lon: lon || 113.59963069739054,
|
|
|
+ lat: lat || 22.364821730960752,
|
|
|
+ translate: { x: 0, y: 0 },
|
|
|
+ scale: [1, 1],
|
|
|
+ direction: 0
|
|
|
+ }
|
|
|
+ this.imgCanvas = await this.map.loadImage(this.args)
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e)
|
|
|
+ alert(e)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ updateBox() {
|
|
|
+ const calcPos = pos => getCanvasToScreenPos(this.imgCanvas, pos)
|
|
|
+ this.box = {
|
|
|
+ tl: this.imgCanvas.posToReal(calcPos({ x: 0, y: 0 })),
|
|
|
+ tc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width / 2, y: 0 })),
|
|
|
+ tr: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width, y: 0 })),
|
|
|
+ rc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width, y: this.imgCanvas.imgData.height / 2 })),
|
|
|
+ lc: this.imgCanvas.posToReal(calcPos({ x: 0, y: this.imgCanvas.imgData.height / 2 })),
|
|
|
+ br: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width, y: this.imgCanvas.imgData.height })),
|
|
|
+ bl: this.imgCanvas.posToReal(calcPos({ x: 0, y: this.imgCanvas.imgData.height })),
|
|
|
+ bc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width / 2, y: this.imgCanvas.imgData.height })),
|
|
|
+ cc: this.imgCanvas.posToReal(calcPos({ x: this.imgCanvas.imgData.width / 2, y: this.imgCanvas.imgData.height / 2 })),
|
|
|
+ }
|
|
|
+
|
|
|
+ let maxX = this.box.tl.x
|
|
|
+ let minX = this.box.tl.x
|
|
|
+ let maxY = this.box.tl.y
|
|
|
+ let minY = this.box.tl.y
|
|
|
+ Object.values(this.box).forEach(({ x, y }) => {
|
|
|
+ x > maxX && (maxX = x)
|
|
|
+ y > maxY && (maxY = y)
|
|
|
+ x < minX && (minX = x)
|
|
|
+ y < minY && (minY = y)
|
|
|
+ })
|
|
|
+ this.box.width = Math.abs(maxX - minX)
|
|
|
+ this.box.height = Math.abs(maxY - minY)
|
|
|
+ },
|
|
|
+ mapStartHandle() {
|
|
|
+ this.mapDown = true
|
|
|
+ },
|
|
|
+ moveHandle(e) {
|
|
|
+ if (!this.imgCanvas || !this.imgCanvas.imgBox) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.moveing && this.oper) {
|
|
|
+ if (!this.time && !this.drawIng) {
|
|
|
+ this.move(e)
|
|
|
+ this.time = null
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.mapDown && this.imgCanvas.imageLayer.refresh()
|
|
|
+ // const [start, end] = this.box
|
|
|
+
|
|
|
+ // this.isHover = e.clientX > start.x && e.clientX < end.x &&
|
|
|
+ // e.clientY > start.y && e.clientY < end.y
|
|
|
+ }
|
|
|
+ },
|
|
|
+ startMove(ev, oper, dir) {
|
|
|
+ this.startTransform = {
|
|
|
+ ...this.args
|
|
|
+ }
|
|
|
+ this.transfroms.push([])
|
|
|
+ this.moveing = true
|
|
|
+ this.oper = oper
|
|
|
+ this.dir = dir
|
|
|
+ this.startMovePos = {
|
|
|
+ x: ev.clientX,
|
|
|
+ y: ev.clientY
|
|
|
+ }
|
|
|
+ },
|
|
|
+ move(ev) {
|
|
|
+ if (!this.moveing || this.drawIng) return;
|
|
|
+ const transfrom = this.transfroms[this.transfroms.length - 1]
|
|
|
+ const start = getScreenToCanvasPos(
|
|
|
+ this.imgCanvas,
|
|
|
+ this.startMovePos
|
|
|
+ )
|
|
|
+ const end = getScreenToCanvasPos(
|
|
|
+ this.imgCanvas, { x: ev.clientX, y: ev.clientY }
|
|
|
+ )
|
|
|
+ const move = {
|
|
|
+ x: end.x - start.x,
|
|
|
+ y: end.y - start.y
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (this.oper === 'move') {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({ translate: move })
|
|
|
+ } else if (this.oper === 'scale') {
|
|
|
+
|
|
|
+ const doScale = (transfrom && transfrom[0] && transfrom[0].scale) || [1, 1]
|
|
|
+ move.x = move.x * doScale[0]
|
|
|
+ move.y = move.y * doScale[1]
|
|
|
+ const width = this.imgCanvas.position[2]
|
|
|
+ const height = this.imgCanvas.position[3]
|
|
|
+ let xScale, yScale
|
|
|
+
|
|
|
+ switch (this.dir) {
|
|
|
+ case 'tl':
|
|
|
+ xScale = (width - move.x) / width
|
|
|
+ yScale = (height - move.y) / height
|
|
|
+ if (xScale < yScale) {
|
|
|
+ yScale = xScale
|
|
|
+ } else {
|
|
|
+ xScale = yScale
|
|
|
+ }
|
|
|
+ if (xScale > 0 && yScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [xScale, yScale],
|
|
|
+ center: { x: this.imgCanvas.position[2], y: this.imgCanvas.position[3] }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'tc':
|
|
|
+ yScale = (height - move.y) / height
|
|
|
+ if (yScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [1, yScale],
|
|
|
+ center: { x: 0, y: this.imgCanvas.position[3] }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'tr':
|
|
|
+ xScale = (width + move.x) / width
|
|
|
+ yScale = (height - move.y) / height
|
|
|
+ if (xScale > yScale) {
|
|
|
+ yScale = xScale
|
|
|
+ } else {
|
|
|
+ xScale = yScale
|
|
|
+ }
|
|
|
+ if (xScale > 0 && yScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [xScale, yScale],
|
|
|
+ center: { x: 0, y: this.imgCanvas.position[3] }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'rc':
|
|
|
+ xScale = (width + move.x) / width
|
|
|
+ if (xScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [xScale, 1],
|
|
|
+ center: { x: 0, y: this.imgCanvas.position[3] }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'lc':
|
|
|
+ xScale = (width - move.x) / width
|
|
|
+ if (xScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [xScale, 1],
|
|
|
+ center: { x: this.imgCanvas.position[2], y: this.imgCanvas.position[3] }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'br':
|
|
|
+ xScale = (width + move.x) / width
|
|
|
+ yScale = (height + move.y) / height
|
|
|
+ if (xScale < yScale) {
|
|
|
+ yScale = xScale
|
|
|
+ } else {
|
|
|
+ xScale = yScale
|
|
|
+ }
|
|
|
+ if (xScale > 0 && yScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [xScale, yScale],
|
|
|
+ center: { x: 0, y: 0 }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'bl':
|
|
|
+ xScale = (width - move.x) / width
|
|
|
+ yScale = (height + move.y) / height
|
|
|
+ if (xScale < yScale) {
|
|
|
+ yScale = xScale
|
|
|
+ } else {
|
|
|
+ xScale = yScale
|
|
|
+ }
|
|
|
+ if (xScale > 0 && yScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [xScale, yScale],
|
|
|
+ center: { x: this.imgCanvas.position[2], y: 0 }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'bc':
|
|
|
+ yScale = (height + move.y) / height
|
|
|
+ if (yScale > 0) {
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ scale: [1, yScale],
|
|
|
+ center: { x: 0, y: 0 }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else if (this.oper === 'rotate') {
|
|
|
+ let move = ev.clientX - this.startMovePos.x
|
|
|
+ let height = this.imgCanvas.position[3]
|
|
|
+ let width = this.imgCanvas.position[2]
|
|
|
+ let center = { x: width / 2, y: height / 2 }
|
|
|
+
|
|
|
+ // let zrotate = transfrom.
|
|
|
+ transfrom.length = 0
|
|
|
+ transfrom.push({
|
|
|
+ rotate: move / 3,
|
|
|
+ center: center
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // this.startMovePos = {
|
|
|
+ // x: ev.clientX,
|
|
|
+ // y: ev.clientY
|
|
|
+ // }
|
|
|
+ this.drawIng = true
|
|
|
+ this.imgCanvas.imageLayer.refresh()
|
|
|
+ },
|
|
|
+ upMove() {
|
|
|
+ this.moveing = false
|
|
|
+ this.mapDown = false
|
|
|
+ this.oper = null
|
|
|
+ this.dir = null
|
|
|
+ this.startMovePos = null
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+ uploadData() {
|
|
|
+ if (!this.args) {
|
|
|
+ return Promise.resolve(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ const promises = []
|
|
|
+ const files = []
|
|
|
+ for (let i = 0; i < this.args.img.length; i++) {
|
|
|
+ const images = this.args.img[i]
|
|
|
+ for (let j = 0; j < images.length; j++) {
|
|
|
+ const file = images[j][2]
|
|
|
+ if (typeof file !== 'string') {
|
|
|
+ const suffix = file.type.substr(file.type.indexOf('/') + 1)
|
|
|
+ files.push({ dir: `${i}/${j}.${suffix}`, file })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (files.length) {
|
|
|
+ if (files.length === 1) {
|
|
|
+ const file = files[0]
|
|
|
+ files.length = 0
|
|
|
+ files.push({
|
|
|
+ ...file,
|
|
|
+ dir: file.file.name
|
|
|
+ })
|
|
|
+ }
|
|
|
+ promises.push(
|
|
|
+ request.uploadFiles(files)
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ promises.push(
|
|
|
+ request.updateCoord({
|
|
|
+ ...this.boxPos,
|
|
|
+ transfroms: this.transfroms
|
|
|
+ })
|
|
|
+ )
|
|
|
+ return Promise.all(promises)
|
|
|
+ },
|
|
|
+ getInfo() {
|
|
|
+ return {
|
|
|
+ pos: this.boxPos,
|
|
|
+ img: this.args.img
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ boxStyle() {
|
|
|
+ if (this.box && Object.keys(this.box).length) {
|
|
|
+ const box = this.box
|
|
|
+ return {
|
|
|
+ width: box.width + 20 + 'px',
|
|
|
+ height: box.height + 20 + 'px',
|
|
|
+ left: box.cc.x + 'px',
|
|
|
+ top: box.cc.y + 'px'
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ boxPos() {
|
|
|
+ if (this.box && Object.keys(this.box).length) {
|
|
|
+ const ret = {}
|
|
|
+ for (let key in this.box) {
|
|
|
+ if (key !== 'width' && key !== 'height') {
|
|
|
+ ret[key] = this.map.screenToLatlan(this.box[key])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let rotate = 0
|
|
|
+ let scale = {x: 1, y: 1}
|
|
|
+ this.transfroms.forEach(items => {
|
|
|
+ items.forEach(item => {
|
|
|
+ if (item.rotate) {
|
|
|
+ rotate = Number((rotate + Number(item.rotate)).toFixed(2))
|
|
|
+ }
|
|
|
+ if (item.scale) {
|
|
|
+ scale.x *= item.scale[0]
|
|
|
+ scale.y *= item.scale[1]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ ret.rotate = rotate
|
|
|
+ ret.scale = scale
|
|
|
+ let ctx = this.imgCanvas.getContext('2d')
|
|
|
+ let key = ['a', 'b', 'c', 'd', 'e', 'f']
|
|
|
+ let imatrix = ctx.getTransform()
|
|
|
+ ret.imatrix = {}
|
|
|
+ key.forEach(k => ret.imatrix[k] = imatrix[k])
|
|
|
+ return ret
|
|
|
+ } else {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ Promise.all([
|
|
|
+ request.getDetail(),
|
|
|
+ request.getSceneInfo()
|
|
|
+ ]).then(async ([res1, res2]) => {
|
|
|
+ const {
|
|
|
+ path,
|
|
|
+ position
|
|
|
+ } = res1.data.data
|
|
|
+ const { location } = res2.data[0]
|
|
|
+
|
|
|
+ if (path && path.length > 0) {
|
|
|
+ const files = {}
|
|
|
+ path.forEach(path => (files[path] = root + path))
|
|
|
+ await this.drawCanvas(
|
|
|
+ analysisFiles(files),
|
|
|
+ position ? position.transfroms : [], {
|
|
|
+ lat: location[1],
|
|
|
+ lon: location[0],
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ this.lat = location[1]
|
|
|
+ this.lon = location[0]
|
|
|
+ })
|
|
|
+
|
|
|
+ document.documentElement.addEventListener('mousemove', ev => {
|
|
|
+ ev.stopPropagation()
|
|
|
+ ev.preventDefault()
|
|
|
+ this.moveHandle.bind(this)(ev)
|
|
|
+ // this.move.bind(this)(ev)
|
|
|
+ })
|
|
|
+ document.documentElement.addEventListener('mousedown', ev => {
|
|
|
+ this.mapStartHandle.bind(this)(ev)
|
|
|
+ })
|
|
|
+ document.documentElement.addEventListener('mouseup', ev => {
|
|
|
+ ev.stopPropagation()
|
|
|
+ ev.preventDefault()
|
|
|
+ this.upMove.bind(this)()
|
|
|
+ })
|
|
|
+ this.map = initMap(this.mapOl)
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+})();
|