Browse Source

Merge branch 'master' of http://192.168.0.115:3000/4dkankan/laser_v1

# Conflicts:
#	笔记.js
xzw 3 years ago
parent
commit
a15f344426
100 changed files with 21143 additions and 149 deletions
  1. 0 0
      0.js
  2. 0 0
      1.js
  3. 1 0
      10.js
  4. 0 0
      12.js
  5. 1 0
      14.js
  6. 113 0
      15.js
  7. 2 2
      17.82bbf60e16d46d39aea0.js
  8. 1 0
      18.js
  9. 1 1
      19.77825ef0e44aed4d6923.js
  10. 0 0
      2.js
  11. 1 0
      20.js
  12. 0 0
      21.js
  13. 1 0
      22.js
  14. 0 0
      23.js
  15. 0 0
      24.js
  16. 0 0
      25.js
  17. 1 0
      3.js
  18. 0 0
      5.js
  19. 0 0
      8.js
  20. 2661 0
      IndoorViewer.all.min.js
  21. 0 0
      PointCloud.worker.js
  22. 1 1
      api/bundles
  23. BIN
      api/mapSmall/0/0/0.png
  24. BIN
      api/mapSmall/1/0/0.png
  25. BIN
      api/mapSmall/1/0/1.png
  26. BIN
      api/mapSmall/1/1/0.png
  27. BIN
      api/mapSmall/1/1/1.png
  28. BIN
      api/mapSmall/2/0/0.png
  29. BIN
      api/mapSmall/2/0/1.png
  30. BIN
      api/mapSmall/2/0/2.png
  31. BIN
      api/mapSmall/2/0/3.png
  32. BIN
      api/mapSmall/2/1/0.png
  33. BIN
      api/mapSmall/2/1/1.png
  34. BIN
      api/mapSmall/2/1/2.png
  35. BIN
      api/mapSmall/2/1/3.png
  36. BIN
      api/mapSmall/2/2/0.png
  37. BIN
      api/mapSmall/2/2/1.png
  38. BIN
      api/mapSmall/2/2/2.png
  39. BIN
      api/mapSmall/2/2/3.png
  40. BIN
      api/mapSmall/2/3/0.png
  41. BIN
      api/mapSmall/2/3/1.png
  42. BIN
      api/mapSmall/2/3/2.png
  43. BIN
      api/mapSmall/2/3/3.png
  44. 1 14
      api/tiled_maps
  45. 0 0
      arrow.png
  46. 125 0
      bus/bus.js
  47. 1 0
      c25767434b48e05a84a7384257d53f88.custom.svg
  48. BIN
      circle.png
  49. 964 0
      components/image-transform/index.js
  50. 205 0
      components/upload-pointClound/index.js
  51. 307 0
      components/upload-titlemap/index.js
  52. 0 0
      cross_hair.png
  53. 15704 0
      css/element.css
  54. BIN
      css/fonts/element-icons.ttf
  55. BIN
      css/fonts/element-icons.woff
  56. 524 128
      css/style.css
  57. 0 0
      cursor_side.png
  58. BIN
      data/2/0/0.png
  59. BIN
      data/2/0/1.png
  60. BIN
      data/2/0/2.png
  61. BIN
      data/2/0/3.png
  62. BIN
      data/2/1/0.png
  63. BIN
      data/2/1/1.png
  64. BIN
      data/2/1/2.png
  65. BIN
      data/2/1/3.png
  66. BIN
      data/2/2/0.png
  67. BIN
      data/2/2/1.png
  68. BIN
      data/2/2/2.png
  69. BIN
      data/2/2/3.png
  70. BIN
      data/2/3/0.png
  71. BIN
      data/2/3/1.png
  72. BIN
      data/2/3/2.png
  73. BIN
      data/2/3/3.png
  74. 0 0
      delete.png
  75. 503 0
      dependencies/ckeditor_plugins/base64image/dialogs/base64image.js
  76. 22 0
      dependencies/ckeditor_plugins/insertsound/dialogs/insertsound.js
  77. 3 3
      dependencies/ckeditor_plugins/youtube/lang/zh.js
  78. 0 0
      dot.png
  79. BIN
      font/SourceHanSansCN-Bold.otf
  80. BIN
      font/SourceHanSansCN-Regular.otf
  81. BIN
      font/element-icons.ttf
  82. BIN
      font/element-icons.woff
  83. 0 0
      free_area_sprite.png
  84. 0 0
      free_distance_sprite.png
  85. 0 0
      generic_poi.png
  86. 0 0
      gridmap.png
  87. BIN
      horizontal_area_polygon_sprite.png
  88. 0 0
      horizontal_area_rectangle_sprite.png
  89. BIN
      horizontal_distance_sprite.png
  90. BIN
      img/gangwan256.png
  91. BIN
      img/icon/disable-1.png
  92. BIN
      img/icon/disable-2.png
  93. BIN
      img/icon/download-1.png
  94. BIN
      img/icon/download-2.png
  95. BIN
      img/icon/icon_back.png
  96. BIN
      img/icon/icon_data@2_1.png
  97. BIN
      img/icon/icon_data@2x.png
  98. BIN
      img/icon/icon_element@2x.png
  99. BIN
      img/icon/icon_element@2x_1.png
  100. 0 0
      img/icon/icon_load_n.png

0.000f190386b228875e25.js → 0.js


1.c1853290f670423b7527.js → 1.js


File diff suppressed because it is too large
+ 1 - 0
10.js


vendors~main.async.cbcba49054e73e98695c.js → 12.js


File diff suppressed because it is too large
+ 1 - 0
14.js


File diff suppressed because it is too large
+ 113 - 0
15.js


+ 2 - 2
17.82bbf60e16d46d39aea0.js

@@ -1070,7 +1070,7 @@
                             l.ɵɵadvance(1),
                             l.ɵɵadvance(1),
                             l.ɵɵproperty("ngIf", i.isArea(o.measurement)),
                             l.ɵɵproperty("ngIf", i.isArea(o.measurement)),
                             l.ɵɵadvance(1),
                             l.ɵɵadvance(1),
-                            l.ɵɵproperty("ngIf", o.location),
+                            // l.ɵɵproperty("ngIf", o.location),
                             l.ɵɵadvance(4),
                             l.ɵɵadvance(4),
                             l.ɵɵproperty("href", o.url.value, l.ɵɵsanitizeUrl),
                             l.ɵɵproperty("href", o.url.value, l.ɵɵsanitizeUrl),
                             l.ɵɵadvance(1),
                             l.ɵɵadvance(1),
@@ -3374,7 +3374,7 @@
                 })
                 })
         },
         },
         2049: function(e, t, n) {
         2049: function(e, t, n) {
-            e.exports = n.p + "8f205d6811eb2231cd87b97fa86a3099.warn-button.png"
+            e.exports = n.p + "warn-button.png"
         }
         }
     }
     }
 ]);
 ]);

