"use script"; //开发环境建议开启严格模式 (function (window, mars3d) { //创建widget类,需要继承BaseWidget class MyWidget extends mars3d.widget.BaseWidget { //外部资源配置 get resources() { return [ "/widgets/plot/js/getGraphicDefStyle.js", "./lib/kml/kml-geojson.js", //导出kml支持,不用kml时可以删除 "./lib/dom2img/dom-to-image.js", //字体标号使用到的div转img库,无此标号时可以删除 ]; } //弹窗配置 get view() { return { type: "window", url: "view.html", windowOptions: { width: 250, position: { top: 50, right: 5, bottom: 5, }, }, }; } //初始化[仅执行1次] create() { this.storageName = "mars3d_plot"; this.graphicGroupLayer = new mars3d.layer.GraphicGroupLayer({ name: this.config.name, pid: 99, //图层管理 中使用,父节点id defaultLayer: "默认分组", isRestorePositions: true, //在标绘和编辑结束时,是否将坐标还原为普通值,true: 停止编辑时会有闪烁,但效率要好些。 hasEdit: false, }); this.map.addLayer(this.graphicGroupLayer); var that = this; this.graphicGroupLayer.bindContextMenu([ { text: "删除对象", iconCls: "fa fa-trash-o", callback: function (e) { let graphic = e.graphic; if (graphic) { that.deleteEntity(graphic); } }, }, ]); //事件监听 this.graphicGroupLayer.on(mars3d.EventType.drawCreated, (e) => { this.showLayerTree(); var graphic = e.graphic; this.startEditing(graphic); }); //模型加载完成后事件 this.graphicGroupLayer.on(mars3d.EventType.load, (e) => { //console.log('gltf模型加载完成'); haoutil.loading.hide(); }); this.graphicGroupLayer.on(mars3d.EventType.editStart, (e) => { var graphic = e.graphic; this.startEditing(graphic); }); this.graphicGroupLayer.on(mars3d.EventType.editMovePoint, (e) => { var graphic = e.graphic; this.startEditing(graphic); }); this.graphicGroupLayer.on(mars3d.EventType.editRemovePoint, (e) => { var graphic = e.graphic; this.startEditing(graphic); }); this.graphicGroupLayer.on(mars3d.EventType.editStop, (e) => { var graphic = e.graphic; this.stopEditing(); this.sendSaveEntity(graphic); //保存数据 this.showLayerTree(); }); this.graphicGroupLayer.on(mars3d.EventType.updateAttr, (e) => { var graphic = e.graphic; //更新了名称 if (e.attr.name && this.viewWindow) { this.viewWindow.treeWork.updateNode(graphic); } }); this.sendGetList(); } //每个窗口创建完成后调用 winCreateOK(opt, result) { this.viewWindow = result; } //激活插件 activate() { this.graphicGroupLayer.hasEdit = true; } //释放插件 disable() { this.stopEditing(); this.graphicGroupLayer.stopDraw(); this.graphicGroupLayer.hasEdit = false; this.viewWindow = null; } getDefStyle(type) { return getGraphicDefStyle(type); } updateTemplateValues(url) { if (this.map.options.templateValues) { return mars3d.Util.template(url, this.map.options.templateValues); } else { return url; } } hasEdit(val) { this.graphicGroupLayer.hasEdit = val; } hasPopup(val) { if (val) { this.graphicGroupLayer.bindPopup( (event) => { let graphic = event.graphic; var html = mars3d.Util.getTemplateHtml({ title: "属性编辑", template: [ { field: "name", name: "名称" }, { field: "address", name: "地址" }, { field: "phone", name: "电话" }, { field: "remark", name: "备注", type: "textarea" }, { name: "确定", type: "button" }, ], attr: graphic.attr, edit: true, width: 190, }); return html; }, { onAdd: (event) => { let eleId = event.id, graphic = event.graphic; //popup的DOM添加到页面的回调方法 $("#" + eleId + " .mars3d-popup-btn").click((e) => { $("#" + eleId + " .mars3d-popup-edititem").each(function () { var val = $(this).val(); var key = $(this).attr("data-type"); graphic.attr[key] = val; }); this.graphicGroupLayer.closePopup(); }); }, onRemove: function (eleId, graphic) { //popup的DOM从页面移除的回调方法 }, anchor: [0, -20], } ); } else { this.graphicGroupLayer.unbindPopup(); } } //开始标记 startDraw(defval) { haoutil.loading.hide(); switch (defval.type) { default: break; case "model": //小模型 defval.drawShow = true; //模型点状对象绘制时,是否显示本身对象,可避免在3dtiles上拾取坐标存在问题。 haoutil.loading.show(); //LoadEnd后关闭 break; case "point": case "font-point": case "billboard": defval.drawShow = true; //模型点状对象绘制时,是否显示本身对象,可避免在3dtiles上拾取坐标存在问题。 break; } console.log("开始绘制", defval); this.graphicGroupLayer.startDraw(defval); } //结束绘制、等同双击完成绘制,比如手机端无法双击结束 endDraw() { this.graphicGroupLayer.endDraw(); } startEditingById(id) { var graphic = this.graphicGroupLayer.getGraphicById(id); if (graphic == null) { return; } graphic.flyTo(); this.graphicGroupLayer.startEditing(graphic); } startEditing(graphic) { clearTimeout(this.timeTik); if (this.viewWindow == null) { return; } var plotAttr = mars3d.widget.getClass("widgets/plotAttr/widget.js"); if (plotAttr && plotAttr.isActivate) { plotAttr.startEditing(graphic, graphic.coordinates); } else { mars3d.widget.activate({ uri: "widgets/plotAttr/widget.js", graphic: graphic, lonlats: graphic.coordinates, }); } } stopEditing() { this.timeTik = setTimeout(function () { mars3d.widget.disable("widgets/plotAttr/widget.js"); }, 200); } flyTo(target) { //参数解释:线面数据:scale控制边界的放大比例,点数据:radius控制视距距离 this.map.flyToGraphic(target, { scale: 1.9, radius: 1000 }); } //文件处理 getGeoJson(target) { if (target) { return target.toGeoJSON(); } else { return this.graphicGroupLayer.toGeoJSON(); } } downloadJson(filename, target) { var data = this.getGeoJson(target); if (data == null || (data.features && data.features.length == 0)) { haoutil.msg("当前未标绘任何数据!"); } else { var timestr = new Date().format("MMddHHmmss"); haoutil.file.downloadFile(filename + "_" + timestr + ".json", JSON.stringify(data)); } } toKml(target) { var geojsonObject = this.getGeoJson(target); if (geojsonObject == null) { return null; } geojsonObject = haoutil.system.clone(geojsonObject); var kml = kgUtil.toKml(geojsonObject, { name: "Mars3D标绘数据", documentName: "Mars3D标绘数据文件", documentDescription: "标绘数据 by mars3d.cn", simplestyle: true, }); return kml; } downloadKml(filename, target) { var data = this.toKml(target); if (data == null) { haoutil.msg("当前未标绘任何数据!"); } else { var timestr = new Date().format("MMddHHmmss"); haoutil.file.downloadFile(filename + "_" + timestr + ".kml", data); } } loadGeoJSON(json, options) { if (json == null) { return; } var arr = this.graphicGroupLayer.loadGeoJSON(json, options); //本地存储 var geojson = JSON.stringify(json); haoutil.storage.add(this.storageName, geojson); this.showLayerTree(); return arr; } deleteAll() { this.stopEditing(); this.graphicGroupLayer.clear(); this.sendDeleteAll(); this.showLayerTree(); } deleteEntity(graphic) { graphic.remove(); this.sendDeleteEntity(graphic); //保存数据 this.showLayerTree(); } //搜索 query(text, maxcount) { var arrGraphic = this.graphicGroupLayer.getGraphics(); var arr = []; var counts = 0; for (var i = 0; i < arrGraphic.length; i++) { var graphic = arrGraphic[i]; var name; if (graphic.type == "label") { name = graphic.text; } else if (graphic.attr?.name) { name = graphic.attr.name; } if (name == null || name.indexOf(text) == -1) { continue; } arr.push({ name: name, type: "标绘 - " + name, _datatype: "plot", _entity: graphic, }); if (maxcount) { counts++; if (counts > maxcount) { break; } } } return arr; } //弹窗属性编辑处理 // showEditAttrWindow(param) { // this.last_window_param = param // layer.open({ // type: 2, // title: '选择数据', // fix: true, // shadeClose: false, // maxmin: true, // area: ['100%', '100%'], // content: 'test.html?name=' + param.attrName + '&value=' + param.attrVal, // skin: 'layer-mars-dialog animation-scale-up', // success: function (layero) {}, // }) // } // saveWindowEdit(attrVal) { // this.viewWindow.plotEdit.updateAttr(this.last_window_param.parname, this.last_window_param.attrName, attrVal) // layer.close(layer.index) // } //分组树相关方法 showLayerTree() { if (!this.viewWindow || !this.isActivate) { return; } this.viewWindow.treeWork.loadData(this.graphicGroupLayer.getLayers()); this.sendSaveEntity(); //保存所有数据 } checkRemoveGroup(layer) { if (this.graphicGroupLayer.length < 2) { haoutil.msg("不能删除所有图层,需要至少保留1个图层!"); return false; } return true; } deleteLayer(layer) { var result = this.graphicGroupLayer.deleteLayer(layer); if (result) { this.showLayerTree(); haoutil.msg("删除成功!"); return true; } else { haoutil.msg("删除失败!"); return false; } } //删除所有非空数组 deleteEmptyLayer() { if (this.graphicGroupLayer.length < 2) { haoutil.msg("不能删除所有图层,需要至少保留1个图层!"); return; } this.graphicGroupLayer.deleteEmptyLayer(); this.showLayerTree(); } editGroupName(layer) { mars3d.widget.activate({ uri: "widgets/plotGroupName/widget.js", name: layer ? "重命名分组" : "新增分组", data: layer ? layer.name : "", checkName: (newname) => { //校验分组是否有同名的 return this.graphicGroupLayer.hasLayer(newname, layer); }, callback: (newname) => { // console.log(newname) if (layer) { //修改 layer.name = newname; } else { //新增 this.graphicGroupLayer.createLayer(newname); } this.showLayerTree(); }, }); } changeSelectedLayer(layer) { this.graphicGroupLayer.selectedLayer = layer; this.showLayerTree(); } moveToLayer(graphic, group) { this.graphicGroupLayer.moveToLayer(graphic, group); this.showLayerTree(); } //数据保存及加载处理 sendGetList() { if (window.hasServer) { //读取后台存储 // window.sendAjax({ // url: 'map/plot/list', // type: 'get', // success: (arr) => { // var arrjson = [] // for (var i = 0; i < arr.length; i++) { // var geojson = JSON.parse(arr[i].geojson) // geojson.properties.id = arr[i].id // arrjson.push(geojson) // } // this.loadGeoJSON({ type: 'FeatureCollection', features: arrjson }, { clear: true, flyTo: true }) // }, // }) } else { //读取本地存储 var laststorage = haoutil.storage.get(this.storageName); //读取localStorage值 if (laststorage == null || laststorage == "null") { this.loadDemoData(); } else { var json = JSON.parse(laststorage); console.log("加载历史缓存数据", json); this.loadGeoJSON(json, { clear: true, flyTo: true }); } } } sendSaveEntity(graphic) { if (this.viewWindow == null) { return; } console.log("plot: 保存了数据"); if (window.hasServer) { //服务端存储 // if (!graphic.attr.name) { // haoutil.msg('名称不可为空!') // return // } // let geojson = graphic.toGeoJSON() // window.sendAjax({ // url: 'map/plot/update', // type: 'post', // data: { // id: graphic.id, // name: graphic.attr.name || '', //名称 // geojson: geojson || '', //geojson // }, // contentType: 'application/json', // success: function (data) { // graphic.id = data.id // }, // }) } else { //本地存储 var geojson = JSON.stringify(this.getGeoJson()); haoutil.storage.add(this.storageName, geojson); } //测试的功能 //this.sendSocket(graphic) } sendDeleteEntity(graphic) { // console.log('plot: 删除了数据') if (window.hasServer) { //后台删除 // window.sendAjax({ // url: 'map/plot/' + graphic.id, // type: 'delete', // contentType: 'application/json', // success: function (result) {}, // }) } else { var storagedata = JSON.stringify(this.getGeoJson()); haoutil.storage.add(this.storageName, storagedata); } } sendDeleteAll() { // console.log('plot: 删除了所有数据') if (window.hasServer) { //后台删除 // window.sendAjax({ // url: 'map/plot/deleteAll', // contentType: 'application/json', // success: function (result) {}, // }) } else { //本地存储 haoutil.storage.del(this.storageName); } } //websocket更新坐标 // socketConfig() { // var that = this // mars3d.widget.activate({ // uri: 'widgets/plotSocket/widget.js', // updateAttr: function (json) { // that.graphicGroupLayer.loadGeoJSON(json) // }, // }) // } // sendSocket(graphic) { // var plotSocket = mars3d.widget.getClass('widgets/plotSocket/widget.js') // if (plotSocket && plotSocket.isActivate) { // plotSocket.sendSocket(graphic.toGeoJSON()) // } // } //实际系统时可以注释下面代码,该代码是mars3d官网在线加载演示数据 loadDemoData() { if (window.location.hostname.indexOf("mars") == -1) { return; } $.getJSON("//data.mars3d.cn/file/geojson/mars3d-draw.json", (result) => { if (!this.isActivate) { return; } this.loadGeoJSON(result, { clear: true, flyTo: true }); }); } } //注册到widget管理器中。 mars3d.widget.bindClass(MyWidget); //每个widet之间都是直接引入到index.html中,会存在彼此命名冲突,所以闭包处理下。 })(window, mars3d);