Sfoglia il codice sorgente

add @dc-modules/layer

tags/2.0.0
Caven Chen 4 anni fa
parent
commit
78bde25b47

+ 315
- 0
modules/layer/Layer.js Vedi File

@@ -0,0 +1,315 @@
/**
* @Author: Caven
* @Date: 2020-01-03 09:38:21
*/

import { Util } from '@dc-modules/utils'
import State from '@dc-modules/state/State'
import { LayerEventType, OverlayEventType, LayerEvent } from '@dc-modules/event'
import LayerType from './LayerType'

const { Cesium } = DC.Namespace

class Layer {
constructor(id) {
this._id = Util.uuid()
this._bid = id || Util.uuid()
this._delegate = undefined
this._viewer = undefined
this._state = undefined
this._show = true
this._cache = {}
this._attr = {}
this._layerEvent = new LayerEvent()
this._layerEvent.on(LayerEventType.ADD, this._onAdd, this)
this._layerEvent.on(LayerEventType.REMOVE, this._onRemove, this)
this._state = undefined
this.type = undefined
}

get layerId() {
return this._id
}

get id() {
return this._bid
}

get delegate() {
return this._delegate
}

set show(show) {
this._show = show
this._delegate && (this._delegate.show = this._show)
}

get show() {
return this._show
}

get layerEvent() {
return this._layerEvent
}

set attr(attr) {
this._attr = attr
}

get attr() {
return this._attr
}

get state() {
return this._state
}

/**
* The hook for added
* @private
*/
_addedHook() {}

/**
* The hook for removed
* @private
*/
_removedHook() {}

/**
* The layer added callback function
* Subclasses need to be overridden
* @param viewer
* @private
*/
_onAdd(viewer) {
this._viewer = viewer
if (!this._delegate) {
return
}
if (this._delegate instanceof Cesium.PrimitiveCollection) {
this._viewer.scene.primitives.add(this._delegate)
} else {
this._viewer.dataSources.add(this._delegate)
}
this._addedHook && this._addedHook()
this._state = State.ADDED
}

/**
* The layer added callback function
* Subclasses need to be overridden
* @private
*/
_onRemove() {
if (!this._delegate) {
return
}
if (this._viewer) {
this._cache = {}
if (this._delegate instanceof Cesium.PrimitiveCollection) {
this._delegate.removeAll()
this._viewer.scene.primitives.remove(this._delegate)
} else if (this._delegate.then) {
this._delegate.then(dataSource => {
dataSource.entities.removeAll()
})
this._viewer.dataSources.remove(this._delegate)
} else {
this._delegate.entities && this._delegate.entities.removeAll()
this._viewer.dataSources.remove(this._delegate)
}
this._removedHook && this._removedHook()
this._state = State.REMOVED
}
}

/**
* The layer add overlay
* @param overlay
* @private
*/
_addOverlay(overlay) {
if (
overlay &&
overlay.overlayEvent &&
!this._cache.hasOwnProperty(overlay.overlayId)
) {
overlay.overlayEvent.fire(OverlayEventType.ADD, this)
this._cache[overlay.overlayId] = overlay
if (this._state === State.CLEARED) {
this._state = State.ADDED
}
}
}

/**
* The layer remove overlay
* @param overlay
* @private
*/
_removeOverlay(overlay) {
if (
overlay &&
overlay.overlayEvent &&
this._cache.hasOwnProperty(overlay.overlayId)
) {
overlay.overlayEvent.fire(OverlayEventType.REMOVE, this)
delete this._cache[overlay.overlayId]
}
}

/**
* Add overlay
* @param overlay
* @returns {Layer}
*/
addOverlay(overlay) {
this._addOverlay(overlay)
return this
}

/**
* Add overlays
* @param overlays
* @returns {Layer}
*/
addOverlays(overlays) {
if (Array.isArray(overlays)) {
overlays.forEach(item => {
this._addOverlay(item)
})
}
return this
}

/**
* Remove overlay
* @param overlay
* @returns {Layer}
*/
removeOverlay(overlay) {
this._removeOverlay(overlay)
return this
}

/**
* Returns the overlay by overlayId
* @param overlayId
* @returns {*|undefined}
*/
getOverlay(overlayId) {
return this._cache[overlayId] || undefined
}

/**
* Returns the overlay by bid
* @param id
* @returns {any}
*/
getOverlayById(id) {
let overlay = undefined
Object.keys(this._cache).forEach(key => {
if (this._cache[key].id === id) {
overlay = this._cache[key]
}
})
return overlay
}

/**
* Returns the overlays by attrName and AttrVal
* @param attrName
* @param attrVal
* @returns {[]}
*/
getOverlaysByAttr(attrName, attrVal) {
let result = []
this.eachOverlay(item => {
if (item.attr[attrName] === attrVal) {
result.push(item)
}
}, this)
return result
}

/**
* Iterate through each overlay and pass it as an argument to the callback function
* @param method
* @param context
* @returns {Layer}
*/
eachOverlay(method, context) {
Object.keys(this._cache).forEach(key => {
method && method.call(context || this, this._cache[key])
})
return this
}

/**
* Returns all overlays
* @returns {[]}
*/
getOverlays() {
let result = []
Object.keys(this._cache).forEach(key => {
result.push(this._cache[key])
})
return result
}

/**
* Clears all overlays
* Subclasses need to be overridden
*/
clear() {}

/**
* Removes from the viewer
*/
remove() {
if (this._viewer) {
this._viewer.removeLayer(this)
}
}

/**
* Adds to the viewer
* @param viewer
* @returns {Layer}
*/
addTo(viewer) {
if (viewer && viewer.addLayer) {
viewer.addLayer(this)
}
return this
}

/**
* sets the style, the style will apply to every overlay of the layer
* Subclasses need to be overridden
* @param style
*/
setStyle(style) {}

/**
* Registers Type
* @param type
*/
static registerType(type) {
if (type) {
LayerType[type.toLocaleUpperCase()] = type.toLocaleLowerCase()
}
}

/**
* Returns type
* @param type
* @returns {*|undefined}
*/
static getLayerType(type) {
return LayerType[type.toLocaleUpperCase()] || undefined
}
}