File diff suppressed because it is too large
+ 1 - 0
18.js


File diff suppressed because it is too large
+ 1 - 1
19.77825ef0e44aed4d6923.js


2.2ce6b49b8b065f35ecd0.js → 2.js


File diff suppressed because it is too large
+ 1 - 0
20.js


21.6e35bf5486d7bec96c04.js → 21.js


File diff suppressed because it is too large
+ 1 - 0
22.js


23.8641b8fc3d6165bb187f.js → 23.js


24.4b5f0f3ea342b634f9c3.js → 24.js


25.1f3d6c9616e13f12f5f2.js → 25.js


File diff suppressed because it is too large
+ 1 - 0
3.js


NotoSansCJKsc-Regular.3d696b37feacacc5ade6.js → 5.js


fonts.5129d374a8ae9f620fd1.js → 8.js


File diff suppressed because it is too large
+ 2661 - 0
IndoorViewer.all.min.js


PointCloud.6891a103d9b18f6f5ac7.worker.js → PointCloud.worker.js


+ 1 - 1
api/bundles

@@ -4,7 +4,7 @@
 		"group_write": 1,
 		"group_write": 1,
 		"can_write": false
 		"can_write": false
 	},
 	},
-	"id": 3,
+	"id": 1,
 	"serial": "abc",
 	"serial": "abc",
 	"name": "4dage"
 	"name": "4dage"
 }]
 }]

BIN
api/mapSmall/0/0/0.png


BIN
api/mapSmall/1/0/0.png


BIN
api/mapSmall/1/0/1.png


BIN
api/mapSmall/1/1/0.png


BIN
api/mapSmall/1/1/1.png


BIN
api/mapSmall/2/0/0.png


BIN
api/mapSmall/2/0/1.png


BIN
api/mapSmall/2/0/2.png


BIN
api/mapSmall/2/0/3.png


BIN
api/mapSmall/2/1/0.png


BIN
api/mapSmall/2/1/1.png


BIN
api/mapSmall/2/1/2.png


BIN
api/mapSmall/2/1/3.png


BIN
api/mapSmall/2/2/0.png


BIN
api/mapSmall/2/2/1.png


BIN
api/mapSmall/2/2/2.png


BIN
api/mapSmall/2/2/3.png


BIN
api/mapSmall/2/3/0.png


BIN
api/mapSmall/2/3/1.png


BIN
api/mapSmall/2/3/2.png


BIN
api/mapSmall/2/3/3.png


+ 1 - 14
api/tiled_maps

@@ -1,14 +1 @@
-[{
-	"bundle_id": 3,
-	"file_path": "data/building_1/mapTest2",
-	"file_name": "$DEPTH/$X/$Y.png",
-	"floor_id": 11,
-	"id": 5,
-	"map_size_m": 37.10058256252635,
-	"max_depth": 3,
-	"quadtree": "fccf7fffcff3bf7f",
-	"location": [113.5892056859005,22.367124170442096,0.5987030136375425],
-	"orientation": [1,0,0,0],
-	"tile_size_px": 256,
-	"type": "TILED_PYRAMID"
-}]
+[]

0ae72e353e12716c1d1b33208d4c0ad6.arrow.png → arrow.png


+ 125 - 0
bus/bus.js

@@ -0,0 +1,125 @@
+(function(caller, bus) {
+    if (typeof exports === "object" && typeof module === "object") {
+        module.exports = bus();
+        module.exports.default = module.exports
+    } else if (typeof exports === "object") {
+        exports.EventBus = bus()
+    } else {
+        caller.EventBus = bus()
+    }
+})(this, function() {
+    var EventBus = function() {
+        this.listeners = {};
+        this.registerListener = function(event, callback, number) {
+            var type = event.constructor.name;
+            number = this.validateNumber(number || "any");
+            if (type !== "Array") {
+                event = [event]
+            }
+            event.forEach(function(e) {
+                if (e.constructor.name !== "String") {
+                    throw new Error("Only `String` and array of `String` are accepted for the event names!")
+                }
+                that.listeners[e] = that.listeners[e] || [];
+                that.listeners[e].push({
+                    callback: callback,
+                    number: number
+                })
+            })
+        };
+        this.validateNumber = function(n) {
+            var type = n.constructor.name;
+            if (type === "Number") {
+                return n
+            } else if (type === "String" && n.toLowerCase() === "any") {
+                return "any"
+            }
+            throw new Error("Only `Number` and `any` are accepted in the number of possible executions!")
+        };
+        this.toBeRemoved = function(info) {
+            var number = info.number;
+            info.execution = info.execution || 0;
+            info.execution++;
+            if (number === "any" || info.execution < number) {
+                return false
+            }
+            return true
+        };
+        var that = this;
+        return {
+            on: function(eventName, callback) {
+                that.registerListener.bind(that)(eventName, callback, "any")
+            },
+            once: function(eventName, callback) {
+                that.registerListener.bind(that)(eventName, callback, 1)
+            },
+            exactly: function(number, eventName, callback) {
+                that.registerListener.bind(that)(eventName, callback, number)
+            },
+            die: function(eventName) {
+                delete that.listeners[eventName]
+            },
+            off: function(eventName) {
+                this.die(eventName)
+            },
+            detach: function(eventName, callback) {
+                if (callback === undefined) {
+                    that.listeners[eventName] = [];
+                    return true
+                }
+                for (var k in that.listeners[eventName]) {
+                    if (that.listeners[eventName].hasOwnProperty(k) && that.listeners[eventName][k].callback === callback) {
+                        that.listeners[eventName].splice(k, 1);
+                        return this.detach(eventName, callback)
+                    }
+                }
+                return true
+            },
+            detachAll: function() {
+                for (var eventName in that.listeners) {
+                    if (that.listeners.hasOwnProperty(eventName)) {
+                        this.detach(eventName)
+                    }
+                }
+            },
+            emit: function(eventName, context) {
+                var listeners = [];
+                for (var name in that.listeners) {
+                    if (that.listeners.hasOwnProperty(name)) {
+                        if (name === eventName) {
+                            Array.prototype.push.apply(listeners, that.listeners[name])
+                        }
+                        if (name.indexOf("*") >= 0) {
+                            var newName = name.replace(/\*\*/, "([^.]+.?)+");
+                            newName = newName.replace(/\*/g, "[^.]+");
+                            var match = eventName.match(newName);
+                            if (match && eventName === match[0]) {
+                                Array.prototype.push.apply(listeners, that.listeners[name])
+                            }
+                        }
+                    }
+                }
+                var parentArgs = arguments;
+                context = context || this;
+                listeners.forEach(function(info, index) {
+                    var callback = info.callback;
+                    var number = info.number;
+                    if (context) {
+                        callback = callback.bind(context)
+                    }
+                    var args = [];
+                    Object.keys(parentArgs).map(function(i) {
+                        if (i > 1) {
+                            args.push(parentArgs[i])
+                        }
+                    });
+                    if (that.toBeRemoved(info)) {
+                        that.listeners[eventName].splice(index, 1)
+                    }
+                    callback.apply(null, args)
+                })
+            }
+        }
+    };
+    return EventBus
+});

