"use script" //开发环境建议开启严格模式
// 在图层绑定Popup弹窗
function bindLayerPopup2() {
graphicLayer.bindPopup(
function (event) {
const attr = getAttrForEvent(event)
attr["类型"] = event.graphic?.type
attr["来源"] = "我是layer上绑定的Popup"
attr["备注"] = "我支持鼠标交互"
return mars3d.Util.getTemplateHtml({ title: "矢量图层", template: "all", attr: attr })
// return new Promise((resolve) => {
// //这里可以进行后端接口请求数据,setTimeout测试异步
// setTimeout(() => {
// resolve('Promise异步回调显示的弹窗内容信息')
// }, 2000)
// })
},
{ pointerEvents: true }
)
}
// 绑定右键菜单
function bindLayerContextMenu2() {
graphicLayer.bindContextMenu([
{
text: "开始编辑对象",
icon: "fa fa-edit",
show: function (e) {
const graphic = e.graphic
if (!graphic || !graphic.hasEdit) {
return false
}
return !graphic.isEditing
},
callback: (e) => {
const graphic = e.graphic
if (!graphic) {
return false
}
if (graphic) {
graphicLayer.startEditing(graphic)
}
}
},
{
text: "停止编辑对象",
icon: "fa fa-edit",
show: function (e) {
const graphic = e.graphic
if (!graphic || !graphic.hasEdit) {
return false
}
return graphic.isEditing
},
callback: (e) => {
const graphic = e.graphic
if (!graphic) {
return false
}
if (graphic) {
graphic.stopEditing()
}
}
},
{
text: "删除对象",
icon: "fa fa-trash-o",
show: (event) => {
const graphic = event.graphic
if (!graphic || graphic.isDestroy) {
return false
} else {
return true
}
},
callback: (e) => {
const graphic = e.graphic
if (!graphic) {
return
}
const parent = graphic.parent // 右击是编辑点时
graphicLayer.removeGraphic(graphic)
if (parent) {
graphicLayer.removeGraphic(parent)
}
}
},
{
text: "计算长度",
icon: "fa fa-medium",
show: function (e) {
const graphic = e.graphic
if (!graphic) {
return false
}
return (
graphic.type === "polyline" ||
graphic.type === "polylineP" ||
graphic.type === "curve" ||
graphic.type === "curveP" ||
graphic.type === "polylineVolume" ||
graphic.type === "polylineVolumeP" ||
graphic.type === "corridor" ||
graphic.type === "corridorP" ||
graphic.type === "wall" ||
graphic.type === "wallP"
)
},
callback: (e) => {
const graphic = e.graphic
const strDis = mars3d.MeasureUtil.formatDistance(graphic.distance)
haoutil.alert("该对象的长度为:" + strDis)
}
},
{
text: "计算周长",
icon: "fa fa-medium",
show: function (e) {
const graphic = e.graphic
if (!graphic) {
return false
}
return (
graphic.type === "circle" ||
graphic.type === "circleP" ||
graphic.type === "rectangle" ||
graphic.type === "rectangleP" ||
graphic.type === "polygon" ||
graphic.type === "polygonP"
)
},
callback: (e) => {
const graphic = e.graphic
const strDis = mars3d.MeasureUtil.formatDistance(graphic.distance)
haoutil.alert("该对象的周长为:" + strDis)
}
},
{
text: "计算面积",
icon: "fa fa-reorder",
show: function (e) {
const graphic = e.graphic
if (!graphic) {
return false
}
return (
graphic.type === "circle" ||
graphic.type === "circleP" ||
graphic.type === "rectangle" ||
graphic.type === "rectangleP" ||
graphic.type === "polygon" ||
graphic.type === "polygonP" ||
graphic.type === "scrollWall" ||
graphic.type === "water"
)
},
callback: (e) => {
const graphic = e.graphic
const strArea = mars3d.MeasureUtil.formatArea(graphic.area)
haoutil.alert("该对象的面积为:" + strArea)
}
}
])
}
function getAttrForEvent(event) {
if (event?.graphic?.attr) {
return event.graphic.attr
}
if (!event.czmObject) {
return {}
}
let attr = event.czmObject._attr || event.czmObject.properties || event.czmObject.attribute
if (attr && attr.type && attr.attr) {
attr = attr.attr // 兼容历史数据,V2内部标绘生产的geojson
}
return attr ?? {}
}
// ***************************** 数据测试 *********************** //
// 生成大数据
function onClickAddRandomGraohic(count) {
haoutil.loading.show()
const startTime = new Date().getTime()
const result = addRandomGraphicByCount(count)
haoutil.loading.close()
const endTime = new Date().getTime()
const usedTime = (endTime - startTime) / 1000 // 两个时间戳相差的毫秒数
window.layer.msg(`生成${result || count}条数据,共耗时${usedTime.toFixed(2)}秒`)
graphicLayer.flyTo({ duration: 0, heading: 0, pitch: -40, scale: 1.2 })
}
// ***************************** 数据导出 *********************** //
// 打开geojson
function onClickImpFile(file) {
let fileName = file.name
let fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length).toLowerCase()
if (fileType == "json" || fileType == "geojson") {
let reader = new FileReader()
reader.readAsText(file, "UTF-8")
reader.onloadend = function (e) {
let geojson = JSON.parse(this.result)
if (geojson.type == "graphic" && geojson.data) {
graphicLayer.addGraphic(geojson.data)
graphicLayer.flyTo()
} else {
geojson = simplifyGeoJSON(geojson) //简化geojson的点
graphicLayer.loadGeoJSON(geojson, { flyTo: true })
}
clearSelectFile()
refreshTabel(graphicLayer)
}
} else if (fileType == "kml") {
let reader = new FileReader()
reader.readAsText(file, "UTF-8")
reader.onloadend = function (e) {
let strkml = this.result
kgUtil.toGeoJSON(strkml).then((geojson) => {
geojson = simplifyGeoJSON(geojson) //简化geojson的点
console.log("kml2geojson", geojson)
graphicLayer.loadGeoJSON(geojson, {
flyTo: true
})
clearSelectFile()
})
clearSelectFile()
}
} else if (fileType == "kmz") {
//加载input文件控件的二进制流
kgUtil.toGeoJSON(file).then((geojson) => {
geojson = simplifyGeoJSON(geojson) //简化geojson的点
console.log("kmz2geojson", geojson)
graphicLayer.loadGeoJSON(geojson, {
flyTo: true
})
clearSelectFile()
})
} else {
window.layer.msg("暂不支持 " + fileType + " 文件类型的数据!")
clearSelectFile()
}
}
function clearSelectFile() {
if (!window.addEventListener) {
document.getElementById("input_draw_file").outerHTML += "" //IE
} else {
document.getElementById("input_draw_file").value = "" //FF
}
}
//简化geojson的坐标
function simplifyGeoJSON(geojson) {
try {
geojson = turf.simplify(geojson, { tolerance: 0.000001, highQuality: true, mutate: true })
} catch (e) {
//
}
return geojson
}
// 保存geojson
function expGeoJSONFile() {
if (graphicLayer.length === 0) {
window.layer.msg("当前没有标注任何数据,无需保存!")
return
}
let geojson = graphicLayer.toGeoJSON()
haoutil.file.downloadFile("矢量数据GeoJSON.json", JSON.stringify(geojson))
}
// 保存json
function expJSONFile() {
if (graphicLayer.length === 0) {
window.layer.msg("当前没有标注任何数据,无需保存!")
return
}
const geojson = graphicLayer.toJSON()
mars3d.Util.downloadFile("矢量数据构造参数.json", JSON.stringify(geojson))
}
// ***************************** 属性面板 *********************** //
// 绑定事件,激活属性面板
function bindAttributePannel() {
// 初始化表格数据
if ($("#graphicTable")) {
graphicLayer.readyPromise.then(function (layer) {
getTableData(graphicLayer)
})
}
graphicLayer.on(mars3d.EventType.drawCreated, function (e) {
let val = $("#hasEdit").is(":checked")
if (val) {
showEditor(e)
}
})
// 修改了矢量数据
graphicLayer.on(
[
mars3d.EventType.editStart,
mars3d.EventType.editStyle,
mars3d.EventType.editAddPoint,
mars3d.EventType.editMovePoint,
mars3d.EventType.editRemovePoint
],
function (e) {
showEditor(e)
}
)
// 停止编辑
graphicLayer.on([mars3d.EventType.editStop, mars3d.EventType.removeGraphic], function (e) {
setTimeout(() => {
if (!graphicLayer.isEditing) {
stopEditing()
}
}, 100)
})
}
//附加:激活属性编辑widget【非必需,可以注释该方法内部代码】
let timeTik
function showEditor(e) {
const graphic = e.graphic
clearTimeout(timeTik)
if (!graphic._conventStyleJson) {
graphic.options.style = graphic.toJSON().style //因为示例中的样式可能有复杂对象,需要转为单个json简单对象
graphic._conventStyleJson = true //只处理一次
}
let plotAttr = es5widget.getClass("widgets/plotAttr/widget.js")
if (plotAttr && plotAttr.isActivate) {
plotAttr.startEditing(graphic, graphic.coordinates)
} else {
// 左侧没有弹出的修改面板时,弹出widget
$("#infoview-left").length === 0 &&
es5widget.activate({
map: map,
uri: "widgets/plotAttr/widget.js",
name: "属性编辑",
graphic: graphic,
lonlats: graphic.coordinates
})
}
}
function stopEditing() {
timeTik = setTimeout(function () {
if (es5widget) {
es5widget.disable("widgets/plotAttr/widget.js")
}
}, 200)
}
//附加:激活属性编辑widget【非必需,可以注释该方法内部代码】
// ***************************** 数据列表 *********************** //
let tableEventTarget = new mars3d.BaseClass()
function tableInit(data) {
$("#graphicTable").bootstrapTable({
data: data,
pagination: true,
pageList: [3, 5, 10],
singleSelect: false,
checkboxHeader: false,
columns: [
{
title: "是否显示",
field: "show",
align: "center",
checkbox: true,
width: 50,
formatter: function (value, row, index) {
return {
checked: true
}
}
},
{
field: "name",
title: "名称"
},
{
title: "操作",
align: "center",
width: 80,
events: {
"click .remove": function (e, value, row, index) {
const graphic = graphicLayer.getGraphicById(row.id)
graphicLayer.removeGraphic(graphic)
if ($("#infoview-left").length > 0) {
$("#infoview-left").hide()
}
},
"click .edit": function (e, value, row, index) {
const graphic = graphicLayer.getGraphicById(row.id)
// const graphic = getGraphic(row.id)
// 矢量数据不能处于编辑状态,否则点光源示例点击编辑时会失去光
// graphic.hasEdit && graphic.startEditing()
if ($("#infoview-left").length > 0) {
$("#infoview-left").show()
} else {
showEditor({ graphic })
}
}
},
formatter: function (value, row, index) {
return [
' ',
''
].join("")
}
}
],
//定位区域
onClickRow: function (row) {
flyToTableItem(row.id)
},
//勾选显示
onCheck: function (row) {
onSelectTableItem(row.id, true)
},
//取消勾选显示
onUncheck: function (row) {
onSelectTableItem(row.id, false)
}
})
}
// 更新表格数据
function refreshTabel(layer) {
const newData = getDataByLayer(layer)
$("#graphicTable").bootstrapTable("load", newData)
}
// 删除表格中的指定项
function removeTableItem(id) {
$("#graphicTable").bootstrapTable("remove", { field: "id", values: id })
}
// tableEventTarget.on("graphicList", function (event) {
// tableInit(event.graphicList)
// })
// tableEventTarget.on("removeGraphic", function (event) {
// removeTableItem(event.graphicId)
// })
function flyToTableItem(id) {
const graphic = graphicLayer.getGraphicById(id)
if (graphic) {
graphic.flyTo()
}
}
function onSelectTableItem(id, selected) {
const graphic = graphicLayer.getGraphicById(id)
if (!graphic) {
return
}
if (selected) {
graphic.show = true
graphic.flyTo()
} else {
graphic.show = false
}
}
// 获取图层数据,填充表格数据,同时监听图层操作
function getTableData(graphicLayer) {
graphicLayer.on(mars3d.EventType.removeGraphic, function (event) {
const graphicId = event.graphic.id
removeTableItem(graphicId)
})
// 图上标绘触发事件
graphicLayer.on(mars3d.EventType.drawCreated, function (event) {
refreshTabel(graphicLayer)
})
const graphicList = getDataByLayer(graphicLayer)
tableInit(graphicList)
}
function getItemName(graphic) {
if (graphic.name) {
return `${graphic.type} - ${graphic.name}`
}
if (graphic.attr.index) {
return `${graphic.type} - ${graphic.attr.index}`
}
if (graphic.attr.remark) {
return `${graphic.type} - ${graphic.attr.remark}`
}
if (graphic?.style?.label?.text && graphic.style.label.text !== "0") {
return `${graphic.type} - ${graphic.style.label.text}`
}
return `${graphic.type} - ${graphic.name || "未命名"}`
}
// 将layer中的数据转为表格中的数据
function getDataByLayer(graphicLayer) {
const graphics = graphicLayer.getGraphics()
let graphicList = []
graphics.forEach((graphic) => {
const itemObj = {
id: graphic.id,
name: getItemName(graphic),
type: graphic.type,
show: true
}
graphicList.push(itemObj)
})
return graphicList
}