Skip to content

Commit

Permalink
feat: added vc-polygon component
Browse files Browse the repository at this point in the history
  • Loading branch information
zouyaoji committed Nov 20, 2021
1 parent 846b6a1 commit e0e40d1
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 22 deletions.
23 changes: 22 additions & 1 deletion packages/components/primitive-collections/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/*
* @Author: zouyaoji@https://github.com/zouyaoji
* @Date: 2021-10-27 15:54:11
* @LastEditTime: 2021-11-20 20:44:43
* @LastEditors: zouyaoji
* @Description:
* @FilePath: \vue-cesium@next\packages\components\primitive-collections\index.ts
*/
import { App } from 'vue'
import CollectionBillboard from './billboard-collection'
import Billboard from './billboard'
Expand All @@ -8,9 +16,21 @@ import Point from './point'
import CollectionPolyline from './polyline-collection'
import Polyline from './polyline'
import CollectionPrimitive from './primitive-collection'
import Polygon from './polygon'
import { SFCWithInstall } from '@vue-cesium/utils/types'

const components = [CollectionBillboard, CollectionLabel, CollectionPoint, CollectionPolyline, CollectionPrimitive, Billboard, Label, Point, Polyline]
const components = [
CollectionBillboard,
CollectionLabel,
CollectionPoint,
CollectionPolyline,
CollectionPrimitive,
Billboard,
Label,
Point,
Polyline,
Polygon
]