export default Layer

+ 8
- 0
modules/layer/LayerType.js Vedi File

@@ -0,0 +1,8 @@
/**
* @Author: Caven
* @Date: 2020-05-10 08:21:19
*/

let LayerType = {}

export default LayerType

+ 23
- 0
modules/layer/index.js Vedi File

@@ -0,0 +1,23 @@
/**
* @Author: Caven
* @Date: 2021-03-13 13:46:19
*/

export { default as LayerType } from './LayerType'
export { default as Layer } from './Layer'

/**
* types
*/
export { default as ClusterLayer } from './type/ClusterLayer'
export { default as CzmlLayer } from './type/CzmlLayer'
export { default as GeoJsonLayer } from './type/GeoJsonLayer'
export { default as HeatLayer } from './type/HeatLayer'
export { default as HtmlLayer } from './type/HtmlLayer'
export { default as KmlLayer } from './type/KmlLayer'
export { default as LabelLayer } from './type/LabelLayer'
export { default as LayerGroup } from './type/LayerGroup'
export { default as PrimitiveLayer } from './type/PrimitiveLayer'
export { default as TilesetLayer } from './type/TilesetLayer'
export { default as TopoJsonLayer } from './type/TopoJsonLayer'
export { default as VectorLayer } from './type/VectorLayer'

+ 179
- 0
modules/layer/type/ClusterLayer.js Vedi File

@@ -0,0 +1,179 @@
/**
* @Author: Caven
* @Date: 2020-02-10 10:05:41
*/

import State from '@dc-modules/state/State'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

const DEF_OPT = {
size: 18,
pixelRange: 40,
gradient: {
0.0001: Cesium.Color.DEEPSKYBLUE,
0.001: Cesium.Color.GREEN,
0.01: Cesium.Color.ORANGE,
0.1: Cesium.Color.RED
},
fontSize: 12,
fontColor: Cesium.Color.BLACK,
style: 'circle'
}