+ 1 - 0
c25767434b48e05a84a7384257d53f88.custom.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linejoin:round;stroke-width:3px}</style></defs><g id="white_icons" data-name="white icons"><path class="cls-1" d="M65.03 90.88L34.56 77.82V47.71l30.47 9.98v33.19zm0-33.19l-30.47-9.98L65.03 39l30.47 8.71-30.47 9.98z"/><path class="cls-1" d="M65.03 90.88L95.5 77.82V47.71l-30.47 9.98v33.19z"/></g></svg>

BIN
circle.png


+ 964 - 0
components/image-transform/index.js

@@ -0,0 +1,964 @@
+(() => {
+    // 初始地图
+    const initMap = (map) => {
+        let cacheCanvas
+        const ctrl = {
+            map,
+            async loadImage(args) {
+                ctrl.remove()
+                const { file, minWidth, minHeight } = args
+                args.img = args.img ?
+                    args.img :
+                    await blobImageLoad(file, minWidth, minHeight)
+
+                cacheCanvas = loadImageLayer(map, args)
+                return cacheCanvas
+            },
+            remove() {
+                if (cacheCanvas && cacheCanvas.__layer) {
+                    map.removeLayer(cacheCanvas.__layer)
+                }
+                cacheCanvas = null
+            },
+            screenToLatlan({ x, y }) {
+                const real = map.getCoordinateFromPixel([x, y])
+                    // const latlan = ol.proj.transform(real, 'EPSG:3857', 'EPSG:99999', 'EPSG:99999')
+                var latlan = proj4("EPSG:3857", "EPSG:4490", real);
+                return latlan
+            }
+        }
+        return ctrl
+    }
+
+    function toArray(quaternion) {
+        var rot90 = (new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0, 0, 1), THREE.Math.degToRad(-90)) //add 转入时旋转90度
+            ,
+            rot90Invert = rot90.clone().inverse() //add 转出时旋回90度
+        var t1 = quaternion.clone().multiply(rot90Invert);
+        var e = t1.toArray();
+        return [e[3], e[0], e[1], e[2]]
+    }
+
+    function getQuaternion(angle) { //angle:0-360 角度
+        var quaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, 0, THREE.Math.degToRad(-angle)));
+        return toArray(quaternion)
+
+    }
+
+    function getSize(imgWidth, scale) { //imgWidth:图片宽度, scale缩放值(x==y)
+        var level = imgWidth / 1024; //以1024为基准
+        return 95.54628610610962 * level * scale;
+    }
+
+
+    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.removeLayer(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
+        canvas.__layer = image
+        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-l03EZNS' : 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 })
+        },
+        updateTiled(data) {
+            return axios.put(`${root}/indoor/${sceneCode}/api/tiled_maps`, {
+                location: data.location,
+                map_size_m: data.map_size_m,
+                orientation: data.orientation,
+            })
+        },
+        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" v-show="false">
+          单文件:<input type="file" @change="imageChange" ref="updom">
+        </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="tr" :style="{left: box.tr.x + 'px', top: box.tr.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tr')"></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="rc" :style="{left: box.rc.x + 'px', top: box.rc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'rc')"></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="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="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
+
+
+            },
+            uploadTiled() {
+                return request.updateTiled(this.boxPos)
+            },
+            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
+                }
+            },
+            readyUpload() {
+                this.$refs.updom.click()
+            },
+        },
+        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])
+
+                    // 缩放,坐标,角度
+                    ret.map_size_m = getSize(this.imgCanvas.position[2], scale.x),
+                        ret.location = ret.cc,
+                        ret.orientation = getQuaternion(rotate)
+                    return ret
+                } else {
+                    return {}
+                }
+            },
+        },
+        destroyed() {
+            this.map.remove()
+        },
+        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.$nextTick(() => {
+                this.map = initMap(this.mapOl)
+
+            })
+        },
+    })
+})();

+ 205 - 0
components/upload-pointClound/index.js