const install = (app: App): void => {
components.forEach(cmp => {
Expand All @@ -37,3 +57,4 @@ export const VcBillboard = Billboard as SFCWithInstall<typeof Billboard>
export const VcLabel = Label as SFCWithInstall<typeof Label>
export const VcPoint = Point as SFCWithInstall<typeof Point>
export const VcPolyline = Polyline as SFCWithInstall<typeof Polyline>
export const VcPolygon = Polygon as SFCWithInstall<typeof Polygon>
124 changes: 124 additions & 0 deletions packages/components/primitive-collections/polygon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* @Author: zouyaoji@https://github.com/zouyaoji
* @Date: 2021-11-19 22:09:27
* @LastEditTime: 2021-11-20 20:43:27
* @LastEditors: zouyaoji
* @Description:
* @FilePath: \vue-cesium@next\packages\components\primitive-collections\polygon\index.ts
*/
import { createCommentVNode, defineComponent, getCurrentInstance, onUnmounted, PropType, watch, WatchStopHandle } from 'vue'
import { VcComponentInternalInstance } from '@vue-cesium/utils/types'
import { usePrimitiveCollectionItems } from '@vue-cesium/composables'
import { color, id, show, enableMouseEvent, positions, classificationType } from '@vue-cesium/utils/cesium-props'
import { kebabCase } from '@vue-cesium/utils/util'
import { PolygonPrimitive } from '@vue-cesium/shared'
import { makeCartesian3Array, makeColor } from '@vue-cesium/utils/cesium-helpers'

export default defineComponent({
name: 'VcPolygon',
props: {
...positions,
...color,
...show,
...id,
...classificationType,
...enableMouseEvent,
depthFailColor: {
type: [Object, String, Array, Function] as PropType<Cesium.Color>,
default: 'white',
watcherOptions: {
cesiumObjectBuilder: makeColor
}
}
},
emits: ['beforeLoad', 'ready', 'destroyed'],
setup(props, ctx) {
// state
const instance = getCurrentInstance() as VcComponentInternalInstance
instance.cesiumClass = 'PolygonPrimitive'
const primitiveCollectionItemsState = usePrimitiveCollectionItems(props, ctx, instance)

if (primitiveCollectionItemsState === void 0) {
return
}

// watcch
let unwatchFns: Array<WatchStopHandle> = []
unwatchFns.push(
watch(
() => props.positions,
val => {
const polygonPrimitive = instance.cesiumObject as PolygonPrimitive
polygonPrimitive.positions = makeCartesian3Array(val!) as Array<Cesium.Cartesian3>
}
)
)

unwatchFns.push(
watch(
() => props.color,
val => {
const polygonPrimitive = instance.cesiumObject as PolygonPrimitive
polygonPrimitive.color = makeColor(val) as Cesium.Color
}
)
)

unwatchFns.push(
watch(
() => props.depthFailColor,
val => {
const polygonPrimitive = instance.cesiumObject as PolygonPrimitive
polygonPrimitive.depthFailColor = makeColor(val) as Cesium.Color
}
)
)

unwatchFns.push(
watch(
() => props.show,
val => {
const polygonPrimitive = instance.cesiumObject as PolygonPrimitive
polygonPrimitive.show = val
}
)
)

unwatchFns.push(
watch(
() => props.classificationType,
val => {
const polygonPrimitive = instance.cesiumObject as PolygonPrimitive
polygonPrimitive.classificationType = val as number
}
)
)

// methods
instance.createCesiumObject = async () => {
const options = primitiveCollectionItemsState.transformProps(props)
return new PolygonPrimitive(options)
}

instance.mount = async () => {
const primitives = primitiveCollectionItemsState.$services.primitives
const collectionItem = instance.cesiumObject
;(collectionItem as any)._vcParent = primitives
return primitives && primitives.add(collectionItem)
}

instance.unmount = async () => {
const primitives = primitiveCollectionItemsState.$services.primitives
const collectionItem = instance.cesiumObject
return primitives && !primitives.isDestroyed() && primitives.remove(collectionItem)
}

// life cycle
onUnmounted(() => {
unwatchFns.forEach(item => item())
unwatchFns = []
})

return () => createCommentVNode(kebabCase(instance.proxy?.$options.name || ''))
}
})
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
/*
* @Author: zouyaoji@https://github.com/zouyaoji
* @Date: 2021-09-16 09:28:13
* @LastEditTime: 2021-09-30 22:48:23
* @LastEditTime: 2021-11-20 20:06:31
* @LastEditors: zouyaoji
* @Description:
* @FilePath: \vue-cesium@next\packages\components\primitive-collections\primitive-collection\index.ts
*/
import { createCommentVNode, defineComponent, getCurrentInstance, h } from 'vue'
import { createCommentVNode, defineComponent, getCurrentInstance, h, onUnmounted, watch, WatchStopHandle } from 'vue'
import { VcComponentInternalInstance } from '@vue-cesium/utils/types'
import { usePrimitiveCollections } from '@vue-cesium/composables'
import { show, enableMouseEvent } from '@vue-cesium/utils/cesium-props'
import { kebabCase } from '@vue-cesium/utils/util'
import { addCustomProperty, kebabCase } from '@vue-cesium/utils/util'
import { hSlot } from '@vue-cesium/utils/private/render'
import cloneDeep from 'lodash/cloneDeep'
import differenceBy from 'lodash/differenceBy'
import { PolygonPrimitive } from '@vue-cesium/shared'

export default defineComponent({
name: 'VcCollectionPrimitive',
Expand All @@ -21,14 +24,113 @@ export default defineComponent({
type: Boolean,
default: true
},
...enableMouseEvent
...enableMouseEvent,
polygons: {
type: Array,
default: () => []
}
},
emits: ['beforeLoad', 'ready', 'destroyed'],
setup(props, ctx) {
// state
const instance = getCurrentInstance() as VcComponentInternalInstance
instance.cesiumClass = 'PrimitiveCollection'
usePrimitiveCollections(props, ctx, instance)
const primitiveCollectionsState = usePrimitiveCollections(props, ctx, instance)

if (primitiveCollectionsState === void 0) {
return
}

// watcher
instance.alreadyListening.push('polygons')
let unwatchFns: Array<WatchStopHandle> = []

unwatchFns.push(
watch(
() => cloneDeep(props.polygons),
(newVal, oldVal) => {
if (!instance.mounted) {
return
}
const primitiveCollection = instance.cesiumObject as Cesium.PrimitiveCollection

if (newVal.length === oldVal.length) {
// 视为修改操作
// Treated as modified
const modifies: Array<any> = []
for (let i = 0; i < newVal.length; i++) {
const options = newVal[i]
const oldOptions = oldVal[i]

if (JSON.stringify(options) !== JSON.stringify(oldOptions)) {
modifies.push({
newOptions: options,
oldOptions: oldOptions
})
}
}

modifies.forEach(modify => {
const modifyPolygon = primitiveCollection._primitives.find(v => v._id === modify.oldOptions.id)
modifyPolygon &&
Object.keys(modify.newOptions).forEach(prop => {
if (modify.oldOptions[prop] !== modify.newOptions[prop]) {
modifyPolygon[prop] = primitiveCollectionsState.transformProp(prop, modify.newOptions[prop])
}
})
})
} else {
const adds: any = differenceBy(newVal, oldVal, 'id')
const deletes: any = differenceBy(oldVal, newVal, 'id')
const deletePolygons: Array<PolygonPrimitive> = []
for (let i = 0; i < deletes.length; i++) {
const deletePolygon = primitiveCollection._primitives.find((v: any) => v.id === deletes[i].id)
deletePolygon && deletePolygons.push(deletePolygon)
}

deletePolygons.forEach(v => {
primitiveCollection.remove(v)
})

for (let i = 0; i < adds.length; i++) {
const polygonOptions = newVal[i] as PolygonPrimitive
polygonOptions.id = Cesium.defined(polygonOptions.id) ? polygonOptions.id : Cesium.createGuid()
const polygonOptionsTransform = primitiveCollectionsState.transformProps(polygonOptions)
const polygonPrimitive = new PolygonPrimitive(polygonOptionsTransform)
;(polygonPrimitive as any)._vcParent = primitiveCollection
addCustomProperty(polygonPrimitive, polygonOptionsTransform)
primitiveCollection.add(polygonPrimitive)
}
}
},
{
deep: true
}
)
)

// methods
instance.createCesiumObject = async () => {
const options = primitiveCollectionsState.transformProps(props)
const primitiveCollection = new Cesium.PrimitiveCollection(options)

for (let i = 0; i < props.polygons.length; i++) {
const polygonOptions = props.polygons[i] as PolygonPrimitive
polygonOptions.id = Cesium.defined(polygonOptions.id) ? polygonOptions.id : Cesium.createGuid()
const polygonOptionsTransform = primitiveCollectionsState.transformProps(polygonOptions)
const polygonPrimitive = new PolygonPrimitive(polygonOptionsTransform)
;(polygonPrimitive as any)._vcParent = primitiveCollection
addCustomProperty(polygonPrimitive, polygonOptionsTransform)
primitiveCollection.add(polygonPrimitive)
}
return primitiveCollection
}

// life cycle
onUnmounted(() => {
unwatchFns.forEach(item => item())
unwatchFns = []
})

const name = instance.proxy?.$options.name || ''
return () =>
Expand Down
29 changes: 17 additions & 12 deletions packages/composables/use-events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,6 @@ export default function (props, vcInstance: VcComponentInternalInstance, logger)
})
}
}
// 图元
if (pickedFeature.primitive) {
eventSourceList.push({
callbackName,
cesiumObject: pickedFeature.primitive,
pickedFeature
})
}

const getParentCollection = e => {
eventSourceList.push({
callbackName,
Expand All @@ -187,16 +178,30 @@ export default function (props, vcInstance: VcComponentInternalInstance, logger)
getParentCollection(e._vcParent)
}
}
// 图元集合
if (pickedFeature.collection) {
// 图元
// + 自定义图元 如 PolygonPrimitive
if (pickedFeature.primitive) {
if (pickedFeature.primitive._vcParent) {
getParentCollection(pickedFeature.primitive._vcParent)
}
eventSourceList.push({
callbackName,
cesiumObject: pickedFeature.collection,
cesiumObject: pickedFeature.primitive,
pickedFeature
})
}

// 图元集合
if (pickedFeature.collection) {
if (pickedFeature.collection._vcParent) {
getParentCollection(pickedFeature.collection._vcParent)
}

eventSourceList.push({
callbackName,
cesiumObject: pickedFeature.collection,
pickedFeature
})
}
})

Expand Down
5 changes: 3 additions & 2 deletions packages/composables/use-primitive-collection-items/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* @Author: zouyaoji@https://github.com/zouyaoji
* @Date: 2021-09-07 23:36:43
* @LastEditTime: 2021-10-02 23:06:08
* @LastEditTime: 2021-11-20 16:06:29
* @LastEditors: zouyaoji
* @Description:
* @FilePath: \vue-cesium@next\packages\composables\use-primitive-collection-items\index.ts
Expand Down Expand Up @@ -46,6 +46,7 @@ export default function (props, ctx, vcInstance: VcComponentInternalInstance) {
return {
transformProps: commonState.transformProps,
unwatchFns: commonState.unwatchFns,
setPropsWatcher: commonState.setPropsWatcher
setPropsWatcher: commonState.setPropsWatcher,
$services: commonState.$services
}
}
Loading

0 comments on commit e0e40d1

Please sign in to comment.