|
@@ -367,19 +367,56 @@ function getMarkerColor(marker) {
|
|
|
return TYPE_COLORS[marker.type] || '#ff4444'
|
|
return TYPE_COLORS[marker.type] || '#ff4444'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function createMarkerCanvas(marker) {
|
|
|
|
|
|
|
+function roundRect(ctx, x, y, width, height, radius) {
|
|
|
|
|
+ ctx.beginPath()
|
|
|
|
|
+ ctx.moveTo(x + radius, y)
|
|
|
|
|
+ ctx.lineTo(x + width - radius, y)
|
|
|
|
|
+ ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
|
|
|
|
|
+ ctx.lineTo(x + width, y + height - radius)
|
|
|
|
|
+ ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
|
|
|
|
|
+ ctx.lineTo(x + radius, y + height)
|
|
|
|
|
+ ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
|
|
|
|
|
+ ctx.lineTo(x, y + radius)
|
|
|
|
|
+ ctx.quadraticCurveTo(x, y, x + radius, y)
|
|
|
|
|
+ ctx.closePath()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function createMarkerLabelCanvas(marker) {
|
|
|
const color = getMarkerColor(marker)
|
|
const color = getMarkerColor(marker)
|
|
|
|
|
+ const text = marker.title || '未命名'
|
|
|
|
|
+ const font = 'bold 12px sans-serif'
|
|
|
|
|
+ const paddingX = 10
|
|
|
|
|
+ const paddingY = 6
|
|
|
|
|
+ const radius = 6
|
|
|
|
|
+
|
|
|
|
|
+ const tempCanvas = document.createElement('canvas')
|
|
|
|
|
+ const tempCtx = tempCanvas.getContext('2d')
|
|
|
|
|
+ tempCtx.font = font
|
|
|
|
|
+ const textWidth = tempCtx.measureText(text).width
|
|
|
|
|
+ const textHeight = 12
|
|
|
|
|
+
|
|
|
|
|
+ const width = Math.ceil(textWidth + paddingX * 2)
|
|
|
|
|
+ const height = Math.ceil(textHeight + paddingY * 2)
|
|
|
|
|
+
|
|
|
const canvas = document.createElement('canvas')
|
|
const canvas = document.createElement('canvas')
|
|
|
- canvas.width = 32
|
|
|
|
|
- canvas.height = 32
|
|
|
|
|
|
|
+ canvas.width = width
|
|
|
|
|
+ canvas.height = height
|
|
|
const ctx = canvas.getContext('2d')
|
|
const ctx = canvas.getContext('2d')
|
|
|
- ctx.beginPath()
|
|
|
|
|
- ctx.arc(16, 16, 12, 0, 2 * Math.PI)
|
|
|
|
|
- ctx.fillStyle = color
|
|
|
|
|
|
|
+
|
|
|
|
|
+ roundRect(ctx, 0, 0, width, height, radius)
|
|
|
|
|
+ ctx.fillStyle = 'rgba(30, 41, 59, 0.92)'
|
|
|
ctx.fill()
|
|
ctx.fill()
|
|
|
- ctx.strokeStyle = '#fff'
|
|
|
|
|
- ctx.lineWidth = 2
|
|
|
|
|
|
|
+
|
|
|
|
|
+ ctx.strokeStyle = color
|
|
|
|
|
+ ctx.lineWidth = 1
|
|
|
ctx.stroke()
|
|
ctx.stroke()
|
|
|
|
|
+
|
|
|
|
|
+ ctx.fillStyle = '#fff'
|
|
|
|
|
+ ctx.font = font
|
|
|
|
|
+ ctx.textAlign = 'center'
|
|
|
|
|
+ ctx.textBaseline = 'middle'
|
|
|
|
|
+ ctx.fillText(text, width / 2, height / 2 + 1)
|
|
|
|
|
+
|
|
|
return canvas
|
|
return canvas
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -391,29 +428,45 @@ function createMarkers() {
|
|
|
markerEntities = []
|
|
markerEntities = []
|
|
|
|
|
|
|
|
props.markers.forEach((marker, index) => {
|
|
props.markers.forEach((marker, index) => {
|
|
|
- const height = getMarkerSurfaceHeight(marker.lon, marker.lat) + (marker.alt || 0)
|
|
|
|
|
- const entity = viewer.entities.add({
|
|
|
|
|
- position: Cesium.Cartesian3.fromDegrees(marker.lon, marker.lat, height),
|
|
|
|
|
|
|
+ const surfaceHeight = getMarkerSurfaceHeight(marker.lon, marker.lat) + (marker.alt || 0)
|
|
|
|
|
+ const labelHeight = surfaceHeight + 55
|
|
|
|
|
+ const color = getMarkerColor(marker)
|
|
|
|
|
+ const cesiumColor = Cesium.Color.fromCssColorString(color)
|
|
|
|
|
+ const labelCanvas = createMarkerLabelCanvas(marker)
|
|
|
|
|
+
|
|
|
|
|
+ const labelEntity = viewer.entities.add({
|
|
|
|
|
+ position: Cesium.Cartesian3.fromDegrees(marker.lon, marker.lat, labelHeight),
|
|
|
billboard: {
|
|
billboard: {
|
|
|
- image: createMarkerCanvas(marker),
|
|
|
|
|
|
|
+ image: labelCanvas,
|
|
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
|
- scale: 1,
|
|
|
|
|
- heightReference: Cesium.HeightReference.NONE
|
|
|
|
|
|
|
+ heightReference: Cesium.HeightReference.NONE,
|
|
|
|
|
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
|
},
|
|
},
|
|
|
- label: {
|
|
|
|
|
- text: marker.title || '未命名',
|
|
|
|
|
- font: '12px sans-serif',
|
|
|
|
|
- fillColor: Cesium.Color.WHITE,
|
|
|
|
|
- outlineColor: Cesium.Color.BLACK,
|
|
|
|
|
|
|
+ polyline: {
|
|
|
|
|
+ positions: Cesium.Cartesian3.fromDegreesArrayHeights([
|
|
|
|
|
+ marker.lon, marker.lat, labelHeight,
|
|
|
|
|
+ marker.lon, marker.lat, surfaceHeight
|
|
|
|
|
+ ]),
|
|
|
|
|
+ width: 2,
|
|
|
|
|
+ material: cesiumColor
|
|
|
|
|
+ },
|
|
|
|
|
+ properties: { markerData: marker, index }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ const groundEntity = viewer.entities.add({
|
|
|
|
|
+ position: Cesium.Cartesian3.fromDegrees(marker.lon, marker.lat, surfaceHeight),
|
|
|
|
|
+ point: {
|
|
|
|
|
+ pixelSize: 8,
|
|
|
|
|
+ color: cesiumColor,
|
|
|
|
|
+ outlineColor: Cesium.Color.WHITE,
|
|
|
outlineWidth: 2,
|
|
outlineWidth: 2,
|
|
|
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
|
|
|
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
|
|
|
- pixelOffset: new Cesium.Cartesian2(0, -34),
|
|
|
|
|
- heightReference: Cesium.HeightReference.NONE
|
|
|
|
|
|
|
+ heightReference: Cesium.HeightReference.NONE,
|
|
|
|
|
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
|
},
|
|
},
|
|
|
properties: { markerData: marker, index }
|
|
properties: { markerData: marker, index }
|
|
|
})
|
|
})
|
|
|
- markerEntities.push(entity)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ markerEntities.push(labelEntity, groundEntity)
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|