@@ -0,0 +1,205 @@
+(() => {
+    Vue.component('uploadPointclound', {
+        props: [],
+        name: 'uploadPointclound',
+        template: `<div id="uploadBox" >
+                    <div class="headerBack">
+                        <div class="topBox">
+                            <i class="backIcon" @click="back"></i>
+                            <p class="headerTitle">添加数据集</p>
+                        </div>
+                    </div>
+                    
+                    <div class="selectBox">
+                        <el-select v-model="value" filterable @click.native="options = dataList" :filter-method="searchScene" placeholder="请选择">
+                            <el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id">
+                                <div class="sceneName">
+                                    <p class="code">{{item.title}}</p>
+                                    <span class="name">数据集:{{item.id}}</span>
+                                </div>
+
+                            </el-option>
+                        </el-select>
+
+                    </div>
+                    <div class="uploadBtn" @click="openUpload" :class="{disabled:value==''}">
+                        <i class="fa fa-plus ng-scope"></i>&nbsp;&nbsp;添加到场景
+                    </div>
+
+                    <p class="itemTitle">已添加的数据集 </p>
+                    <div class="listBox">
+                        <ul class="sceneList">
+                            <li class="sceneItem" v-for="i in hasList">
+                                <div class="sceneName">
+                                    <p class="code">{{i.mergeCode}}</p>
+                                    <span class="name">来自场景:{{i.title}}</span>
+                                </div>
+                                <div class="scene_control">
+                                   
+
+                                    <el-popconfirm placement="top" title="是否要删除该数据集?" :hide-icon="true" @confirm="delConfirm(i.mergeCode)">
+                                        <el-button class="delBtn" title="删除" slot="reference"></el-button>
+                                    </el-popconfirm>
+                                    <!-- <div class="delBtn" title="删除"></div> -->
+                                </div>
+                            </li>
+                        </ul>
+                    </div>
+
+                </div>`,
+        data() {
+            return {
+                dataList: [],
+                options: [],
+                hasList: [],
+                value: '',
+            }
+        },
+        methods: {
+
+            getSceneData() {
+                let params = {
+                    "pageNum": 0,
+                    "pageSize": 999,
+                    "searchKey": "",
+                }
+
+                axios({
+                    url: '/indoor/scene/list',
+                    method: 'post',
+                    data: params
+                }).then(res => {
+                    console.log(res)
+                    this.dataList = res.data.data.content
+                    this.options = res.data.data.content
+                }).catch(err => {
+
+                })
+            },
+            getHasSceneList() {
+                axios({
+                    url: `/indoor/${sceneNum}/api/merge/exist`,
+                    method: 'get',
+                }).then(res => {
+                    if (res.data.code == 0) {
+                        this.hasList = res.data.data
+                    }
+                }).catch(err => {
+
+                })
+            },
+            searchScene(e) {
+                console.log(e)
+                let res = this.dataList.filter(i => {
+                    if (i.id.indexOf(e) != -1 || i.title.indexOf(e) != -1) {
+                        return i
+                    }
+                })
+                console.log(res)
+                this.options = res
+
+            },
+            openUpload() {
+                // 
+                if (this.value != '') {
+                    this.$parent.showLoading('上传中...')
+                    let res = this.hasList.filter(i => {
+                        console.log(i.sceneNum)
+                        if (this.value == i.sceneNum) {
+                            return i
+                        }
+                    })
+                    if (res.length > 0) {
+                        this.$parent.hideLoading()
+                        this.$message({
+                            message: '请勿重复添加数据集',
+                            type: 'error',
+                            duration: 2000,
+                        });
+                        return
+
+                    }
+
+                    axios.post(`/indoor/${sceneNum}/api/merge/${this.value}`).then(res => {
+                        this.$parent.hideLoading()
+                        this.value = ''
+                        if (res.data.code == 0) {
+                            this.getHasSceneList()
+                            this.$message({
+                                message: '数据集添加成功,请点击左侧【数据集】查看',
+                                type: 'success',
+                                duration: 2000,
+                            });
+                            IV.api.AuthenticationService.sendAuthenticationChanged()
+                        } else if (res.data.code == 3005) {
+                            this.$message({
+                                message: '不可重复添加',
+                                type: 'error',
+                                duration: 2000,
+                            });
+                        } else {
+                            this.$message({
+                                message: '数据集添加失败,请重试',
+                                type: 'error',
+                                duration: 2000,
+                            });
+                        }
+
+                    }).catch(err => {
+                        this.value = ''
+                        this.$parent.hideLoading()
+                        this.$message({
+                            message: '数据集添加失败,请重试',
+                            type: 'error',
+                            duration: 2000,
+                        });
+
+                    })
+                }
+
+
+
+            },
+            delConfirm(mergeCode) {
+                axios({
+                    // url: `/indoor/${sceneNum}/api/merge/exist`,
+                    url: `/indoor/${sceneNum}/api/merge/remove/${mergeCode}`,
+                    method: 'get',
+                }).then(res => {
+                    if (res.data.code == 0) {
+                        this.getHasSceneList()
+                        this.$message({
+                            message: '数据集删除成功',
+                            type: 'success',
+                            duration: 2000,
+                        });
+                        IV.api.AuthenticationService.sendAuthenticationChanged()
+                    }
+                }).catch(err => {
+
+                })
+            },
+            back() {
+                this.$parent.showType = 0
+            }
+
+        },
+        computed: {
+
+        },
+        destroyed() {
+
+        },
+        mounted() {
+            // window.eventBus.off('openMap', openMap);
+            // window.eventBus.on('openMap', openMap);
+
+            // function openMap() {
+            //     IV.swapScenes()
+            // }
+
+            this.getSceneData()
+            this.getHasSceneList()
+        },
+    })
+})();

+ 307 - 0
components/upload-titlemap/index.js

