| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- import Style from 'ol/style/Style'
- import Photo from 'ol-ext/style/Photo'
- import { newPoint } from '@/utils/map.js'
- import VectorLayer from 'ol/layer/Vector.js'
- import { Cluster, Vector as VectorSource } from 'ol/source.js'
- import { Vector } from 'ol/layer.js'
- import * as KMap from '@/utils/ol-map/KMap.js'
- import { Fill, Text, Icon, Stroke } from 'ol/style.js'
- // import eventBus from '@/api/eventBus.js'
- import { extractCoordinates } from '@/common/commonFun.js'
- import treeImg from '@/assets/img/map/tree.png'
- import treeActiveImg from '@/assets/img/map/tree-active.png'
- import activeBgImg from '@/assets/img/map/active-bg.png'
- import hereImg from '@/assets/img/map/here.png'
- import progressImg from '@/assets/img/map/progress.png'
- import progressActiveImg from '@/assets/img/map/progress-active.png'
- /**
- * 果树聚合点位图层
- */
- class ClusterPointsLayer {
- constructor(kmap) {
- const that = this
- this.cloudFilenameCache = {}
- this.statusTitleStyleCache = {}
- this.textBgStyleCache = {}
- this.bgStyleCache = {}
- this.activeBgStyleCache = {}
- this.progressBgStyleCache = {}
- this.enterSelectTree = false
- this.selectableActiveTree = null
- that.initLayer(kmap)
- that.kmap = kmap
- // that.addMapSingerClick()
- this.currentPoint = null
- }
- addMapSingerClick() {
- const that = this
- that.kmap.on('singleclick', (evt) => {
- that.kmap.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
- if (layer instanceof VectorLayer && layer.get('name') === 'clusterPointsLayer') {
- const fs = that.selectFeature(feature)
- // if (that.selectableActiveTree) {
- // that.selectableActiveTree.set('selectableActive', false)
- // }
- // if (that.enterSelectTree) {
- // // eventBus.emit('showTreePopup', fs.get('sampleId'))
- // that.selectableActiveTree = fs
- // fs.set('selectableActive', true)
- // return
- // }
- // const miniUserId = fs.get('miniUserId') && !fs.get('virtual')
- // const isMy = fs.get('my')
- // if (isMy) {
- // localStorage.setItem('showMapText', true)
- // } else if (miniUserId) {
- // // eventBus.emit('adoptMap:friendTree', {
- // // sampleId: fs.get('sampleId'),
- // // })
- // } else {
- // // eventBus.emit('showTreePopup', fs.get('sampleId'))
- // that.selectableActiveTree = fs
- // fs.set('selectableActive', true)
- // }
- }
- })
- })
- }
- initLayer(kmap) {
- const that = this
- this.vectorStyle = new KMap.VectorStyle()
- this.clusterSource = new VectorSource({})
- this.clusterLayer = new Vector({
- source: new Cluster({
- distance: 40,
- source: this.clusterSource,
- }),
- className: 'ol-layer-cluster',
- name: 'clusterPointsLayer',
- minZoom: 14.6,
- maxZoom: 22,
- zIndex: 1001,
- style: function (feature) {
- const f = that.selectFeature(feature)
- const isVisible = f.get('visible') !== false
- const selectableActive = f.get('selectableActive')
- if (!isVisible) {
- return []
- }
- if (that.enterSelectTree || selectableActive) {
- return new Style({
- image: new Icon({
- src: selectableActive ? treeActiveImg : treeImg,
- scale: 0.55,
- }),
- })
- }
- const isOther = f.get('miniUserId') ? true : false
- const isHigh = f.get('my')
- if (!isHigh && !isOther) {
- return new Style({
- image: new Icon({
- src: treeImg,
- scale: 0.55,
- }),
- })
- }
- const img = f.get('icon')
- const count = 30
- const startColor = isHigh ? '#FFD887' : '#FFFFFFb3'
- const endColor = isHigh ? '#ED9E1E' : '#FFFFFFb3'
- const styles = [
- that.pointStyle(img, isHigh),
- that.progressStyle(count, isHigh),
- that.textBgStyle(count, startColor, endColor, isHigh),
- ]
- if (isHigh) {
- styles.push(
- that.activePointBgStyle(),
- that.statusTitleStyle(
- f.get('treeName'),
- 0,
- -36,
- '#FFFFFF',
- '#B38A00',
- 14,
- isHigh,
- ),
- )
- if (!localStorage.getItem('showMapText')) {
- styles.push(that.activeTextStyle())
- }
- }
- return styles
- },
- })
- kmap.addLayer(this.clusterLayer)
- this.kmap = kmap
- }
- setVisible(visible) {
- if (this.clusterLayer) {
- this.clusterLayer.setVisible(visible)
- }
- }
- setData(data, enterSelectTreeVal) {
- const that = this
- this.enterSelectTree = enterSelectTreeVal
- if (enterSelectTreeVal) {
- this.setVisible(false)
- this.clusterSource.clear()
- return
- }
- this.setVisible(true)
- this.clusterSource.clear()
- const features = []
- if (!data || !data.length) return
- const myPoint = data.find((item) => item.my)
- for (const item of data) {
- try {
- const f = newPoint(item, 'geom', 'cluster-point')
- features.push(f)
- } catch (err) {
- console.log('err', err)
- }
- }
- this.clusterSource.addFeatures(features)
- this.kmap.getView().fit(this.clusterSource.getExtent(), {
- duration: 1000,
- padding: [0, 10, 0, 10],
- })
- if (myPoint) {
- setTimeout(() => {
- const pointPosition = extractCoordinates(myPoint.geom)
- const view = this.kmap.getView()
- view.animate({
- duration: 1200,
- zoom: 20,
- center: pointPosition,
- })
- }, 1100)
- }
- }
- textBgStyle(count, startColor, endColor, isHigh) {
- const key = count + startColor + endColor + isHigh
- let style = this.textBgStyleCache[key]
- let length = 5
- let offsetX = 0
- let highOffsetX = 0
- if (count === 0) {
- length = 0
- } else if (count < 7) {
- length = 10
- offsetX = 14
- highOffsetX = 14
- } else if (count > 7 && count <= 14) {
- length = 20
- offsetX = 6
- highOffsetX = 7
- } else if (count > 14 && count <= 21) {
- length = 28
- offsetX = 4
- highOffsetX = 5
- } else if (count > 21 && count <= 29) {
- length = 34
- offsetX = 2
- highOffsetX = 3
- } else if (count === 30) {
- length = 38
- offsetX = 0
- highOffsetX = 0
- }
- if (!style) {
- style = new Style({
- renderer: function (coordinates, state) {
- const ctx = state.context
- const x =
- coordinates[0] -
- (isHigh ? highOffsetX * state.pixelRatio : offsetX * state.pixelRatio)
- const y =
- coordinates[1] + (isHigh ? 24 * state.pixelRatio : 17 * state.pixelRatio)
- const width = isHigh
- ? (length + 10) * state.pixelRatio
- : length * state.pixelRatio
- const height = isHigh ? 10 * state.pixelRatio : 6 * state.pixelRatio
- const cornerRadius = isHigh ? 5 * state.pixelRatio : 3 * state.pixelRatio
- const gradient = ctx.createLinearGradient(x - width / 2, y, x + width / 2, y)
- gradient.addColorStop(0, startColor)
- gradient.addColorStop(1, endColor)
- ctx.beginPath()
- ctx.moveTo(x - width / 2 + cornerRadius, y - height / 2)
- ctx.lineTo(x + width / 2 - cornerRadius, y - height / 2)
- ctx.arc(
- x + width / 2 - cornerRadius,
- y - height / 2 + cornerRadius,
- cornerRadius,
- -Math.PI / 2,
- 0,
- )
- ctx.lineTo(x + width / 2, y + height / 2 - cornerRadius)
- ctx.arc(
- x + width / 2 - cornerRadius,
- y + height / 2 - cornerRadius,
- cornerRadius,
- 0,
- Math.PI / 2,
- )
- ctx.lineTo(x - width / 2 + cornerRadius, y + height / 2)
- ctx.arc(
- x - width / 2 + cornerRadius,
- y + height / 2 - cornerRadius,
- cornerRadius,
- Math.PI / 2,
- Math.PI,
- )
- ctx.lineTo(x - width / 2, y - height / 2 + cornerRadius)
- ctx.arc(
- x - width / 2 + cornerRadius,
- y - height / 2 + cornerRadius,
- cornerRadius,
- Math.PI,
- -Math.PI / 2,
- )
- ctx.closePath()
- ctx.fillStyle = gradient
- ctx.fill()
- },
- zIndex: isHigh ? 12 : 10,
- })
- this.textBgStyleCache[key] = style
- }
- return style
- }
- statusTitleStyle(statusName, offsetX, offsetY, color, strokeColor, fontSize, isHigh) {
- const key = statusName + '-' + offsetY
- let style = this.statusTitleStyleCache[key]
- if (!style) {
- style = new Style({
- text: new Text({
- text: statusName,
- offsetX: offsetX,
- offsetY: offsetY,
- font: isHigh ? 'bold 14px sans-serif' : '12px sans-serif',
- fill: new Fill({ color }),
- stroke: new Stroke({ color: strokeColor }),
- }),
- zIndex: 13,
- })
- this.statusTitleStyleCache[key] = style
- }
- return style
- }
- pointStyle(img, isHigh) {
- const key = img + isHigh
- let bgStyle = this.bgStyleCache[key]
- if (!bgStyle) {
- bgStyle = new Style({
- image: new Photo({
- src: img,
- kind: 'circle',
- radius: isHigh ? 23 : 17,
- shadow: 0,
- crop: false,
- displacement: [0, 0],
- stroke: new Stroke({
- width: isHigh ? 0 : 1,
- color: isHigh ? '#fff' : '#C7C7C7',
- }),
- }),
- zIndex: isHigh ? 11 : 0,
- })
- this.bgStyleCache[key] = bgStyle
- }
- return bgStyle
- }
- activePointBgStyle() {
- return new Style({
- image: new Icon({
- src: activeBgImg,
- scale: 0.55,
- }),
- zIndex: 10,
- })
- }
- activeTextStyle() {
- return new Style({
- image: new Icon({
- src: hereImg,
- scale: 0.5,
- displacement: [0, 108],
- }),
- zIndex: 15,
- })
- }
- progressStyle(count, isHigh) {
- const key = count + isHigh
- let progressBgStyle = this.progressBgStyleCache[key]
- if (!progressBgStyle) {
- progressBgStyle = new Style({
- image: new Icon({
- src: isHigh ? progressActiveImg : progressImg,
- scale: 0.5,
- displacement: isHigh ? [0, -48] : [0, -34],
- }),
- zIndex: isHigh ? 12 : 0,
- })
- this.progressBgStyleCache[key] = progressBgStyle
- }
- return progressBgStyle
- }
- selectFeature(feature) {
- const fs = feature.get('features')
- if (!fs || fs.length === 0) {
- return feature
- }
- if (fs.length === 1) {
- return fs[0]
- }
- for (const item of fs) {
- if (item.get('my')) {
- return item
- }
- }
- for (const item of fs) {
- if (item.get('miniUserId')) {
- return item
- }
- }
- return fs[0]
- }
- }
- export default ClusterPointsLayer
|