class ClusterLayer extends Layer {
constructor(id, options = {}) {
super(id)
this._delegate = new Cesium.CustomDataSource(id)
this._options = {
...DEF_OPT,
...options
}
this._delegate.clustering.enabled = true
this._delegate.clustering.clusterEvent.addEventListener(
this._clusterEventHandler,
this
)
this._delegate.clustering.pixelRange = this._options.pixelRange
this.type = Layer.getLayerType('cluster')
this._state = State.INITIALIZED
}

set enableCluster(enableCluster) {
this._delegate.clustering.enabled = enableCluster
return this
}

/**
*
* @param color
* @param numLength
* @returns {*}
* @private
*/
_drawCircle(color, numLength) {
let size = this._options.size * (numLength + 1)
let key = color.toCssColorString() + '-' + size
if (!this._cache[key]) {
let canvas = document.createElement('canvas')
canvas.width = size
canvas.height = size
let context2D = canvas.getContext('2d')
context2D.save()
context2D.scale(size / 24, size / 24) //Added to auto-generated code to scale up to desired size.
context2D.fillStyle = color.withAlpha(0.2).toCssColorString() //Modified from auto-generated code.
context2D.beginPath()
context2D.arc(12, 12, 9, 0, 2 * Math.PI)
context2D.closePath()
context2D.fill()
context2D.beginPath()
context2D.arc(12, 12, 6, 0, 2 * Math.PI)
context2D.fillStyle = color.toCssColorString()
context2D.fill()
context2D.closePath()
context2D.restore()
this._cache[key] = canvas.toDataURL()
}
return this._cache[key]
}

/**
*
* @param color
* @param numLength
* @returns {*}
* @private
*/
_drawClustering(color, numLength) {
let size = this._options.size * (numLength + 1)
let key = color.toCssColorString() + '-' + size
let startAngle = -Math.PI / 12
let angle = Math.PI / 2
let intervalAngle = Math.PI / 6
if (!this._cache[key]) {
let canvas = document.createElement('canvas')
canvas.width = size
canvas.height = size
let context2D = canvas.getContext('2d')
context2D.save()
context2D.scale(size / 24, size / 24) //Added to auto-generated code to scale up to desired size.
context2D.beginPath()
context2D.arc(12, 12, 6, 0, 2 * Math.PI)
context2D.fillStyle = color.toCssColorString()
context2D.fill()
context2D.closePath()
context2D.lineWidth = 2
for (let i = 0; i < 3; i++) {
context2D.beginPath()
context2D.arc(12, 12, 8, startAngle, startAngle + angle, false)
context2D.strokeStyle = color.withAlpha(0.4).toCssColorString()
context2D.stroke()
context2D.arc(12, 12, 11, startAngle, startAngle + angle, false)
context2D.strokeStyle = color.withAlpha(0.2).toCssColorString()
context2D.stroke()
context2D.closePath()
startAngle = startAngle + angle + intervalAngle
}
context2D.restore()
this._cache[key] = canvas.toDataURL()
}
return this._cache[key]
}

/**
*
* @param {*} clusteredEntities
* @param {*} cluster
*/
_clusterEventHandler(clusteredEntities, cluster) {
if (!this._delegate.clustering.enabled) {
return
}
cluster.billboard.show = true
cluster.label.font = `bold ${this._options.fontSize}px sans-serif`
cluster.label.fillColor = this._options.fontColor
cluster.label.disableDepthTestDistance = Number.POSITIVE_INFINITY
if (this._delegate.entities.values.length) {
let allCount = this._delegate.entities.values.length || 0
for (let key in this._options.gradient) {
if (clusteredEntities.length >= allCount * key) {
let numLength = String(clusteredEntities.length).length
if (this._options.style === 'circle') {
cluster.billboard.image = this._drawCircle(
this._options.gradient[key],
numLength
)
} else {
cluster.billboard.image = this._drawClustering(
this._options.gradient[key],
numLength
)
}
cluster.label.show = true
if (numLength === 1) {
cluster.label.pixelOffset = new Cesium.Cartesian2(-2, 3)
} else {
cluster.label.pixelOffset = new Cesium.Cartesian2(
-5 * (numLength - 1),
5
)
}
} else if (clusteredEntities.length <= 1) {
cluster.label.show = false
}
}
}
}

clear() {
this._delegate.entities.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('cluster')

export default ClusterLayer

+ 52
- 0
modules/layer/type/CzmlLayer.js Vedi File

@@ -0,0 +1,52 @@
/**
* @Author: Caven
* @Date: 2020-01-19 13:38:48
*/

import State from '@dc-modules/state/State'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

class CzmlLayer extends Layer {
constructor(id, url = '', options = {}) {
super(id)
this._delegate = Cesium.CzmlDataSource.load(url, options)
this.type = Layer.getLayerType('czml')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate &&
this._delegate.then(dataSource => {
dataSource.show = this._show
})
}

get show() {
return this._show
}

/**
*
* @param method
* @param context
* @returns {CzmlLayer}
*/
eachOverlay(method, context) {
if (this._delegate) {
this._delegate.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
method.call(context, item)
})
})
return this
}
}
}