@@ -0,0 +1,307 @@
+(() => {
+    Vue.component('uploadTitlemap', {
+        props: [],
+        name: 'uploadTitlemap',
+        template: ` <div id="planePic"">
+                    <div class="headerBack">
+                        <div class="topBox">
+                            <i class="backIcon" @click="back"></i>
+                            <p class="headerTitle">平面图</p>
+                        </div>
+                        <el-switch v-model="showMapPic" @change="changeDisplay" active-color="#15BEC8" inactive-color="#999">
+                        </el-switch>
+                    </div>
+                    <div class="defaultPic itemBox" :class="type==0 ?'active':''">
+                        <div class="ctrlBox">
+                            <div class="ctrlTitle">
+                                默认平面图
+                                <div class="tipBox" title="修改点云或数据集后,请更新平面图"></div>
+                            </div>
+                            <!-- <p>默认平面图</p> -->
+                            <el-popconfirm placement="top" title="确认重新生成平面图?" :hide-icon="true" @confirm="refreshConfirm">
+                                <el-button slot="reference">
+                                    <div class="ctrlBtn">
+                                        <i class="ctrlIcon refreshIcon"></i>
+                                        <p class="ctrlText">重新生成</p>
+
+
+                                    </div>
+                                </el-button>
+                            </el-popconfirm>
+
+                        </div>
+
+                    </div>
+                    <div class="diyPic itemBox " :class=" type==1  ?'active':''">
+                        <div class="ctrlBox">
+
+                            <p class="ctrlTitle">自定义平面图</p>
+                            <div class="btnBox">
+                            
+
+                                <div class="ctrlBtn" @click="downloadMap">
+                                    <i class="ctrlIcon downloadIcon"></i>
+                                    <p class="ctrlText">下载</p>
+
+                                </div>
+                                <label class="ctrlBtn" for="files">
+                                    <i class="ctrlIcon uploadIcon"></i>
+                                    <p class="ctrlText">上传</p>
+                                </label>
+
+
+                                <input type="file"  ref="files"  id="files" @change="uploadPic">
+                            </div>
+
+                        </div>
+
+                    </div>
+                    <div class="tipText">
+                        操作说明<br /> 1. 下载默认平面图,支持.png文件下载;<br /> 2.上传时,图片需与默认平面图图片大小、格式保持一致。<br />
+                    </div>
+                </div>`,
+        //删除
+        // <el-popconfirm placement="top" title="确认删除?" :hide-icon="true" @confirm="delConfirm">
+        //     <el-button slot="reference">
+        //         <div class="ctrlBtn">
+        //             <i class="ctrlIcon disableIcon "></i>
+        //             <p class="ctrlText">删除</p>
+
+        //         </div>
+        //     </el-button>
+        // </el-popconfirm>
+        data() {
+            return {
+                showMapPic: false,
+                info: {},
+                type: -1,
+                downloadUrl: 'https://laser.4dkankan.com/'
+            }
+        },
+        methods: {
+            downloadIamge(imgsrc, name) { //下载图片地址和图片名
+                let image = new Image();
+                // 解决跨域 Canvas 污染问题
+                image.setAttribute("crossOrigin", "anonymous");
+                image.onload = function () {
+                    let canvas = document.createElement("canvas");
+                    canvas.width = image.width;
+                    canvas.height = image.height;
+                    let context = canvas.getContext("2d");
+                    context.drawImage(image, 0, 0, image.width, image.height);
+                    let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
+                    let a = document.createElement("a"); // 生成一个a元素
+                    let event = new MouseEvent("click"); // 创建一个单击事件
+                    a.download = name || "photo"; // 设置图片名称
+                    a.href = url; // 将生成的URL设置为a.href属性
+                    a.dispatchEvent(event); // 触发a的单击事件
+                };
+                image.src = imgsrc;
+            },
+            downloadMap() {
+                axios.get(`/indoor/${sceneNum}/api/tiled_maps/download`).then(res => {
+                    // console.log(res)
+                    // console.log(this.downloadUrl + res.data.msg)
+
+                    if (res.data.code == 0) {
+                        var name = res.data.msg.split('/')[res.data.msg.split('/').length - 1]
+                        var file = this.downloadUrl + res.data.msg
+                        // console.log(name)
+                        this.downloadIamge(file, name)
+                        // window.location.href = this.downloadUrl + res.data.msg
+                    } else {
+                        this.$message({
+                            message: res.data.msg,
+                            type: 'error',
+                            duration: 2000,
+                        });
+                    }
+
+                }).catch(err => {
+                    this.$message({
+                        message: err.data.msg,
+                        type: 'error',
+                        duration: 2000,
+                    });
+
+                })
+
+            },
+            refreshConfirm() {
+                this.$parent.showLoading('更新中...')
+                axios.get(`/indoor/${sceneNum}/api/tiled_maps/init`).then(res => {
+                    // this.$parent.hideLoading()
+                    if (res.data.code == 0) {
+                        this.getDetaile()
+                        IV.api.AuthenticationService.sendAuthenticationChanged()
+                    } else {
+                        this.$parent.hideLoading()
+                        this.$message({
+                            message: res.data.msg,
+                            type: 'error',
+                            duration: 2000,
+                        });
+                    }
+
+                }).catch(err => {
+                    this.$parent.hideLoading()
+                    this.$message({
+                        message: err.data.msg,
+                        type: 'error',
+                        duration: 2000,
+                    });
+
+                })
+            },
+            changeDisplay(val) {
+                console.log(val)
+                if (val) {
+                    this.info.display = 1
+                } else {
+                    this.info.display = 0
+                }
+                this.$parent.showLoading('切换中...')
+                axios.get(`/indoor/${sceneNum}/api/tiled_maps/updateDisplay/${this.info.display}`).then(res => {
+
+                    if (res.data.code == 0) {
+
+                        IV.api.AuthenticationService.sendAuthenticationChanged()
+                    } else {
+                        this.$parent.hideLoading()
+                        this.$message({
+                            message: res.data.msg,
+                            type: 'error',
+                            duration: 2000,
+                        });
+                    }
+
+
+                }).catch(err => {
+                    this.$parent.hideLoading()
+                    this.$message({
+                        message: err.data.msg,
+                        type: 'error',
+                        duration: 2000,
+                    });
+
+                })
+            },
+
+            delConfirm() {
+                console.log('delConfirm')
+            },
+            isZip(file) {
+                return /\.(zip)$/.test(file.name)
+            },
+            uploadPic(e) {
+                let file = e.target.files[0]
+                console.log(file)
+                // if (!this.isZip(file)) {
+                //     this.$message({
+                //         message: '请上传zip格式',
+                //         type: 'error',
+                //         duration: 2000,
+                //     });
+                //     return
+                // }
+                let params = new FormData()
+                params.append('file', file)
+                this.$parent.showLoading('上传中...')
+
+                axios.post(`/indoor/${sceneNum}/api/tiled_maps/upload`, params).then(res => {
+                    let file = this.$refs.files
+                    file.value = ''
+                    if (res.data.code == 0) {
+
+
+                        this.$message({
+                            message: '上传成功',
+                            type: 'success',
+                            duration: 2000,
+                        });
+                        this.getDetaile()
+                        IV.api.AuthenticationService.sendAuthenticationChanged()
+                    } else {
+                        this.$parent.hideLoading()
+                        this.$message({
+                            message: res.data.msg,
+                            type: 'error',
+                            duration: 2000,
+                        });
+                    }
+
+                }).catch(err => {
+                    let file = this.$refs.file
+                    file.value = ''
+                    this.$parent.hideLoading()
+                    this.$message({
+                        message: err.data.msg,
+                        type: 'error',
+                        duration: 2000,
+                    });
+
+                })
+
+            },
+            back() {
+                this.$parent.showType = 0
+            },
+            getDetaile() {
+                axios.get(`/indoor/${sceneNum}/api/tiled_maps/detail`).then(res => {
+                    if (res.data.code == 0) {
+                        console.log(res.data.data)
+                        this.info = res.data.data
+                        this.type = this.info.status || 0
+                        if (this.info.display) {
+                            this.showMapPic = true
+                        } else {
+                            this.showMapPic = false
+                        }
+                    } else {
+                        this.$message({
+                            message: res.data.msg,
+                            type: 'error',
+                            duration: 1000,
+                        });
+                    }
+
+                }).catch(err => {
+                    this.$message({
+                        message: err.data.msg,
+                        type: 'error',
+                        duration: 1000,
+                    });
+
+                })
+            },
+            openMap() {
+                this.$parent.hideLoading()
+                if (IV.getMainView().ViewService.primaryView != 'map') {
+                    IV.swapScenes()
+                }
+            }
+
+        },
+        computed: {
+
+        },
+        destroyed() {
+            if (IV.getMainView().ViewService.primaryView == 'map') {
+                IV.swapScenes()
+            }
+        },
+        mounted() {
+            this.openMap()
+            window.eventBus.off('openMap', this.openMap);
+            window.eventBus.on('openMap', this.openMap);
+
+            // function openMap() {
+            //       this.$parent.hideLoading()
+            //     if (IV.getMainView().ViewService.primaryView != 'map') {
+            //         IV.swapScenes()
+            //     }
+            // }
+            this.getDetaile()
+        },
+    })
+})();

42358c64435fd5376879b55e8cd16a0d.cross_hair.png → cross_hair.png


File diff suppressed because it is too large
+ 15704 - 0
css/element.css


BIN
css/fonts/element-icons.ttf


BIN
css/fonts/element-icons.woff


File diff suppressed because it is too large
+ 524 - 128
css/style.css


81cf314660ee47ab9c04dc47bc26de4b.cursor_side.png → cursor_side.png


BIN
data/2/0/0.png


BIN
data/2/0/1.png


BIN
data/2/0/2.png


BIN
data/2/0/3.png


BIN
data/2/1/0.png


BIN
data/2/1/1.png


BIN
data/2/1/2.png


BIN
data/2/1/3.png


BIN
data/2/2/0.png


BIN
data/2/2/1.png


BIN
data/2/2/2.png


BIN
data/2/2/3.png


BIN
data/2/3/0.png


BIN
data/2/3/1.png


BIN
data/2/3/2.png


BIN
data/2/3/3.png


ee79da0466afec3b5f9771e2fe9e43d0.delete.png → delete.png


+ 503 - 0
dependencies/ckeditor_plugins/base64image/dialogs/base64image.js

