448 lines
13 KiB
TypeScript
448 lines
13 KiB
TypeScript
import { wktToGeoJSON,geojsonToWKT } from "@terraformer/wkt"
|
||
import * as turf from '@turf/turf'
|
||
import * as mars3d from 'mars3d';
|
||
import { EventBus } from '@/utils/eventBus';
|
||
|
||
// wkt 转 geojson
|
||
const WktToGeojson = (wktData)=> {
|
||
return wktToGeoJSON(wktData);
|
||
}
|
||
|
||
// geojson 转 wkt
|
||
const GeojsonToWkt = (geojsonData)=> {
|
||
return geojsonToWKT(geojsonData)
|
||
}
|
||
|
||
// 获取数据中心点
|
||
const GetGeometryCenter = (geometry) => {
|
||
let geojson = null;
|
||
|
||
// wkt
|
||
if(typeof geometry == 'string'){
|
||
geojson = wktToGeoJSON(geometry);
|
||
}
|
||
|
||
let coordinates = null;
|
||
let centerPointGeojson = null;
|
||
|
||
switch(geojson?.type){
|
||
|
||
case "Point":
|
||
coordinates = geojson.coordinates;
|
||
break;
|
||
|
||
case "Polygon":
|
||
let polygon = turf.polygon(geojson.coordinates);
|
||
centerPointGeojson = turf.centerOfMass(polygon);
|
||
coordinates = centerPointGeojson.geometry.coordinates;
|
||
break;
|
||
|
||
case "MultiPolygon":
|
||
let multiPolygon = turf.multiPolygon(geojson.coordinates);
|
||
centerPointGeojson = turf.centerOfMass(multiPolygon);
|
||
coordinates = centerPointGeojson.geometry.coordinates;
|
||
break;
|
||
}
|
||
return coordinates;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
let drawingGraphicLayer = new mars3d.layer.GeoJsonLayer();
|
||
|
||
// 编辑图斑
|
||
const EditDrawingGeometry = (map,geometry) => {
|
||
|
||
// 获取geojson
|
||
let geojson = null;
|
||
|
||
if(typeof geometry == 'string'){
|
||
let jsonData = WktToGeojson(geometry)
|
||
|
||
geojson = {
|
||
"type": "FeatureCollection",
|
||
"features": [
|
||
{
|
||
"type": "Feature",
|
||
"geometry": jsonData
|
||
}
|
||
]
|
||
}
|
||
}
|
||
console.log("geojson",geojson);
|
||
|
||
// 加载图层
|
||
if(drawingGraphicLayer){
|
||
drawingGraphicLayer.clear();
|
||
map.removeLayer(drawingGraphicLayer);
|
||
drawingGraphicLayer = null;
|
||
}
|
||
|
||
drawingGraphicLayer = new mars3d.layer.GeoJsonLayer({
|
||
name: "编辑图层",
|
||
data:geojson,
|
||
isAutoEditing:true,
|
||
symbol: {
|
||
styleOptions: {
|
||
color: "#0d3685",
|
||
outlineColor: "#0d3685",
|
||
opacity: 0.8,
|
||
clampToGround:true,
|
||
"color": "#2f00b0",
|
||
"pixelSize": 10,
|
||
"opacity": 1,
|
||
"outline": true,
|
||
"outlineColor": "#ffffff",
|
||
"outlineOpacity": 0.6,
|
||
"outlineWidth": 2,
|
||
"scaleByDistance_far": 1000000,
|
||
"scaleByDistance_farValue": 0.1,
|
||
"scaleByDistance_near": 1000,
|
||
"scaleByDistance_nearValue": 1,
|
||
"distanceDisplayCondition_far": 10000,
|
||
"visibleDepth": true
|
||
}
|
||
},
|
||
clampToGround:true,
|
||
popup: [],
|
||
popupOptions: {
|
||
showNull: true
|
||
},
|
||
// flyTo: true
|
||
})
|
||
|
||
map.addLayer(drawingGraphicLayer)
|
||
|
||
// 绑定菜单
|
||
geometryBindMenu();
|
||
}
|
||
|
||
// 添加图斑
|
||
const AddDrawingGeometry = (map,type) => {
|
||
|
||
// 加载图层
|
||
if(drawingGraphicLayer){
|
||
drawingGraphicLayer.clear();
|
||
map.removeLayer(drawingGraphicLayer);
|
||
drawingGraphicLayer = null;
|
||
}
|
||
|
||
let geojson = {
|
||
"type": "FeatureCollection",
|
||
"features": []
|
||
}
|
||
|
||
drawingGraphicLayer = new mars3d.layer.GeoJsonLayer({
|
||
name: "编辑图层",
|
||
data:geojson,
|
||
isAutoEditing:true,
|
||
symbol: {
|
||
styleOptions: {
|
||
color: "#0d3685",
|
||
outlineColor: "#0d3685",
|
||
opacity: 0.8,
|
||
clampToGround:true,
|
||
"color": "#2f00b0",
|
||
"pixelSize": 10,
|
||
"opacity": 1,
|
||
"outline": true,
|
||
"outlineColor": "#ffffff",
|
||
"outlineOpacity": 0.6,
|
||
"outlineWidth": 2,
|
||
"scaleByDistance_far": 1000000,
|
||
"scaleByDistance_farValue": 0.1,
|
||
"scaleByDistance_near": 1000,
|
||
"scaleByDistance_nearValue": 1,
|
||
"distanceDisplayCondition_far": 10000,
|
||
"visibleDepth": true
|
||
}
|
||
},
|
||
clampToGround:true,
|
||
popup: [],
|
||
popupOptions: {
|
||
showNull: true
|
||
},
|
||
// flyTo: trues
|
||
})
|
||
|
||
map.addLayer(drawingGraphicLayer);
|
||
|
||
// 开始绘制
|
||
switch(type){
|
||
case "point":
|
||
drawingGraphicLayer.startDraw({
|
||
type: "pointP",
|
||
style: {
|
||
pixelSize: 12,
|
||
color: "#3388ff",
|
||
label: {
|
||
// 不需要文字时,去掉label配置即可
|
||
text: "",
|
||
font_size: 20,
|
||
color: "#ffffff",
|
||
outline: true,
|
||
outlineColor: "#000000",
|
||
pixelOffsetY: -20
|
||
}
|
||
}
|
||
})
|
||
break;
|
||
|
||
case "polygon":
|
||
// 贴地面
|
||
drawingGraphicLayer.startDraw({
|
||
type: "polygonP",
|
||
style: {
|
||
color: "#3388ff",
|
||
opacity: 0.5,
|
||
outline: true,
|
||
outlineColor: "#ffffff",
|
||
outlineWidth: 2.0,
|
||
clampToGround:true
|
||
}
|
||
})
|
||
break;
|
||
|
||
case "polyline":
|
||
drawingGraphicLayer.startDraw({
|
||
type: "polylineP",
|
||
style: {
|
||
color:"#3388ff",
|
||
width: 3,
|
||
clampToGround:true
|
||
}
|
||
})
|
||
break;
|
||
}
|
||
|
||
|
||
geometryBindMenu();
|
||
|
||
}
|
||
|
||
// 查看图斑
|
||
const PreviewDrawingGeometry = (map,geometry) => {
|
||
// 获取geojson
|
||
let geojson = null;
|
||
|
||
if(typeof geometry == 'string'){
|
||
let jsonData = WktToGeojson(geometry)
|
||
|
||
geojson = {
|
||
"type": "FeatureCollection",
|
||
"features": [
|
||
{
|
||
"type": "Feature",
|
||
"geometry": jsonData
|
||
}
|
||
]
|
||
}
|
||
}
|
||
|
||
if(drawingGraphicLayer){
|
||
drawingGraphicLayer.clear();
|
||
map.removeLayer(drawingGraphicLayer);
|
||
drawingGraphicLayer = null;
|
||
}
|
||
|
||
// 加载图层
|
||
|
||
console.log("geojsongeojson",geojson.features[0].geometry.coordinates[0][0]);
|
||
|
||
geojson.features[0].geometry.coordinates[0][0].pop();
|
||
|
||
drawingGraphicLayer = new mars3d.layer.GeoJsonLayer({
|
||
name: "标绘示例数据",
|
||
data:geojson,
|
||
popup: "{type} {name}",
|
||
queryParameters: {
|
||
token: "mars3d" // 可以传自定义url参数,如token等
|
||
},
|
||
symbol: {
|
||
merge: true,
|
||
styleOptions: {
|
||
color: "#408eff",
|
||
outlineColor: "#408eff",
|
||
opacity: 0.8,
|
||
clampToGround:true,
|
||
}
|
||
},
|
||
clampToGround:true,
|
||
flyTo: true
|
||
})
|
||
|
||
// drawingGraphicLayer = new mars3d.layer.GeoJsonLayer({
|
||
// name: "编辑图层",
|
||
// data:geojson,
|
||
// isAutoEditing:true,
|
||
// symbol: {
|
||
// styleOptions: {
|
||
// color: "#0d3685",
|
||
// outlineColor: "#0d3685",
|
||
// opacity: 0.8,
|
||
// clampToGround:true,
|
||
// "color": "#2f00b0",
|
||
// "pixelSize": 10,
|
||
// "opacity": 1,
|
||
// "outline": true,
|
||
// "outlineColor": "#ffffff",
|
||
// "outlineOpacity": 0.6,
|
||
// "outlineWidth": 2,
|
||
// "scaleByDistance_far": 1000000,
|
||
// "scaleByDistance_farValue": 0.1,
|
||
// "scaleByDistance_near": 1000,
|
||
// "scaleByDistance_nearValue": 1,
|
||
// "distanceDisplayCondition_far": 10000,
|
||
// "visibleDepth": false
|
||
// }
|
||
// },
|
||
// clampToGround:true,
|
||
// popup: [],
|
||
// popupOptions: {
|
||
// showNull: true
|
||
// },
|
||
// flyTo: true
|
||
// })
|
||
|
||
map.addLayer(drawingGraphicLayer)
|
||
|
||
}
|
||
|
||
// 图斑菜单
|
||
const geometryBindMenu = () => {
|
||
// 绑定菜单
|
||
drawingGraphicLayer.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) {
|
||
drawingGraphicLayer.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-pencil",
|
||
show: (event) => {
|
||
function hasRestore(graphic) {
|
||
if (!graphic || !graphic.hasEdit || !graphic.isEditing) {
|
||
return false
|
||
}
|
||
return graphic.editing?.hasRestore()
|
||
}
|
||
|
||
const graphic = event.graphic
|
||
if (hasRestore(graphic)) {
|
||
return true
|
||
}
|
||
if (graphic.isPrivate && graphic.parent) {
|
||
return hasRestore(graphic.parent) // 右击是编辑点时
|
||
}
|
||
return false
|
||
},
|
||
callback: (event) => {
|
||
const graphic = event.graphic
|
||
if (graphic.editing?.restore) {
|
||
graphic.editing.restore() // 撤销编辑,可直接调用
|
||
} else if (graphic.parent?.editing?.restore) {
|
||
graphic.parent.editing.restore() // 右击是编辑点时
|
||
}
|
||
}
|
||
},
|
||
{
|
||
text: "撤销编辑(还原到上一步)",
|
||
icon: "fa fa-pencil",
|
||
show: (event) => {
|
||
function hasRevoke(graphic) {
|
||
if (!graphic || !graphic.hasEdit || !graphic.isEditing) {
|
||
return false
|
||
}
|
||
return graphic.editing?.hasRevoke()
|
||
}
|
||
|
||
const graphic = event.graphic
|
||
if (hasRevoke(graphic)) {
|
||
return true
|
||
}
|
||
if (graphic.isPrivate && graphic.parent) {
|
||
return hasRevoke(graphic.parent) // 右击是编辑点时
|
||
}
|
||
return false
|
||
},
|
||
callback: (event) => {
|
||
const graphic = event.graphic
|
||
if (graphic.editing?.revoke) {
|
||
graphic.editing.revoke() // 撤销编辑,可直接调用
|
||
} else if (graphic.parent?.editing?.revoke) {
|
||
graphic.parent.editing.revoke() // 右击是编辑点时
|
||
}
|
||
}
|
||
}
|
||
])
|
||
|
||
// 获取编辑结果
|
||
drawingGraphicLayer.on(mars3d.EventType.editStop, function (e) {
|
||
let resultGeojson = e.graphic.toGeoJSON({standard:true,noAlt:true})
|
||
|
||
let resultWkt = GeojsonToWkt(resultGeojson.geometry)
|
||
EventBus.emit("editLayerEnd",resultWkt)
|
||
})
|
||
|
||
// 绘制完成
|
||
drawingGraphicLayer.on(mars3d.EventType.drawCreated, function (e) {
|
||
|
||
|
||
let resultGeojson = e.graphic.toGeoJSON({standard:true,noAlt:true})
|
||
|
||
if(resultGeojson.geometry.type == "Polygon"){
|
||
resultGeojson.geometry.coordinates [0].push(resultGeojson.geometry.coordinates [0][0])
|
||
}
|
||
console.log("resultGeoJson",resultGeojson);
|
||
|
||
let resultWkt = GeojsonToWkt(resultGeojson.geometry)
|
||
|
||
EventBus.emit("editLayerEnd",resultWkt)
|
||
})
|
||
}
|
||
|
||
// 结束停止编辑
|
||
const DrawingEnd = () => {
|
||
drawingGraphicLayer.clear();
|
||
}
|
||
|
||
|
||
export {WktToGeojson,GeojsonToWkt,GetGeometryCenter,EditDrawingGeometry,AddDrawingGeometry,PreviewDrawingGeometry,DrawingEnd} |