Layer.registerType('czml')

export default CzmlLayer

+ 131
- 0
modules/layer/type/GeoJsonLayer.js Vedi File

@@ -0,0 +1,131 @@
/**
* @Author: Caven
* @Date: 2020-01-13 10:13:53
*/

import State from '@dc-modules/state/State'
import { Billboard, Polyline, Polygon, Model } from '@dc-modules/overlay'
import Layer from '../Layer'
import VectorLayer from './VectorLayer'

const { Cesium } = DC.Namespace

class GeoJsonLayer extends Layer {
constructor(id, url, options = {}) {
if (!url) {
throw new Error('GeoJsonLayer:the url invalid')
}
super(id)
this._delegate = Cesium.GeoJsonDataSource.load(url, options)
this.type = Layer.getLayerType('geojson')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate &&
this._delegate.then(dataSource => {
dataSource.show = this._show
})
}

get show() {
return this._show
}

_createBillboard(entity) {
if (entity.position && entity.billboard) {
return Billboard.fromEntity(entity)
}
}

/**
* Returns polyline Entity
* @param entity
* @returns {any}
* @private
*/
_createPolyline(entity) {
if (entity.polyline) {
return Polyline.fromEntity(entity)
}
}

/**
* Returns polygon Entity
* @param entity
* @returns {any}
* @private
*/
_createPolygon(entity) {
if (entity.polygon) {
return Polygon.fromEntity(entity)
}
}

/**
* Returns model Entity
* @param entity
* @param modelUrl
* @returns {Model}
* @private
*/
_createModel(entity, modelUrl) {
if (entity) {
return Model.fromEntity(entity, modelUrl)
}
}

/**
*
* @param method
* @param context
* @returns {GeoJsonLayer}
*/
eachOverlay(method, context) {
if (this._delegate) {
this._delegate.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
method.call(context, item)
})
})
return this
}
}

/**
* Converts to VectorLayer
* @returns {VectorLayer}
*/
toVectorLayer() {
let layer = new VectorLayer(this.id)
this.eachOverlay(item => {
if (item.billboard) {
layer.addOverlay(this._createBillboard(item))
} else if (item.polyline) {
layer.addOverlay(this._createPolyline(item))
} else if (item.polygon) {
layer.addOverlay(this._createPolygon(item))
}
}, this)
return layer
}

/**
* Converts to VectorLayer
* @param modelUrl
* @returns {VectorLayer}
*/
toModelLayer(modelUrl) {
let layer = new VectorLayer(this.id)
this.eachOverlay(item => {
layer.addOverlay(this._createModel(item, modelUrl))
}, this)
return layer
}
}

Layer.registerType('geojson')

export default GeoJsonLayer

+ 283
- 0
modules/layer/type/HeatLayer.js Vedi File

@@ -0,0 +1,283 @@
/**
* @Author: Caven
* @Date: 2020-02-27 00:35:35
*/