@@ -0,0 +1,503 @@
+/*
+ * Created by ALL-INKL.COM - Neue Medien Muennich - 04. Feb 2014
+ * Licensed under the terms of GPL, LGPL and MPL licenses.
+ */
+CKEDITOR.dialog.add("base64imageDialog", function(editor){
+	
+	var t = null,
+		selectedImg = null,
+		orgWidth = null, orgHeight = null,
+		imgPreview = null, urlCB = null, urlI = null, fileCB = null, imgScal = 1, lock = true;
+	
+	/* Check File Reader Support */
+	function fileSupport() {
+		var r = false, n = null;
+		try {
+			if(FileReader) {
+				var n = document.createElement("input");
+				if(n && "files" in n) r = true;
+			}
+		} catch(e) { r = false; }
+		n = null;
+		return r;
+	}
+	var fsupport = fileSupport();
+	
+	/* Load preview image */
+	function imagePreviewLoad(s) {
+		
+		/* no preview */
+		if(typeof(s) != "string" || !s) {
+			imgPreview.getElement().setHtml("");
+			return;
+		}
+		
+		/* Create image */
+		var i = new Image();
+		
+		/* Display loading text in preview element */
+		imgPreview.getElement().setHtml("Loading...");
+		
+		/* When image is loaded */
+		i.onload = function() {
+			
+			/* Remove preview */
+			imgPreview.getElement().setHtml("");
+			
+			/* Set attributes */
+			if(orgWidth == null || orgHeight == null) {
+				t.setValueOf("tab-properties", "width", this.width);
+				t.setValueOf("tab-properties", "height", this.height);
+				imgScal = 1;
+				if(this.height > 0 && this.width > 0) imgScal = this.width / this.height;
+				if(imgScal <= 0) imgScal = 1;
+			} else {
+				orgWidth = null;
+				orgHeight = null;
+			}
+			this.id = editor.id+"previewimage";
+			this.setAttribute("style", "max-width:400px;max-height:100px;");
+			this.setAttribute("alt", "");
+			
+			/* Insert preview image */
+			try {
+				var p = imgPreview.getElement().$;
+				if(p) p.appendChild(this);
+			} catch(e) {}
+			
+		};
+		
+		/* Error Function */
+		i.onerror = function(){ imgPreview.getElement().setHtml(""); };
+		i.onabort = function(){ imgPreview.getElement().setHtml(""); };
+		
+		/* Load image */
+		i.src = s;
+	}
+	
+	/* Change input values and preview image */
+	function imagePreview(src){
+		
+		/* Remove preview */
+		imgPreview.getElement().setHtml("");
+		
+		if(src == "base64") {
+			
+			/* Disable Checkboxes */
+			if(urlCB) urlCB.setValue(false, true);
+			if(fileCB) fileCB.setValue(false, true);
+			
+		} else if(src == "url") {
+			
+			/* Ensable Image URL Checkbox */
+			if(urlCB) urlCB.setValue(true, true);
+			if(fileCB) fileCB.setValue(false, true);
+			
+			/* Load preview image */
+			if(urlI) imagePreviewLoad(urlI.getValue());
+			
+		} else if(fsupport) {
+			
+			/* Ensable Image File Checkbox */
+			if(urlCB) urlCB.setValue(false, true);
+			if(fileCB) fileCB.setValue(true, true);
+			
+			/* Read file and load preview */
+			var fileI = t.getContentElement("tab-source", "file");
+			var n = null;
+			try { n = fileI.getInputElement().$; } catch(e) { n = null; }
+			if(n && "files" in n && n.files && n.files.length > 0 && n.files[0]) {
+				if("type" in n.files[0] && !n.files[0].type.match("image.*")) return;
+				if(!FileReader) return;
+				imgPreview.getElement().setHtml("Loading...");
+				var fr = new FileReader();
+				fr.onload = (function(f) { return function(e) {
+					imgPreview.getElement().setHtml("");
+					imagePreviewLoad(e.target.result);
+				}; })(n.files[0]);
+				fr.onerror = function(){ imgPreview.getElement().setHtml(""); };
+				fr.onabort = function(){ imgPreview.getElement().setHtml(""); };
+				fr.readAsDataURL(n.files[0]);
+			}
+		}
+	};
+	
+	/* Calculate image dimensions */
+	function getImageDimensions() {
+		var o = {
+			"w" : t.getContentElement("tab-properties", "width").getValue(),
+			"h" : t.getContentElement("tab-properties", "height").getValue(),
+			"uw" : "px",
+			"uh" : "px"
+		};
+		if(o.w.indexOf("%") >= 0) o.uw = "%";
+		if(o.h.indexOf("%") >= 0) o.uh = "%";
+		o.w = parseInt(o.w, 10);
+		o.h = parseInt(o.h, 10);
+		if(isNaN(o.w)) o.w = 0;
+		if(isNaN(o.h)) o.h = 0;
+		return o;
+	}
+	
+	/* Set image dimensions */
+	function imageDimensions(src) {
+		var o = getImageDimensions();
+		var u = "px";
+		if(src == "width") {
+			if(o.uw == "%") u = "%";
+			o.h = Math.round(o.w / imgScal);
+		} else {
+			if(o.uh == "%") u = "%";
+			o.w = Math.round(o.h * imgScal); 
+		}
+		if(u == "%") {
+			o.w += "%";
+			o.h += "%";
+		}
+		t.getContentElement("tab-properties", "width").setValue(o.w),
+		t.getContentElement("tab-properties", "height").setValue(o.h)
+	}
+	
+	/* Set integer Value */
+	function integerValue(elem) {
+		var v = elem.getValue(), u = "";
+		if(v.indexOf("%") >= 0) u = "%";
+		v = parseInt(v, 10);
+		if(isNaN(v)) v = 0;
+		elem.setValue(v+u);
+	}
+	
+	if(fsupport) {
+		
+		/* Dialog with file and url image source */
+		var sourceElements = [
+			{
+				type: "hbox",
+				widths: ["70px"],
+				children: [
+					{
+						type: "checkbox",
+						id: "urlcheckbox",
+						style: "margin-top:5px",
+						label: editor.lang.common.url+":"
+					},
+					{
+						type: "text",
+						id: "url",
+						label: "",
+						onChange: function(){ imagePreview("url"); }
+					}
+				]
+			},
+			{
+				type: "hbox",
+				widths: ["70px"],
+				children: [
+					{
+						type: "checkbox",
+						id: "filecheckbox",
+						style: "margin-top:5px",
+						label: editor.lang.common.upload+":"
+					},
+					{
+						type: "file",
+						id: "file",
+						label: "",
+						onChange: function(){ imagePreview("file"); }
+					}
+				]
+			},
+			{
+				type: "html",
+				id: "preview",
+				html: new CKEDITOR.template("<div style=\"text-align:center;\"></div>").output()
+			}
+		];
+		
+	} else {
+		
+		/* Dialog with url image source */
+		var sourceElements = [
+			{
+				type: "text",
+				id: "url",
+				label: editor.lang.common.url,
+				onChange: function(){ imagePreview("url"); }
+			},
+			{
+				type: "html",
+				id: "preview",
+				html: new CKEDITOR.template("<div style=\"text-align:center;\"></div>").output()
+			}
+		];
+	}
+	
+	/* Dialog */
+    return {
+		title: editor.lang.common.image,
+        minWidth: 450,
+        minHeight: 180,
+		onLoad: function(){
+			
+			if(fsupport) {
+				
+				/* Get checkboxes */
+				urlCB = this.getContentElement("tab-source", "urlcheckbox");
+				fileCB = this.getContentElement("tab-source", "filecheckbox");
+				
+				/* Checkbox Events */
+				urlCB.getInputElement().on("click", function(){ imagePreview("url"); });
+				fileCB.getInputElement().on("click", function(){ imagePreview("file"); });
+				
+			}
+			
+			/* Get url input element */
+			urlI = this.getContentElement("tab-source", "url");
+			
+			/* Get image preview element */
+			imgPreview = this.getContentElement("tab-source", "preview");
+			
+			/* Constrain proportions or not */
+			this.getContentElement("tab-properties", "lock").getInputElement().on("click", function(){
+				if(this.getValue()) lock = true; else lock = false;
+				if(lock) imageDimensions("width");
+			}, this.getContentElement("tab-properties", "lock"));
+			
+			/* Change Attributes Events  */
+			this.getContentElement("tab-properties", "width").getInputElement().on("keyup", function(){ if(lock) imageDimensions("width"); });
+			this.getContentElement("tab-properties", "height").getInputElement().on("keyup", function(){ if(lock) imageDimensions("height"); });
+			this.getContentElement("tab-properties", "vmargin").getInputElement().on("keyup", function(){ integerValue(this); }, this.getContentElement("tab-properties", "vmargin"));
+			this.getContentElement("tab-properties", "hmargin").getInputElement().on("keyup", function(){ integerValue(this); }, this.getContentElement("tab-properties", "hmargin"));
+			this.getContentElement("tab-properties", "border").getInputElement().on("keyup", function(){ integerValue(this); }, this.getContentElement("tab-properties", "border"));
+			
+		},
+		onShow: function(){
+			
+			/* Remove preview */
+			imgPreview.getElement().setHtml("");
+			
+			t = this, orgWidth = null, orgHeight = null, imgScal = 1, lock = true;
+			
+			/* selected image or null */
+			selectedImg = editor.getSelection();
+			if(selectedImg) selectedImg = selectedImg.getSelectedElement();
+			if(!selectedImg || selectedImg.getName() !== "img") selectedImg = null;
+			
+			/* Set input values */
+			t.setValueOf("tab-properties", "lock", lock);
+			t.setValueOf("tab-properties", "vmargin", "0");
+			t.setValueOf("tab-properties", "hmargin", "0");
+			t.setValueOf("tab-properties", "border", "0");
+			t.setValueOf("tab-properties", "align", "none");
+			if(selectedImg) {
+				
+				/* Set input values from selected image */
+				if(typeof(selectedImg.getAttribute("width")) == "string") orgWidth = selectedImg.getAttribute("width");
+				if(typeof(selectedImg.getAttribute("height")) == "string") orgHeight = selectedImg.getAttribute("height");
+				if((orgWidth == null || orgHeight == null) && selectedImg.$) {
+					orgWidth = selectedImg.$.width;
+					orgHeight = selectedImg.$.height;
+				}
+				if(orgWidth != null && orgHeight != null) {
+					t.setValueOf("tab-properties", "width", orgWidth);
+					t.setValueOf("tab-properties", "height", orgHeight);
+					orgWidth = parseInt(orgWidth, 10);
+					orgHeight = parseInt(orgHeight, 10);
+					imgScal = 1;
+					if(!isNaN(orgWidth) && !isNaN(orgHeight) && orgHeight > 0 && orgWidth > 0) imgScal = orgWidth / orgHeight;
+					if(imgScal <= 0) imgScal = 1;
+				}
+				
+				if(typeof(selectedImg.getAttribute("src")) == "string") {
+					if(selectedImg.getAttribute("src").indexOf("data:") === 0) {
+						imagePreview("base64");
+						imagePreviewLoad(selectedImg.getAttribute("src"));
+					} else {
+						t.setValueOf("tab-source", "url", selectedImg.getAttribute("src"));
+					}
+				}
+				if(typeof(selectedImg.getAttribute("alt")) == "string") t.setValueOf("tab-properties", "alt", selectedImg.getAttribute("alt"));
+				if(typeof(selectedImg.getAttribute("hspace")) == "string") t.setValueOf("tab-properties", "hmargin", selectedImg.getAttribute("hspace"));
+				if(typeof(selectedImg.getAttribute("vspace")) == "string") t.setValueOf("tab-properties", "vmargin", selectedImg.getAttribute("vspace"));
+				if(typeof(selectedImg.getAttribute("border")) == "string") t.setValueOf("tab-properties", "border", selectedImg.getAttribute("border"));
+				if(typeof(selectedImg.getAttribute("align")) == "string") {
+					switch(selectedImg.getAttribute("align")) {
+						case "top":
+						case "text-top":
+							t.setValueOf("tab-properties", "align", "top");
+							break;
+						case "baseline":
+						case "bottom":
+						case "text-bottom":
+							t.setValueOf("tab-properties", "align", "bottom");
+							break;
+						case "left":
+							t.setValueOf("tab-properties", "align", "left");
+							break;
+						case "right":
+							t.setValueOf("tab-properties", "align", "right");
+							break;
+					}
+				}
+				t.selectPage("tab-properties");
+			}
+			
+		},
+		onOk : function(){
+			
+			/* Get image source */
+			var src = "";
+			try { src = CKEDITOR.document.getById(editor.id+"previewimage").$.src; } catch(e) { src = ""; }
+			if(typeof(src) != "string" || src == null || src === "") return;
+			
+			/* selected image or new image */
+			if(selectedImg) var newImg = selectedImg; else var newImg = editor.document.createElement("img");
+			newImg.setAttribute("src", src);
+			src = null;
+			
+			/* Set attributes */
+			newImg.setAttribute("alt", t.getValueOf("tab-properties", "alt").replace(/^\s+/, "").replace(/\s+$/, ""));
+			var attr = {
+				"width" : ["width", "width:#;", "integer", 1],
+				"height" : ["height", "height:#;", "integer", 1],
+				"vmargin" : ["vspace", "margin-top:#;margin-bottom:#;", "integer", 0],
+				"hmargin" : ["hspace", "margin-left:#;margin-right:#;", "integer", 0],
+				"align" : ["align", ""],
+				"border" : ["border", "border:# solid black;", "integer", 0]
+			}, css = [], value, cssvalue, attrvalue, k;
+			for(k in attr) {
+				
+				value = t.getValueOf("tab-properties", k);
+				attrvalue = value;
+				cssvalue = value;
+				unit = "px";
+				
+				if(k == "align") {
+					switch(value) {
+						case "top":
+						case "bottom":
+							attr[k][1] = "vertical-align:#;";
+							break;
+						case "left":
+						case "right":
+							attr[k][1] = "float:#;";
+							break;
+						default:
+							value = null;
+							break;
+					}
+				}
+				
+				if(attr[k][2] == "integer") {
+					if(value.indexOf("%") >= 0) unit = "%";
+					value = parseInt(value, 10);
+					if(isNaN(value)) value = null; else if(value < attr[k][3]) value = null;
+					if(value != null) {
+						if(unit == "%") {
+							attrvalue = value+"%";
+							cssvalue = value+"%";
+						} else {
+							attrvalue = value;
+							cssvalue = value+"px";
+						}
+					}
+				}
+				
+				if(value != null) {
+					newImg.setAttribute(attr[k][0], attrvalue);
+					css.push(attr[k][1].replace(/#/g, cssvalue));
+				}
+				
+			}
+			if(css.length > 0) newImg.setAttribute("style", css.join(""));
+			
+			/* Insert new image */
+			if(!selectedImg) editor.insertElement(newImg);
+			
+			/* Resize image */
+			if(editor.plugins.imageresize) editor.plugins.imageresize.resize(editor, newImg, 800, 800);
+			
+		},
+		
+		/* Dialog form */
+        contents: [
+            {
+                id: "tab-source",
+                label: editor.lang.common.generalTab,
+                elements: sourceElements
+            },
+            {
+                id: "tab-properties",
+                label: editor.lang.common.advancedTab,
+                elements: [
+                    {
+                        type: "text",
+                        id: "alt",
+                        label: editor.lang.base64image.alt
+                    },
+                    {
+						type: 'hbox',
+						widths: ["15%", "15%", "70%"],
+						children: [
+							{
+								type: "text",
+								width: "45px",
+								id: "width",
+								label: editor.lang.common.width
+							},
+							{
+								type: "text",
+								width: "45px",
+								id: "height",
+								label: editor.lang.common.height
+							},
+							{
+								type: "checkbox",
+								id: "lock",
+								label: editor.lang.base64image.lockRatio,
+								style: "margin-top:18px;"
+							}
+						]
+                    },
+					{
+						type: 'hbox',
+						widths: ["23%", "30%", "30%", "17%"],
+						style: "margin-top:10px;",
+						children: [
+							{
+								type: "select",
+								id: "align",
+								label: editor.lang.common.align,
+								items: [
+									[editor.lang.common.notSet, "none"],
+									[editor.lang.common.alignTop, "top"],
+									[editor.lang.common.alignBottom, "bottom"],
+									[editor.lang.common.alignLeft, "left"],
+									[editor.lang.common.alignRight, "right"]
+								]
+							},
+							{
+								type: "text",
+								width: "45px",
+								id: "vmargin",
+								label: editor.lang.base64image.vSpace
+							},
+							{
+								type: "text",
+								width: "45px",
+								id: "hmargin",
+								label: editor.lang.base64image.hSpace
+							},
+							{
+								type: "text",
+								width: "45px",
+								id: "border",
+								label: editor.lang.base64image.border
+							}
+						]
+					}
+                ]
+            }
+        ]
+    };
+});

+ 22 - 0
dependencies/ckeditor_plugins/insertsound/dialogs/insertsound.js

@@ -0,0 +1,22 @@
+CKEDITOR.dialog.add('insertsoundDialog', function(editor) {
+    return {
+        title: "Insert audio",
+        minWidth: 300,
+        minHeight: 150,
+        contents: [{
+            id: 'tab',
+            label: 'Settings',
+            elements: [{
+                type: 'text',
+                id: 'url',
+                label: 'Please enter an MP3 URL to insert:',
+                validate: CKEDITOR.dialog.validate.notEmpty("URL field cannot be empty.")
+            }]
+        }],
+        onOk: function() {
+            var string = '<audio controls><source src="' + this.getValueOf('tab', 'url') + '">';
+            string += 'Your browser does not support the audio element.</source></audio>';
+            editor.insertHtml(string);
+        }
+    };
+});

+ 3 - 3
dependencies/ckeditor_plugins/youtube/lang/zh.js

@@ -1,8 +1,8 @@
 CKEDITOR.plugins.setLang('youtube', 'zh', {
 CKEDITOR.plugins.setLang('youtube', 'zh', {
-    button: '嵌入 Youtube 影片',
-    title: '嵌入 Youtube 影片',
+    button: '嵌入影片',
+    title: '嵌入影片',
     txtEmbed: '貼上嵌入碼',
     txtEmbed: '貼上嵌入碼',
-    txtUrl: '貼上 Youtube 影片 URL',
+    txtUrl: '貼上影片 URL',
     txtWidth: '寬',
     txtWidth: '寬',
     txtHeight: '高',
     txtHeight: '高',
     txtResponsive: '使用自適應縮放模式 (忽略設定的長寬, 以寬為基準縮放)',
     txtResponsive: '使用自適應縮放模式 (忽略設定的長寬, 以寬為基準縮放)',

3ffd85dd86a402de1f828170c4c1777c.dot.png → dot.png


BIN
font/SourceHanSansCN-Bold.otf


BIN
font/SourceHanSansCN-Regular.otf


BIN
font/element-icons.ttf


BIN
font/element-icons.woff


d143aded330ea211e9040fdeaad9a887.free_area_sprite.png → free_area_sprite.png


583917ff154f83c6f7dc2a470a8e7a01.free_distance_sprite.png → free_distance_sprite.png


e2266fec7968df82769dcc02eb218d15.generic_poi.png → generic_poi.png


14e42f83c89495bc6eb91ae0af686e41.gridmap.png → gridmap.png


BIN
horizontal_area_polygon_sprite.png


fb3ab9c94f62cf131c6573f56f3b6a21.horizontal_area_rectangle_sprite.png → horizontal_area_rectangle_sprite.png


BIN
horizontal_distance_sprite.png


BIN
img/gangwan256.png


BIN
img/icon/disable-1.png


BIN
img/icon/disable-2.png


BIN
img/icon/download-1.png


BIN
img/icon/download-2.png


BIN
img/icon/icon_back.png


BIN
img/icon/icon_data@2_1.png


BIN
img/icon/icon_data@2x.png


BIN
img/icon/icon_element@2x.png


BIN
img/icon/icon_element@2x_1.png


+ 0 - 0
img/icon/icon_load_n.png


Some files were not shown because too many files changed in this diff