Browse Source

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

xushiting 4 years ago
parent
commit
c0dccee70c

+ 1 - 1
17.82bbf60e16d46d39aea0.js

@@ -2807,7 +2807,7 @@
             2 & e) {
             2 & e) {
                 var n = p.ɵɵnextContext().$implicit;
                 var n = p.ɵɵnextContext().$implicit;
                 p.ɵɵadvance(1),
                 p.ɵɵadvance(1),
-                p.ɵɵtextInterpolate(n("Please contact your 4dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately."))
+                p.ɵɵtextInterpolate(n("Please contact your 4Dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately."))
             }
             }
         }
         }
         function I(e, t) {
         function I(e, t) {

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


+ 112 - 1
css/style.css

@@ -957,6 +957,10 @@ form[role="form"] .panel .panel-body label.btn-block {
     display: none;
     display: none;
 }
 }
 
 
+form[role="form"] .form-group button[ng-click="vm.save()"] {
+    background-color: #15BEC8;
+}
+
 form[class="ng-valid ng-dirty ng-valid-parse"] .panel.panel-default {
 form[class="ng-valid ng-dirty ng-valid-parse"] .panel.panel-default {
     border-color: rgba(255, 255, 255, .2);
     border-color: rgba(255, 255, 255, .2);
 }
 }
@@ -1160,7 +1164,7 @@ measurement-list .fa-square-o:before {
 }
 }
 
 
 measurement-list .hovered {
 measurement-list .hovered {
-    background-color: #15BEC8 !important;
+    background-color: #143537 !important;
 }
 }
 
 
 measurement-list hr {
 measurement-list hr {
@@ -1282,4 +1286,111 @@ results-element .checkbox,
 
 
 .dropdown-menu-search-results.dropdown-menu.dropdown-menu-item-separators>li:not(.divider):not(:last-child) {
 .dropdown-menu-search-results.dropdown-menu.dropdown-menu-item-separators>li:not(.divider):not(:last-child) {
     border-bottom: 1px solid rgba(255, 255, 255, .2);
     border-bottom: 1px solid rgba(255, 255, 255, .2);
+}
+
+
+/* PDF */
+
+.cdk-overlay-container mat-dialog-container .mat-dialog-title {
+    color: #fff;
+}
+
+.cdk-overlay-container mat-dialog-container .body-container .link-ellipses span.ng-star-inserted {
+    color: #fff;
+}
+
+.cdk-overlay-container mat-dialog-container .body-container i[class="material-icons icn-small clickable"] {
+    color: #fff;
+}
+
+.cdk-overlay-container mat-dialog-container {
+    background: rgba(0, 0, 0, .8);
+}
+
+.cdk-overlay-container mat-dialog-container .measurement-container {
+    background: #141414 !important;
+}
+
+.cdk-overlay-container mat-dialog-container .measurement-container .flex-row {
+    color: #fff;
+}
+
+.cdk-overlay-container mat-dialog-container .measurement-container .flex-row .subtitle {
+    color: #fff;
+    margin-bottom: 22px;
+}
+
+.cdk-overlay-container mat-dialog-container .measurement-container .location {
+    color: #fff;
+}
+
+.cdk-overlay-container mat-dialog-container .measurement-container .location img {
+    width: 16px;
+    height: 16px;
+    margin-right: 10px;
+}
+
+.cdk-overlay-container .mat-flat-button {
+    border-radius: 4px;
+    border: 1px solid #15BEC8;
+    background: transparent;
+    color: #15BEC8;
+}
+
+.cdk-overlay-container mat-dialog-actions .mat-flat-button.mat-primary {
+    background: #15BEC8;
+}
+
+.cdk-overlay-container mat-dialog-container .mat-dialog-content::-webkit-scrollbar {
+    width: 8px;
+}
+
+.cdk-overlay-container mat-dialog-container .mat-dialog-content::-webkit-scrollbar-track {
+    background-color: #000;
+    -webkit-border-radius: 1em;
+    -moz-border-radius: 1em;
+    border-radius: 1em;
+}
+
+.cdk-overlay-container mat-dialog-container .mat-dialog-content::-webkit-scrollbar-thumb {
+    background-color: rgba(255, 255, 255, .2);
+    -webkit-border-radius: 1em;
+    -moz-border-radius: 1em;
+    border-radius: 1em;
+}
+
+
+/*  导出XML */
+
+#xmlExport button.form-control {
+    border: none;
+    background: #15BEC8 !important;
+}
+
+
+/* 右键兴趣点 */
+
+.context-menu-list {
+    background: rgba(0, 0, 0, 0.5) !important;
+    border: none !important;
+}
+
+.context-menu-item {
+    background: transparent !important;
+    color: #fff !important;
+}
+
+.context-menu-item:hover {
+    background: #15BEC8 !important;
+}
+
+.context-menu-item.context-menu-icon:before {
+    color: #fff !important;
+}
+
+
+/* 多语言 */
+
+translation-editor[selected-language="selectedLanguage"] .form-group:first-of-type {
+    display: none;
 }
 }

BIN
e2266fec7968df82769dcc02eb218d15.generic_poi.png


+ 22 - 304
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,31 +162,10 @@
                 </div>
                 </div>
             </div>
             </div>
             <div class="rightBox">
             <div class="rightBox">
-                <div id="map" class="map">
-                    <div class="plane1">
-                        <!-- 文件路径:<input type="text" id="filePath" value="./img/gangwan256.png" /><button
-                            id="upload">上传</button><br> -->
-
-                        上传地图:<input type="file" id="file" name="file" multiple="multiple" @change="handleFileChange">
-                        <br> 位置(左上角):
-                        <br> 经度:
-                        <input type="text" id="lon" v-model="uploadData.lon" /><br> 纬度:
-                        <input type="text" id="lat" v-model="uploadData.lat" /><br> 朝向(顺时针为正):
-                        <input type="text" id="direction" v-model="uploadData.direction" /><br> 大小:
-                        <input type="text" id="size" v-model="uploadData.size" /><br>
-                        <!-- <button id="ok" @click="getImage">确定</button> -->
-                        <button id="drug" @click="onDrawImage">
-                            <span v-if="!isDraw">开启拖拽</span>
-                            <span v-if="isDraw">关闭拖拽</span>
-                        </button>
-                        <button id="rotate" @click="onRotate">
-                            <span v-if="!isRotate">开启旋转</span>
-                            <span v-if="isRotate">关闭旋转</span>
-                        </button>
-                        <button id="save" @click="onSave">保存</button>
-                    </div>
+                <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>
@@ -193,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>
@@ -204,7 +185,7 @@
                 return {
                 return {
 
 
                     pointLayerArray: [],
                     pointLayerArray: [],
-                    map: {},
+                    map: null,
                     gaodeMapLayer: {},
                     gaodeMapLayer: {},
                     ax: '',
                     ax: '',
                     ay: '',
                     ay: '',
@@ -257,7 +238,7 @@
 
 
                 this.map = this.initMap('map');
                 this.map = this.initMap('map');
 
 
-
+                console.log(this.map)
 
 
 
 
 
 
@@ -265,6 +246,11 @@
 
 
             },
             },
             methods: {
             methods: {
+                getImageTransform() {
+                    // 地图数据上传  如果用户没有选择数据直接返回true  如果有数据要上传返回promise
+                    console.log(this.$refs.imageTranform)
+                    return this.$refs.imageTranform.uploadData()
+                },
                 initMap(divid) {
                 initMap(divid) {
                     this.pointLayerArray = [];
                     this.pointLayerArray = [];
                     this.gaodeMapLayer = new ol.layer.Tile({
                     this.gaodeMapLayer = new ol.layer.Tile({
@@ -369,9 +355,9 @@
                 },
                 },
 
 
                 commit() {
                 commit() {
-
                     this.handleData()
                     this.handleData()
-                    axios.post('/indoor/' + this.sceneNum + '/api/controlPoint/save', {
+                    Promise.all([
+                        axios.post('/indoor/' + this.sceneNum + '/api/controlPoint/save', {
                             ageControlLocation1: this.ageControlLocation1,
                             ageControlLocation1: this.ageControlLocation1,
                             ageControlLocation2: this.ageControlLocation2,
                             ageControlLocation2: this.ageControlLocation2,
                             gpsControlCoordinate1: this.gpsControlCoordinate1,
                             gpsControlCoordinate1: this.gpsControlCoordinate1,
@@ -379,288 +365,20 @@
                             sceneNum: this.sceneNum,
                             sceneNum: this.sceneNum,
                             // id: 1
                             // id: 1
                         })
                         })
-                        .then(function(response) {
-                            alert('成功')
-                        })
                         .catch(function(error) {
                         .catch(function(error) {
-                            alert('失败')
-                        });
-                },
-                handleFileChange(e) {
-                    const input = e.target;
-                    const files = e.target.files;
-                    if (files && files[0]) {
-                        const file = files[0];
-                        // onload 里面不能用this
-                        this.imgSrc = window.URL.createObjectURL(file);
-                        let img = new Image();
-                        img.src = this.imgSrc;
-                        let self = this;
-                        img.onload = function() {
-                            console.log(img.width, img.height)
-                            if (img.width < self.limitSize || img.height < self.limitSize) {
-                                alert('图片宽高需要大于512')
-                                input.value = '';
-                                return false;
-                            } else if (img.width != img.height) {
-                                alert('图片比例必须为1:1')
-                                input.value = '';
-                                return false;
-                            } else {
-
-                                self.file = file
-                                self.uploadData.size = img.width
-                                self.getImage()
-                            }
-                        };
-                    }
-
-                },
-                getImage() {
-                    let lon = document.getElementById("lon").value;
-                    let lat = document.getElementById("lat").value;
-                    let direction = document.getElementById("direction").value;
-                    // let url = document.getElementById("filePath").value;
-                    let url = this.imgSrc;
-                    this.showSmallMap(+lon, +lat, +direction, url)
-                },
-
-                onDrawImage() {
-                    let self = this
-                    this.isRotate = false
-                    this.rotateObj && this.rotateObj.close();
-                    this.isDraw = !this.isDraw
-                    if (this.isDraw) {
-                        this.drugObj = new Drug(canvas, ctx, img);
-                        this.drugObj.open();
-                    } else {
-                        this.drugObj.close();
-                    }
-
-                    /**
-                     * canvas 原生拖拽
-                     **/
-                    function Drug(canvas, ctx, img) {
-                        //这里禁用底图拖拽
-                        self.setMapDragPan(false)
-                        let oldX, oldY, allMoveX = 0,
-                            allMoveY = 0;
-                        canvas.draggable = false; //禁用原生拖拽
-                        let onmousedown = function(evt) {
-                            oldX = evt.x;
-                            oldY = evt.y;
-                            document.addEventListener("mousemove", onmousemove);
-                        }
-                        let onmousemove = function(evt) {
-                            if (!isNaN(oldX - evt.x)) {
-                                ctx.clearRect(0, 0, canvas.width, canvas.height);
-                                allMoveX = allMoveX + evt.x - oldX;
-                                allMoveY = allMoveY + evt.y - oldY;
-                                ctx.translate(evt.x - oldX, evt.y - oldY);
-                                self.drawImage(canvas, ctx, img);
-                                oldX = evt.x;
-                                oldY = evt.y;
-                                imageCanvas.refresh();
-                            }
-                        }
-                        let onmouseup = function(evt) {
-                            document.removeEventListener("mousemove", onmousemove);
-                        }
-                        this.open = function() {
-                            document.addEventListener("mousedown", onmousedown);
-                            document.addEventListener("mousemove", onmousemove);
-                            document.addEventListener("mouseup", onmouseup);
-                        }
-                        this.close = function() {
-                            document.removeEventListener("mousedown", onmousedown);
-                            document.removeEventListener("mousemove", onmousemove);
-                            document.removeEventListener("mouseup", onmouseup);
-                            self.setMapDragPan(true) //打开底图拖拽
-                        }
-                        this.getMoveXY = function() {
-                            this.moveX = allMoveX;
-                            this.moveY = allMoveY;
-                            return [this.moveX, this.moveY]
-                        }
-
-                        return this;
-                    }
-                },
-
-
-                onRotate() {
-                    let self = this
-                    this.isDraw = false
-                    this.drugObj && this.drugObj.close();
-                    this.isRotate = !this.isRotate
-
-                    if (this.isRotate) {
-                        this.rotateObj = new Rotate(canvas, ctx, img);
-                        this.rotateObj.open();
-                    } else {
-                        this.rotateObj.close();
-                    }
-
-
-
-                    /**
-                     * canvas 原生旋转
-                     **/
-                    function Rotate(canvas, ctx, img) {
-                        //这里禁用底图拖拽
-                        self.setMapDragPan(false)
-                        let oldX, oldY, angle = 0,
-                            angleAll = 0;
-                        canvas.draggable = false; //禁用原生拖拽
-                        let onmousedown = function(evt) {
-                            oldX = evt.x;
-                            oldY = evt.y;
-                            document.addEventListener("mousemove", onmousemove);
-                        }
-                        let onmousemove = function(evt) {
-                            if (!isNaN(oldX - evt.x)) {
-                                ctx.clearRect(0, 0, canvas.width, canvas.height);
-                                let tana = (oldY - evt.y) / (evt.x - oldX);
-                                angle = 0.02 * Math.atan(tana);
-                                angleAll = angleAll + angle;
-                                ctx.translate(128, 128);
-                                ctx.rotate(angle);
-                                ctx.translate(-128, -128);
-                                self.drawImage(canvas, ctx, img)
-                                imageCanvas.refresh();
-                            }
-                        }
-                        let onmouseup = function(evt) {
-                            document.removeEventListener("mousemove", onmousemove);
-                        }
-                        this.open = function() {
-                            document.addEventListener("mousedown", onmousedown);
-                            document.addEventListener("mousemove", onmousemove);
-                            document.addEventListener("mouseup", onmouseup);
-                        }
-                        this.close = function() {
-                            document.removeEventListener("mousedown", onmousedown);
-                            document.removeEventListener("mousemove", onmousemove);
-                            document.removeEventListener("mouseup", onmouseup);
-                            self.setMapDragPan(true) //打开底图拖拽
-                        }
-                        this.getAngle = function() {
-                            this.angle = angleAll
-                            return this.angle;
-                        }
-                        return this;
-                    }
-                },
-
-                onSave() {
-                    let lon = document.getElementById("lon").value;
-                    let lat = document.getElementById("lat").value;
-                    let direction = document.getElementById("direction").value;
-                    let size = document.getElementById("size").value;
-                    this.save(+lon, +lat, +direction, +size, this.drugObj, this.rotateObj)
-                },
-
-                showSmallMap(lon, lat, direction, imageUrl) {
-                    let canvasOption = {};
-                    let isFirst = true;
-                    canvasOption.canvasFunction = (extent, resolution, pixelRatio, size, projection) => {
-                        if (isFirst) {
-                            isFirst = false;
-                            canvas = document.createElement('canvas');
-                            canvas.width = size[0];
-                            canvas.height = size[1];
-                            //Canvas四至范围不同于当前地图四至范围,计算出南北方向与东西方向的偏移
-                            let mapExtent = this.map.getView().calculateExtent(this.map
-                                .getSize()); //当前底图视图范围的投影坐标
-                            let canvasOrigin = this.map.getPixelFromCoordinate([extent[0], extent[
-                                3]]); //添加到地图上的canvas图像的左上角
-                            let mapOrigin = this.map.getPixelFromCoordinate([mapExtent[0], mapExtent[3]]);
-                            let delta = [mapOrigin[0] - canvasOrigin[0], mapOrigin[1] - canvasOrigin[1]];
-                            let leftTop = this.map.getPixelFromCoordinate(ol.proj.fromLonLat([lon, lat]));
-                            //canvas原生加载图片
-                            ctx = canvas.getContext('2d');
-                            img = new Image();
-                            img.src = imageUrl;
-                            img.onload = () => {
-                                ctx.translate(leftTop[0] + delta[0], leftTop[1] + delta[1])
-                                ctx.translate(128, 128)
-                                ctx.rotate(direction * (Math.PI / 180))
-                                ctx.translate(-128, -128)
-                                this.drawImage(canvas, ctx, img)
-                            }
-                            return canvas;
-                        }
-                    }
-                    imageCanvas = new ol.source.ImageCanvas(canvasOption);
-                    imageCanvasLayer = new ol.layer.Image({
-                        source: imageCanvas
-                    });
-                    this.map.addLayer(imageCanvasLayer);
-                    this.map.getView().setCenter(ol.proj.fromLonLat([lon, lat]));
-                    this.map.getView().setZoom(19)
-                },
-
-                save(lon, lat, direction, size, drugObj, rotateObj) {
-                    let saveLonLat, saveAngle;
-                    if (drugObj) {
-                        let moveXY = drugObj.getMoveXY();
-                        let leftTop = this.map.getPixelFromCoordinate(ol.proj.fromLonLat([lon, lat]));
-                        let pixelX = moveXY[0] + leftTop[0];
-                        let pixelY = moveXY[1] + leftTop[1];
-                        saveLonLat = this.map.getCoordinateFromPixel([pixelX, pixelY]);
-                        saveLonLat = ol.proj.toLonLat(saveLonLat);
-
-                    } else {
-                        saveLonLat = [lon, lat]
-                    }
-                    if (rotateObj) {
-                        saveAngle = rotateObj.getAngle() * 180 / Math.PI + Number(direction);
-
-                    } else {
-                        saveAngle = direction
-                    }
-                    let save = {
-                        lonlat: saveLonLat,
-                        angle: saveAngle,
-                        size: size
-                    }
-                    console.log(save) //保存到数据库去
-
+                            alert('数据集位置上传失败')
+                        }),
 
 
-                    let location = saveLonLat;
-                    if (location.length == 2) {
-                        location.push(0)
-                    }
-                    let formData = new FormData()
-                    formData.append('file', this.file)
-                    formData.append('location', location)
-                    formData.append('orientation', saveAngle)
-                        // formData.append('sceneCode', this.sceneNum)
-                        // formData.append('sceneCode', 't810')
-                    axios.post('indoor/' + this.sceneNum + '/api/map/upload', formData)
-                        // axios.post('http://192.168.0.135:9294/indoor/t810/api/map/upload', formData)
-                        .then(function(response) {
-                            alert('成功')
+                        this.getImageTransform()
+                        .catch(_ => {
+                            alert('地图数据上传失败')
                         })
                         })
-                        .catch(function(error) {
-                            alert('失败')
-                        });
-
-                },
-
-
+                    ]).then(() => {
+                        alert('成功')
+                    })
 
 
-                drawImage(canvas, ctx, img) {
-                    ctx.clearRect(0, 0, canvas.width, canvas.height);
-                    ctx.drawImage(img, 0, 0); //canvas 从左上角开始绘制
                 },
                 },
 
 
-                setMapDragPan(bool) {
-                    this.map.getInteractions().forEach(function(element, index, array) {
-                        if (element instanceof ol.interaction.DragPan)
-                            element.setActive(bool);
-                    });
-                }
 
 
             }
             }
         })
         })

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

@@ -0,0 +1,824 @@
+(() => {
+    // 初始地图
+    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 canvas = document.createElement('canvas')
+    const loadImage = (map, args, itude) => {
+        console.log('create 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) => {
+        const analysis = (blob) => new Promise((resolve, reject) => {
+            const url = typeof blob !== 'string' ?
+                window.URL.createObjectURL(blob) :
+                blob
+            const img = new Image()
+
+            img.onload = () => {
+                if (img.width < minWidth || img.height < minHeight) {
+                    reject('图片宽高需要大于512')
+                } else {
+                    resolve([img, url, blob])
+                }
+            }
+            img.src = url
+        })
+
+        let arrasPromises = []
+        for (let images of arrayImages) {
+            let analys = []
+            for (let bolb of images) {
+                analys.push(analysis(bolb))
+            }
+            arrasPromises.push(
+                Promise.all(analys)
+            )
+        }
+
+        return Promise.all(arrasPromises)
+    }
+
+
+    // 获取逆转矩阵
+    const getCanvasInverImatrix = $canvas => {
+        const ctx = $canvas.getContext('2d')
+        const transform = ctx.getTransform()
+        return transform.invertSelf();
+    }
+
+    // canvas坐标转屏幕坐标
+    const getCanvasToScreenPos = ($canvas, { x, y }) => {
+        const {
+            a,
+            b,
+            c,
+            d,
+            e,
+            f
+        } = getCanvasInverImatrix($canvas)
+
+        const screenX = (c * y - d * x + d * e - c * f) / (b * c - a * d)
+        const screenY = (y - screenX * b - f) / d
+
+        return {
+            x: Math.round(screenX),
+            y: Math.round(screenY),
+        }
+    }
+
+    // 屏幕坐标转canvas坐标
+    const getScreenToCanvasPos = ($canvas, { x, y }) => {
+        const {
+            a,
+            b,
+            c,
+            d,
+            e,
+            f
+        } = getCanvasInverImatrix($canvas)
+
+        return {
+            x: Math.round(x * a + y * c + e),
+            y: Math.round(x * b + y * d + f)
+        };
+    }
+
+
+    const sceneName = window.location.pathname.split('/')[2]
+    const isDev = !sceneName || sceneName === 'addDataSet.html'
+
+    const sceneCode = isDev ? 't-kJ2PEjZ' : window.location.pathname.split('/')[2]
+    const root = isDev ? `https://testlaser.4dkankan.com` : ''
+        // const root = 'http://192.168.0.135:9294'
+    const request = {
+        uploadFiles(files) {
+            const fromData = new FormData()
+            files.forEach(({ dir, file }) => {
+                fromData.append(dir, file)
+            })
+            return axios({
+                headers: { 'Content-Type': 'multipart/form-data' },
+                method: 'POST',
+                data: fromData,
+                url: `${root}/indoor/${sceneCode}/api/mapSmall/upload`
+            })
+        },
+        getDetail() {
+            return axios.post(`${root}/indoor/${sceneCode}/api/mapSmall/detail`)
+        },
+        updateCoord(data) {
+            return axios.post(
+                `${root}/indoor/${sceneCode}/api/update/coord`, { param: data }
+            )
+        },
+        getSceneInfo() {
+            return axios.get(`${root}/indoor/${sceneCode}/api/datasets`)
+        }
+    }
+
+    const analysisFiles = (files) => {
+            const imagesArray = []
+            const formatError = () => {
+                alert('目录不规范 请上传 z/x/y.png 格式目录,且在最底级目录放置图片文件')
+            }
+
+            let imagesXYZ = {}
+            for (let dir in files) {
+                let file = files[dir]
+                let locals = dir.split(/[\\|//]/)
+                if (locals.length < 3) return formatError()
+                let current = imagesXYZ
+                for (let i = 0; i < locals.length; i++) {
+                    let dir = locals[i]
+
+                    if (i !== locals.length - 1) {
+                        if (!current[dir]) {
+                            current[dir] = i === locals.length - 2 ? [] : {}
+                        }
+                        current = current[dir]
+
+                        if (i === locals.length - 3) {
+                            current.key = 'z'
+                        }
+                    }
+
+                    if (i === locals.length - 1) {
+                        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))
+                )
+            })
+
+            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="move"  @mouseup="upMove">
+        <div class="upload-layer">
+         
+          单文件:<input type="file" @change="imageChange">
+        </div>
+        <div class="ctrls" :style="boxStyle" @mousedown.stop.prevent="startMove($event, 'move')"></div>
+        <div class="cctrls" v-if="box.tl">
+          <span class="tl" :style="{left: box.tl.x + 'px', top: box.tl.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tl')"></span>
+          <span class="tc" :style="{left: box.tc.x + 'px', top: box.tc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tc')"></span>
+          <span class="tr" :style="{left: box.tr.x + 'px', top: box.tr.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'tr')"></span>
+          <span class="rc" :style="{left: box.rc.x + 'px', top: box.rc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'rc')"></span>
+          <span class="lc" :style="{left: box.lc.x + 'px', top: box.lc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'lc')"></span>
+          <span class="br" :style="{left: box.br.x + 'px', top: box.br.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'br')"></span>
+          <span class="bl" :style="{left: box.bl.x + 'px', top: box.bl.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'bl')"></span>
+          <span class="bc" :style="{left: box.bc.x + 'px', top: box.bc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'scale', 'bc')"></span>
+          <span class="cc" :style="{left: box.cc.x + 'px', top: box.cc.y + 'px'}" @mousedown.prevent.stop="startMove($event, 'rotate')"></span>
+        </div>
+        <div class="box-info" v-if="boxPos.tl">
+          <div v-for="(item, key) in boxPos" :key="key">
+            <span>{{key}}</span>
+            <span>{{item}}</span>
+          </div>
+        </div>
+      </div>
+    `,
+        data() {
+            return {
+                isHover: false,
+                box: {},
+                left: 0,
+                top: 0
+            }
+        },
+        methods: {
+            imageChange(e) {
+                const files = e.target.files;
+                if (files && files[0]) {
+                    const file = files[0];
+                    // onload 里面不能用this
+                    let img = new Image();
+                    img.src = window.URL.createObjectURL(file);
+                    img.onload = async() => {
+                        if (img.width % 256 == 0 && img.height % 256 == 0) {
+                            let imagesArray = []
+
+                            if (e.target.files.length > 1) {
+                                const files = {}
+                                for (let file of e.target.files) {
+                                    files[file.webkitRelativePath] = file
+                                }
+                                imagesArray = analysisFiles(files)
+                            } else {
+                                imagesArray = [
+                                    [e.target.files[0]]
+                                ]
+                            }
+                            if (this.imgCanvas) {
+                                ctx = this.imgCanvas.getContext('2d')
+                                ctx.clearRect(-10000, -10000, 10000, 10000)
+                            }
+                            this.imgCanvas.imageLayer.refresh()
+                            await this.drawCanvas(imagesArray, [], {
+                                lat: this.lat,
+                                lon: this.lon
+                            })
+                        } else {
+                            alert('图片宽高需为256的倍数')
+                        }
+                    };
+                }
+
+
+
+            },
+            async drawCanvas(imagesArray, transfroms, { lat, lon } = {}) {
+                try {
+                    this.transfroms = transfroms || []
+                    this.args = {
+                        draw: (ctx) => {
+                            this.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) {
+                    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
+
+
+            },
+            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) {
+                    promises.push(
+                        request.uploadFiles(files)
+                    )
+                }
+
+                promises.push(
+                    request.updateCoord({
+                        ...this.boxPos,
+                        transfroms: this.transfroms
+                    })
+                )
+                return Promise.all(promises)
+            },
+            getInfo() {
+                return {
+                    pos: this.boxPos,
+                    img: this.args.img
+                }
+            }
+        },
+        computed: {
+            boxStyle() {
+                if (this.box && Object.keys(this.box).length) {
+                    const box = this.box
+                    return {
+                        width: box.width + 20 + 'px',
+                        height: box.height + 20 + 'px',
+                        left: box.cc.x + 'px',
+                        top: box.cc.y + 'px'
+                    }
+                } else {
+                    return {}
+                }
+            },
+            boxPos() {
+                if (this.box && Object.keys(this.box).length) {
+                    const ret = {}
+                    for (let key in this.box) {
+                        if (key !== 'width' && key !== 'height') {
+                            ret[key] = this.map.screenToLatlan(this.box[key])
+                        }
+                    }
+                    return ret
+                } else {
+                    return {}
+                }
+            }
+        },
+        mounted() {
+            Promise.all([
+                request.getDetail(),
+                request.getSceneInfo()
+            ]).then(async([res1, res2]) => {
+                const {
+                    path,
+                    position
+                } = res1.data.data
+                const { location } = res2.data[0]
+
+                if (path && path.length > 0) {
+                    const files = {}
+                    path.forEach(path => (files[path] = root + path))
+                    await this.drawCanvas(
+                        analysisFiles(files),
+                        position ? position.transfroms : [], {
+                            lat: location[1],
+                            lon: location[0],
+                        }
+                    )
+                }
+
+                this.lat = location[1]
+                this.lon = location[0]
+            })
+
+            document.documentElement.addEventListener('mousemove', ev => {
+                ev.stopPropagation()
+                ev.preventDefault()
+                this.moveHandle.bind(this)(ev)
+                this.move.bind(this)(ev)
+            })
+            document.documentElement.addEventListener('mousedown', ev => {
+                this.mapStartHandle.bind(this)(ev)
+            })
+            document.documentElement.addEventListener('mouseup', ev => {
+                ev.stopPropagation()
+                ev.preventDefault()
+                this.upMove.bind(this)()
+            })
+            this.map = initMap(this.mapOl)
+
+        }
+    })
+})();

+ 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);
+  }

+ 4 - 4
translations/json/en.json

@@ -11,7 +11,7 @@
   "Upload Data": "Upload Data",
   "Upload Data": "Upload Data",
   "Upload recorded data": "Upload recorded data",
   "Upload recorded data": "Upload recorded data",
   "or drop files here": "or drop files here",
   "or drop files here": "or drop files here",
-  "Connect the SSD from a 4dkankan device and drag-and-drop your datasets_rec folder or the dataset folder here to start": "Connect the SSD from a 4dkankan device and drag-and-drop your datasets_rec folder or the dataset folder here to start",
+  "Connect the SSD from a 4Dkankan device and drag-and-drop your datasets_rec folder or the dataset folder here to start": "Connect the SSD from a 4Dkankan device and drag-and-drop your datasets_rec folder or the dataset folder here to start",
   "You are about to delete the dataset {datasetName}.": "You are about to delete the dataset {datasetName}.",
   "You are about to delete the dataset {datasetName}.": "You are about to delete the dataset {datasetName}.",
   "You are about to delete {count} datasets.": "You are about to delete {count} datasets.",
   "You are about to delete {count} datasets.": "You are about to delete {count} datasets.",
   "This operation cannot be undone.": "This operation cannot be undone.",
   "This operation cannot be undone.": "This operation cannot be undone.",
@@ -144,19 +144,19 @@
   "The depth maps are used in panorama mode by the cursor to visualize the distance of an object to the current position. The improved depth maps allow you to capture and measure details in the panoramas more accurately.": "The depth maps are used in panorama mode by the cursor to visualize the distance of an object to the current position. The improved depth maps allow you to capture and measure details in the panoramas more accurately.",
   "The depth maps are used in panorama mode by the cursor to visualize the distance of an object to the current position. The improved depth maps allow you to capture and measure details in the panoramas more accurately.": "The depth maps are used in panorama mode by the cursor to visualize the distance of an object to the current position. The improved depth maps allow you to capture and measure details in the panoramas more accurately.",
   "The update may take a while, but during this time you will be still able use the measurement mode.": "The update may take a while, but during this time you will be still able use the measurement mode.",
   "The update may take a while, but during this time you will be still able use the measurement mode.": "The update may take a while, but during this time you will be still able use the measurement mode.",
   "Do you want to start the update?": "Do you want to start the update?",
   "Do you want to start the update?": "Do you want to start the update?",
-  "Please contact your 4dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately.": "Please contact your 4dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately.",
+  "Please contact your 4Dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately.": "Please contact your 4Dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately.",
   "Magnifier": "Magnifier",
   "Magnifier": "Magnifier",
   "Open ID group mapping": "Open ID group mapping",
   "Open ID group mapping": "Open ID group mapping",
   "Create these groups in your OIDC system of record ensuring you create a mapper to a claim array matching your selector in BOTH your identity and access tokens.": "Create these groups in your OIDC system of record ensuring you create a mapper to a claim array matching your selector in BOTH your identity and access tokens.",
   "Create these groups in your OIDC system of record ensuring you create a mapper to a claim array matching your selector in BOTH your identity and access tokens.": "Create these groups in your OIDC system of record ensuring you create a mapper to a claim array matching your selector in BOTH your identity and access tokens.",
   "Your administrator may then assign membership within the OIDC system of record. Users will have the rights and privileges assigned to members of that group when they log in.": "Your administrator may then assign membership within the OIDC system of record. Users will have the rights and privileges assigned to members of that group when they log in.",
   "Your administrator may then assign membership within the OIDC system of record. Users will have the rights and privileges assigned to members of that group when they log in.": "Your administrator may then assign membership within the OIDC system of record. Users will have the rights and privileges assigned to members of that group when they log in.",
-  "4dkankan Groups": "4dkankan Groups",
+  "4Dkankan Groups": "4Dkankan Groups",
   "Export CSV": "Export CSV",
   "Export CSV": "Export CSV",
   "Export JSON": "Export JSON",
   "Export JSON": "Export JSON",
   "Add processed data": "Add processed data",
   "Add processed data": "Add processed data",
   "to dataset management": "to dataset management",
   "to dataset management": "to dataset management",
   "Dataset management": "Dataset management",
   "Dataset management": "Dataset management",
   "Upload & Process": "Upload & Process",
   "Upload & Process": "Upload & Process",
-  "your 4dkankan data": "your 4dkankan data",
+  "your 4Dkankan data": "your 4Dkankan data",
   "Cloud processing": "Cloud processing",
   "Cloud processing": "Cloud processing",
   "Today": "Today",
   "Today": "Today",
   "Yesterday": "Yesterday",
   "Yesterday": "Yesterday",

+ 3 - 3
translations/json/zh.json

@@ -21,7 +21,7 @@
   "Upload Data": "上传数据",
   "Upload Data": "上传数据",
   "Upload recorded data": "上传所记录的数据",
   "Upload recorded data": "上传所记录的数据",
   "or drop files here": "或将文件拖到这里",
   "or drop files here": "或将文件拖到这里",
-  "Connect the SSD from a 4dkankan device and drag-and-drop your datasets_rec folder or the dataset folder here to start": "从4dkankan设备连接SSD,将您的datasets_rec文件夹或数据集文件夹拖放到这里,以便开始",
+  "Connect the SSD from a 4Dkankan device and drag-and-drop your datasets_rec folder or the dataset folder here to start": "从4Dkankan设备连接SSD,将您的datasets_rec文件夹或数据集文件夹拖放到这里,以便开始",
   "Download Processed Data": "下载所处理的数据",
   "Download Processed Data": "下载所处理的数据",
   "Please select the file of {datasetName} you want to download": "请选择您想下载的{datasetName}文件",
   "Please select the file of {datasetName} you want to download": "请选择您想下载的{datasetName}文件",
   "Colored point cloud {fileExtension}": "彩色点云{fileExtension}",
   "Colored point cloud {fileExtension}": "彩色点云{fileExtension}",
@@ -72,12 +72,12 @@
   "The depth maps are used in panorama mode by the cursor to visualize the distance of an object to the current position. The improved depth maps allow you to capture and measure details in the panoramas more accurately.": "深度图通过光标用于全景模式,以使对象与当前位置的距离可视化。经过改进的深度图可使您更精确地捕捉和测量全景图像中的细节。",
   "The depth maps are used in panorama mode by the cursor to visualize the distance of an object to the current position. The improved depth maps allow you to capture and measure details in the panoramas more accurately.": "深度图通过光标用于全景模式,以使对象与当前位置的距离可视化。经过改进的深度图可使您更精确地捕捉和测量全景图像中的细节。",
   "The update may take a while, but during this time you will be still able use the measurement mode.": "更新可能需要一段时间,但在此期间,您仍能使用测量模式。",
   "The update may take a while, but during this time you will be still able use the measurement mode.": "更新可能需要一段时间,但在此期间,您仍能使用测量模式。",
   "Do you want to start the update?": "您要开始更新吗?",
   "Do you want to start the update?": "您要开始更新吗?",
-  "Please contact your 4dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately.": "请联系您的4dkankan管理员以更新您的数据。更新将使您能够更准确地捕捉和测量全景图像的细节。",
+  "Please contact your 4Dkankan administrator to update your data. The update will allow you to capture and measure details in the panoramas more accurately.": "请联系您的4Dkankan管理员以更新您的数据。更新将使您能够更准确地捕捉和测量全景图像的细节。",
   "Magnifier": "放大镜",
   "Magnifier": "放大镜",
   "Open ID group mapping": "打开ID组映射",
   "Open ID group mapping": "打开ID组映射",
   "Create these groups in your OIDC system of record ensuring you create a mapper to a claim array matching your selector in BOTH your identity and access tokens.": "在您的OIDC记录系统中创建这些组,确保您创建一个声明数组的映射器,而该声明数组是与标识和访问令牌中的选择器匹配的。",
   "Create these groups in your OIDC system of record ensuring you create a mapper to a claim array matching your selector in BOTH your identity and access tokens.": "在您的OIDC记录系统中创建这些组,确保您创建一个声明数组的映射器,而该声明数组是与标识和访问令牌中的选择器匹配的。",
   "Your administrator may then assign membership within the OIDC system of record. Users will have the rights and privileges assigned to members of that group when they log in.": "然后,您的管理员可以在OIDC记录系统中分配成员资格。用户在登录时将拥有分配给该组成员的权利和特权。",
   "Your administrator may then assign membership within the OIDC system of record. Users will have the rights and privileges assigned to members of that group when they log in.": "然后,您的管理员可以在OIDC记录系统中分配成员资格。用户在登录时将拥有分配给该组成员的权利和特权。",
-  "4dkankan Groups": "4dkankan组",
+  "4Dkankan Groups": "4Dkankan组",
   "Export CSV": "导出CSV",
   "Export CSV": "导出CSV",
   "Export JSON": "导出JSON",
   "Export JSON": "导出JSON",
   "Today": "今天",
   "Today": "今天",

File diff suppressed because it is too large
+ 1 - 1
translations/zh.json