import State from '@dc-modules/state/State'
import { SceneEventType } from '@dc-modules/event'
import { Transform } from '@dc-modules/transform'
import Position from '@dc-modules/position/Position'
import { DomUtil, Util } from '@dc-modules/utils'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

const h337 = require('heatmap.js/build/heatmap.min')

const DEF_OPTS = {
maxOpacity: 0.8, // the maximum opacity used if not given in the heatmap options object
minOpacity: 0.1, // the minimum opacity used if not given in the heatmap options object
blur: 0.85, // the blur used if not given in the heatmap options object
maxCanvasSize: 2000,
minCanvasSize: 700,
radius: 25,
gradient: {
'0.4': 'blue',
'0.6': 'green',
'0.8': 'yellow',
'0.9': 'red'
}
}

class HeatLayer extends Layer {
constructor(id, options) {
super(id)
this._options = {
...DEF_OPTS,
...options
}
this._heat = undefined
this._bounds = undefined
this._mBounds = undefined
this._scale = 1
this._positions = []
this._options.spacing = this._options.radius * 1.5
this._delegate = new Cesium.CustomDataSource(id)
this._entity = new Cesium.Entity()
this.type = Layer.getLayerType('heat')
this._state = State.INITIALIZED
}

get options() {
return this._options
}

/**
* The hook for added
*/
_addedHook() {
this._redraw()
this._viewer.on(SceneEventType.CAMERA_MOVE_END, this._reset, this)
}

/**
* The hook for removed
*/
_removedHook() {
this._viewer.off(SceneEventType.CAMERA_MOVE_END, this._reset, this)
}

/**
*
* @param {*} position
*/
_transformWGS84ToHeatmap(position) {
position = Transform.transformWGS84ToMercator(position)
let coord = {}
coord.x = Math.round(
(position.lng - this._mBounds.west) / this._scale + this._options.spacing
)
coord.y = Math.round(
(position.lat - this._mBounds.south) / this._scale + this._options.spacing
)
coord.y = this._heat._renderer.canvas.height - coord.y
return coord
}

/**
*
* @returns {{east: *, south: *, north: *, west: *}}
* @private
*/
_getMBounds() {
let mWestSouth = Transform.transformWGS84ToMercator(
new Position(this._bounds.west, this._bounds.south)
)
let mEastNorth = Transform.transformWGS84ToMercator(
new Position(this._bounds.east, this._bounds.north)
)
return {
west: mWestSouth.lng,
south: mWestSouth.lat,
east: mEastNorth.lng,
north: mEastNorth.lat
}
}

/**
*
* @private
*/
_initCanvas() {
let diffLng = Math.abs(this._mBounds.east - this._mBounds.west)
let diffLat = Math.abs(this._mBounds.north - this._mBounds.south)
let max = Math.max(diffLng, diffLat)
let min = Math.min(diffLng, diffLat)
let scale = 1
if (max > this._options.maxCanvasSize) {
scale = max / this._options.maxCanvasSize
if (min / scale < this._options.minCanvasSize) {
scale = min / this._options.minCanvasSize
}
} else if (min < this._options.minCanvasSize) {
scale = min / this._options.minCanvasSize
if (max / scale > this._options.maxCanvasSize) {
scale = max / this._options.maxCanvasSize
}
}
this._scale = scale
if (!this._options.container) {
this._options.container = DomUtil.create(
'div',
'heat-map',
document.getElementsByClassName('dc-container')[0]
)
}
this._options.container.style.cssText = `
width:${diffLng / this._scale}px;
height:${diffLat / this._scale}px;
margin:0;
display:none`
if (!this._heat) {
this._heat = h337.create(this._options)
} else {
this._heat.configure(this._options)
}
}

/**
*
*/
_initEntity() {
let offset = this._options.spacing * this._scale
this._mBounds.west -= offset
this._mBounds.south -= offset
this._mBounds.east += offset
this._mBounds.north += offset
let westSouth = Transform.transformMercatorToWGS84({
lng: this._mBounds.west,
lat: this._mBounds.south
})
let eastNorth = Transform.transformMercatorToWGS84({
lng: this._mBounds.east,
lat: this._mBounds.north
})
let bounds = Cesium.Rectangle.fromDegrees(
westSouth.lng,
westSouth.lat,
eastNorth.lng,
eastNorth.lat
)
this._entity.show = false
this._entity.rectangle = {
coordinates: bounds,
fill: false,
distanceDisplayCondition: this._options.distanceDisplayCondition
}
this._delegate.entities.add(this._entity)
}

_reset() {
let cameraHeight = Math.floor(
this._viewer.camera.positionCartographic.height
)
let radius = (1e4 / cameraHeight) * 60
if (radius < 10) {
radius = 10
}
if (radius > 60) {
radius = 60
}
this._options.radius = radius
this._options.spacing = this._options.radius * 1.5
this._heat && this._heat.configure(this._options)
}

_redraw() {
/** set bounds */
if (!this._bounds) {
return false
}
let mBounds = this._getMBounds()
if (
!this._mBounds ||
mBounds.west !== this._mBounds.west ||
mBounds.south !== this._mBounds.south ||
mBounds.east !== this._mBounds.east ||
mBounds.north !== this._mBounds.north
) {
this._mBounds = mBounds
this._initCanvas()
}
let data = []
this._positions.forEach(item => {
let coord = this._transformWGS84ToHeatmap({
lng: item.lng || item.x,
lat: item.lat || item.y
})
data.push({
x: coord.x,
y: coord.y,
value: item.value || 1
})
})
this._heat.setData({
min: 0,
max: 1,
data
})
this._delegate.entities.remove(this._entity)
this._initEntity()
let material = new Cesium.ImageMaterialProperty({
image: this._heat._renderer.canvas,
transparent: true
})
Util.merge(this._entity.rectangle, {
fill: true,
material: material
})
this._entity.show = true
}

/**
*
* @param {*} positions
*/
setPositions(positions) {
if (!positions || !Array.isArray(positions)) {
return this
}
this._positions = positions
this._bounds = Cesium.Math.bounds(this._positions)
this._redraw()
return this
}

/**
*
* @param {*} position
*/
addPosition(position) {
this._positions.push(position)
this._bounds = Cesium.Math.bounds(this._positions)
this._redraw()
return this
}

/**
*
* @param {*} options
*/
setOptions(options) {
Util.merge(this._options, options)
if (this._heat) {
this._options.spacing = this._options.radius * 1.5
this._heat.configure(this._options)
}
return this
}
}

