Quellcode durchsuchen

添加地图对准功能

bill vor 4 Jahren
Ursprung
Commit
57b29daa8d
3 geänderte Dateien mit 744 neuen und 7 gelöschten Zeilen
  1. 10 5
      locat/addDataSet.html
  2. 688 0
      locat/components/image-transform/index.js
  3. 46 2
      locat/style.css

+ 10 - 5
locat/addDataSet.html

@@ -153,6 +153,7 @@
                     <div class="style"></div>
                     <div class="style"></div>
                     <!-- <input type="submit" class="submitBtn" value="提交" />
                     <!-- <input type="submit" class="submitBtn" value="提交" />
                     <button id="clear">取消</button> -->
                     <button id="clear">取消</button> -->
+                    <div id="clear" @click="getImageTransform">获取信息</div>
                     <div id="clear" @click="clearMap">取消</div>
                     <div id="clear" @click="clearMap">取消</div>
                     <div class="submitBtn" @click="commit()">
                     <div class="submitBtn" @click="commit()">
                         提交
                         提交
@@ -161,10 +162,10 @@
                 </div>
                 </div>
             </div>
             </div>
             <div class="rightBox">
             <div class="rightBox">
-                <div id="map" class="map">
-
+                <div class="map-layer">
+                    <div id="map" class="map"></div>    
+                    <image-tranform :map-ol="map" v-if="map" ref="imageTranform" />
                 </div>
                 </div>
-
             </div>
             </div>
 
 
         </div>
         </div>
@@ -172,6 +173,7 @@
 
 
     <script src="./js/vue.js"></script>
     <script src="./js/vue.js"></script>
     <script src="./js/axios.min.js"></script>
     <script src="./js/axios.min.js"></script>
+    <script src="./components/image-transform/index.js"></script>
     <script type="text/javascript">
     <script type="text/javascript">
         //输入经纬度就可以定位
         //输入经纬度就可以定位
     </script>
     </script>
@@ -183,7 +185,7 @@
                 return {
                 return {
 
 
                     pointLayerArray: [],
                     pointLayerArray: [],
-                    map: {},
+                    map: null,
                     gaodeMapLayer: {},
                     gaodeMapLayer: {},
                     ax: '',
                     ax: '',
                     ay: '',
                     ay: '',
@@ -236,7 +238,7 @@
 
 
                 this.map = this.initMap('map');
                 this.map = this.initMap('map');
 
 
-
+                console.log(this.map)
 
 
 
 
 
 
@@ -244,6 +246,9 @@
 
 
             },
             },
             methods: {
             methods: {
+                getImageTransform() {
+                    console.log(this.$refs.imageTranform.getInfo())
+                },
                 initMap(divid) {
                 initMap(divid) {
                     this.pointLayerArray = [];
                     this.pointLayerArray = [];
                     this.gaodeMapLayer = new ol.layer.Tile({
                     this.gaodeMapLayer = new ol.layer.Tile({

+ 688 - 0
locat/components/image-transform/index.js

@@ -0,0 +1,688 @@
+(() => {
+  // 初始地图
+  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:3857','EPSG:4326')
+        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) => {
+      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 loadImage = (map, args, itude) => {
+
+    const canvas = document.createElement('canvas');
+    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
+          }
+        })
+        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) => {
+    console.log(arrayImages)
+    const analysis = (blob) => new Promise((resolve, reject) => {
+      const url = window.URL.createObjectURL(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)
+    };
+  }
+
+
+
+  Vue.component('imageTranform', {
+    props: ['mapOl'],
+    name: 'imageTranform',
+    template: `
+      <div class="transform-layer"  @mousemove.stop.prevent="move"  @mouseup="upMove">
+        <div class="upload-layer">
+          目录:<input type="file" @change="imageChange" directory webkitdirectory multiple>
+          单文件:<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: {
+      async imageChange(e) {
+        let imagesArray = []
+        if (e.target.files.length > 1) {
+          const formatError = () => {
+            e.target.value = null
+            console.log(imagesXYZ)
+            alert('目录不规范 请上传 z/x/y.png 格式目录,且在最底级目录放置图片文件')
+          }
+          let imagesXYZ = {}
+          for (let file of e.target.files) {
+            let locals = file.webkitRelativePath.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) {
+                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
+
+          Object.keys(imagesXYZ).sort((a, b) => a - b).forEach(key => {
+            imagesArray.push(
+              imagesXYZ[key].sort((a, b) => parseInt(a.name) - parseInt(b))
+            )
+          })
+        } else {
+          imagesArray = [[e.target.files[0]]]
+        }
+
+        try {
+          this.transfroms = []
+          this.args = {
+            draw: (ctx) => {
+              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: 113.59963069739054,
+            lat: 22.364821730960752,
+            translate: {x: 0, y: 0},
+            scale: [1, 1],
+            direction: 0
+          }
+          console.log('---0---')
+          this.imgCanvas = await this.map.loadImage(this.args)
+        } catch(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) {
+          this.move(e)
+        } 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) 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.push({ translate: move })
+        } else if (this.oper === 'scale'){
+          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 > 0.1 && yScale > 0.1) {
+                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.1) {
+                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 > 0.1 && yScale > 0.1) {
+                transfrom.push({ 
+                  scale: [xScale, yScale],
+                  center: {x: 0, y: this.imgCanvas.position[3]}
+                })
+              }
+              break;
+            case 'rc':
+              xScale = (width + move.x) / width
+              if (xScale > 0.1) {
+                transfrom.push({ 
+                  scale: [xScale, 1],
+                  center: {x: 0, y: this.imgCanvas.position[3]}
+                })
+              }
+              break;
+            case 'lc':
+              xScale = (width - move.x) / width
+              if (xScale > 0.1) {
+              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 > 0.1 && yScale > 0.1) {
+              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 > 0.1 && yScale > 0.1) {
+              transfrom.push({ 
+                scale: [xScale, yScale],
+                center: {x: this.imgCanvas.position[2], y: 0}
+              })
+              }
+              break;
+            case 'bc':
+              yScale = (height + move.y) / height
+              if (yScale > 0.1) {
+              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.push({ 
+            rotate: move / 3,
+            center: center
+          })
+        }
+        this.startMovePos = {
+          x: ev.clientX,
+          y: ev.clientY
+        }
+        this.imgCanvas.imageLayer.refresh()
+      },
+      upMove() {
+        this.moveing = false
+        this.mapDown = false
+        this.oper = null
+        this.dir = null
+        this.startMovePos = null
+
+        
+      },
+      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])
+            }
+          }
+          return ret
+        } else {
+          return {}
+        }
+      }
+    },
+    mounted() {
+      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)
+      
+    }
+  })
+})();

+ 46 - 2
locat/style.css

@@ -29,7 +29,7 @@ body {
     justify-content: center;
     justify-content: center;
 }
 }
 
 
-.map {
+.map-layer {
     height: 800px;
     height: 800px;
     width: 94%;
     width: 94%;
     padding: 0px;
     padding: 0px;
@@ -38,6 +38,11 @@ body {
 
 
 }
 }
 
 
+.map-layer .map {
+    width: 100%;
+    height: 100%;
+}
+
 #plane {
 #plane {
     width: 30%;
     width: 30%;
     height: 100%;
     height: 100%;
@@ -279,4 +284,43 @@ input::-webkit-input-placeholder {
     background-color: rgb(0, 0, 0, 0.3);
     background-color: rgb(0, 0, 0, 0.3);
     z-index: 1;
     z-index: 1;
     color: #fff;
     color: #fff;
-}
+}
+
+.transform-layer {
+    top: 0;
+    left: 0;
+}
+
+.upload-layer {
+    z-index: 99;
+    left: 0;
+    top: 0;
+    position: absolute;
+}
+
+.ctrls {
+    position: absolute;
+    z-index: 9;
+    --margin: 10px;
+    transform: translate(-50%, -50%);
+  }
+  
+  .cctrls span {
+    z-index: 10;
+    position: absolute;
+    width: 10px;
+    height: 10px;
+    border-radius: 50%;
+    background: red;
+    cursor: pointer;
+    transform: translate(-50%, -50%);
+  }
+  
+  .box-info {
+    padding: 10px;
+    color: #fff;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    background: rgba(0, 0, 0, 0.5);
+  }