Layer.registerType('heat')

export default HeatLayer

+ 89
- 0
modules/layer/type/HtmlLayer.js Vedi File

@@ -0,0 +1,89 @@
/**
* @Author: Caven
* @Date: 2020-02-12 21:43:33
*/

import { DomUtil } from '@dc-modules/utils'
import State from '@dc-modules/state/State'
import { Transform } from '@dc-modules/transform'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

class HtmlLayer extends Layer {
constructor(id) {
super(id)
this._delegate = DomUtil.create('div', 'html-layer', undefined)
this._delegate.setAttribute('id', this._id)
this._renderRemoveCallback = undefined
this.type = Layer.getLayerType('html')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate.style.visibility = this._show ? 'visible' : 'hidden'
this._cache.keys().forEach(key => {
this._cache[key].show = show
})
return this
}

get show() {
return this._show
}

/**
* add handler
* @param viewer
* @private
*/
_onAdd(viewer) {
this._viewer = viewer
this._viewer.dcContainer.appendChild(this._delegate)
let scene = this._viewer.scene
this._renderRemoveCallback = scene.postRender.addEventListener(() => {
let cameraPosition = this._viewer.camera.positionWC
this.eachOverlay(item => {
if (item && item.position) {
let position = Transform.transformWGS84ToCartesian(item.position)
let windowCoord = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
scene,
position
)
let distance = Cesium.Cartesian3.distance(position, cameraPosition)
item._updateStyle({ transform: windowCoord }, distance)
}
}, this)
}, this)
this._state = State.ADDED
}

/**
* remove handler
* @returns {boolean}
* @private
*/
_onRemove() {
this._renderRemoveCallback && this._renderRemoveCallback()
this._viewer.dcContainer.removeChild(this._delegate)
this._state = State.REMOVED
}

/**
* Clears all divIcons
* @returns {HtmlLayer}
*/
clear() {
while (this._delegate.hasChildNodes()) {
this._delegate.removeChild(this._delegate.firstChild)
}
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('html')

export default HtmlLayer

+ 49
- 0
modules/layer/type/KmlLayer.js Vedi File

@@ -0,0 +1,49 @@
/**
* @Author: Caven
* @Date: 2020-01-19 11:03:17
*/

import State from '@dc-modules/state/State'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

class KmlLayer extends Layer {
constructor(id, url, options = {}) {
if (!url) {
throw new Error('KmlLayer: the url is empty')
}
super(id)
this._delegate = Cesium.KmlDataSource.load(url, options)
this.type = Layer.getLayerType('kml')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate &&
this._delegate.then(dataSource => {
dataSource.show = this._show
})
}

get show() {
return this._show
}

eachOverlay(method, context) {
if (this._delegate) {
this._delegate.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
method.call(context, item)
})
})
return this
}
}
}

Layer.registerType('kml')

export default KmlLayer

+ 41
- 0
modules/layer/type/LabelLayer.js Vedi File

@@ -0,0 +1,41 @@
/**
* @Author: Caven
* @Date: 2020-03-30 17:14:00
*/

import State from '@dc-modules/state/State'
import { Label } from '@dc-modules/overlay'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

class LabelLayer extends Layer {
constructor(id, url = '') {
super(id)
this._dataSource = Cesium.GeoJsonDataSource.load(url)
this._delegate = new Cesium.CustomDataSource(id)
this._initLabel()
this.type = Layer.registerType('label')
this._state = State.INITIALIZED
}

_createLabel(entity) {
if (entity.position && entity.name) {
return Label.fromEntity(entity)
}
}

_initLabel() {
this._dataSource.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
let label = this._createLabel(item)
this.addOverlay(label)
})
})
}
}

Layer.registerType('label')

export default LabelLayer

+ 143
- 0
modules/layer/type/LayerGroup.js Vedi File

@@ -0,0 +1,143 @@
/**
* @Author: Caven
* @Date: 2020-08-27 19:50:32
*/

import { Util } from '@dc-modules/utils'
import State from '@dc-modules/state/State'
import { LayerGroupEventType, LayerGroupEvent } from '@dc-modules/event'
import Layer from '../Layer'

class LayerGroup {
constructor(id) {
this._id = id || Util.uuid()
this._cache = {}
this._show = true
this._viewer = undefined
this._layerGroupEvent = new LayerGroupEvent()
this._layerGroupEvent.on(LayerGroupEventType.ADD, this._onAdd, this)
this._layerGroupEvent.on(LayerGroupEventType.REMOVE, this._onRemove, this)
this.type = Layer.getLayerType('layer_group')
this._state = State.INITIALIZED
}

get id() {
return this._id
}

set show(show) {
this._show = show
Object.keys(this._cache).forEach(key => {
this._cache[key].show = this._show
})
}

get show() {
return this._show
}

get layerGroupEvent() {
return this._layerGroupEvent
}

get state() {
return this._state
}

/**
*
* @param viewer
* @private
*/
_onAdd(viewer) {
this._viewer = viewer
Object.keys(this._cache).forEach(key => {
this._viewer.addLayer(this._cache[key])
})
this._state = State.ADDED
}

/**
*
* @private
*/
_onRemove() {
Object.keys(this._cache).forEach(key => {
this._viewer && this._viewer.removeLayer(this._cache[key])
})
this._cache = {}
this._state = State.REMOVED
}

/**
* Adds a layer
* @param layer
* @returns {LayerGroup}
*/
addLayer(layer) {
if (!Object(this._cache).hasOwnProperty(layer.id)) {
this._cache[layer.id] = layer
this._viewer && this._viewer.addLayer(layer)
}
return this
}

/**
* Removes a layer
* @param layer
* @returns {LayerGroup}
*/
removeLayer(layer) {
if (Object(this._cache).hasOwnProperty(layer.id)) {
this._viewer && this._viewer.removeLayer(layer)
delete this._cache[layer.id]
}
return this
}

/**
* Returns a layer by id
* @param id
* @returns {*|undefined}
*/
getLayer(id) {
return this._cache[id] || undefined
}

/**
* Returns all layers
* @returns {[]}
*/
getLayers() {
let result = []
Object.keys(this._cache).forEach(key => {
result.push(this._cache[key])
})
return result
}

/**
* Adds to the viewer
* @param viewer
* @returns {LayerGroup}
*/
addTo(viewer) {
if (viewer && viewer.addLayerGroup) {
viewer.addLayerGroup(this)
}
return this
}

/**
*
* @returns {LayerGroup}
*/
remove() {
this._viewer && this._viewer.removeLayerGroup(this)
return this
}
}

Layer.registerType('layer_group')

export default LayerGroup

+ 33
- 0
modules/layer/type/PrimitiveLayer.js Vedi File

@@ -0,0 +1,33 @@
/**
* @Author: Caven
* @Date: 2020-10-11 18:16:47
*/

import State from '@dc-modules/state/State'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

class PrimitiveLayer extends Layer {
constructor(id) {
super(id)
this._delegate = new Cesium.PrimitiveCollection()
this.type = Layer.getLayerType('primitive')
this._state = State.INITIALIZED
}

/**
* Clears all primitives
* @returns {PrimitiveLayer}
*/
clear() {
this._delegate && this._delegate.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('primitive')

export default PrimitiveLayer

+ 36
- 0
modules/layer/type/TilesetLayer.js Vedi File

@@ -0,0 +1,36 @@
/**
* @Author: Caven
* @Date: 2020-01-09 09:16:27
*/

import State from '@dc-modules/state/State'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

/**
* TilesetLayer is used to add various tileset
*/
class TilesetLayer extends Layer {
constructor(id) {
super(id)
this._delegate = new Cesium.PrimitiveCollection()
this.type = Layer.getLayerType('tileset')
this._state = State.INITIALIZED
}

/**
* Clear all tileset
* @returns {TilesetLayer}
*/
clear() {
this._delegate.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('tileset')

export default TilesetLayer

+ 22
- 0
modules/layer/type/TopoJsonLayer.js Vedi File

@@ -0,0 +1,22 @@
/**
* @Author: Caven
* @Date: 2020-09-11 19:32:22
*/

import State from '@dc-modules/state/State'
import GeoJsonLayer from './GeoJsonLayer'

class TopoJsonLayer extends GeoJsonLayer {
constructor(id, url, options = {}) {
if (!url) {
throw new Error('TopoJsonLayer:the url invalid')
}
super(id, url, options)
this.type = GeoJsonLayer.getLayerType('topojson')
this._state = State.INITIALIZED
}
}

GeoJsonLayer.registerType('topojson')

export default TopoJsonLayer

+ 37
- 0
modules/layer/type/VectorLayer.js Vedi File

@@ -0,0 +1,37 @@
/**
* @Author: Caven
* @Date: 2020-01-02 16:42:03
*/

import State from '@dc-modules/state/State'
import Layer from '../Layer'

const { Cesium } = DC.Namespace

/**
* The vector layer is used to add various entity, which is essentially a CustomDataSource
* that is used to place entities of the same class or business attribute into the same layer
*/
class VectorLayer extends Layer {
constructor(id) {
super(id)
this._delegate = new Cesium.CustomDataSource(id)
this.type = Layer.getLayerType('vector')
this._state = State.INITIALIZED
}

/**
* Clears all entities
* @returns {VectorLayer}
*/
clear() {
this._delegate.entities && this._delegate.entities.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('vector')

export default VectorLayer

Loading…
Annulla
Salva