<script>
import commonMixin from '../base/mixins/common.js'
import { convertObjToStyle } from '../base/SymbolUtil.js'
import { GeometryType } from '../base/GeometryType.js'
import SymbolConfig from '../base/SymbolConfig.js'
import { covertObjToGeometry } from '../base/GeometryUtil.js'
import  Feature  from 'ol/Feature'
import GeoJSON from 'ol/format/GeoJSON'
import KML from 'ol/format/KML'
import VectorSource from 'ol/source/Vector'
import VectorLayer from 'ol/layer/Vector'
import Cluster from 'ol/source/Cluster'
import {bbox as bboxStrategy} from 'ol/loadingstrategy'
import {Circle as CircleStyle, Fill, RegularShape, Stroke, Style, Text, Icon} from 'ol/style'
import {createEmpty, getWidth, getHeight, extend} from 'ol/extent'
import Select from 'ol/interaction/Select'
// import SelectCluster from '../interaction/SelectCluster'
export default {
  name: 'sl-clusterlayer',
  render (h) { },
  mixins: [commonMixin('layer')],
  props: {
    id: {
      type: String,
      require: true
    },
    name: {
      type: String,
      require: true
    },
    features: {
      type: Array,
      default: function () {
        return []
      }
    },
    visible: {
      type: Boolean,
      default: true
    },
    zIndex: {
      type: Number,
      require: true,
      default: 6
    },
    clusterDistance: {
      type: Number,
      default: 20
    },
    url:{
      type: String
    },
    format:{
      type: String,
      default: "geojson"
    }
  },
  watch: {
    features (val) {
      if (this.url) {
        return
      }
      this.originInstance.getSource().clear()
      this.addFeatures()
    },
    visible (val) {
      this.originInstance.setVisible(val)
    },
    zIndex(val) {
      this.originInstance.setZIndex(val)
    }
  },
  data(){
    return {
      currentResolution: null, // 保存地图当前分辨率
      maxFeatureCount: 0  // 最大的要素数量
    }
  },
  methods: {
    // 初始化图层-----
    load () {
      const { id, name, $rootComponent,  clusterDistance, zIndex, url, format } = this
      if($rootComponent.isLayerExist(id)){
         $rootComponent.removeLayer(id)
      }
      let featureFormat = new GeoJSON()
      let style = this.styleFunction
      if (format === "kml") {
          featureFormat = new KML()
      }
      if (url) {
         let param =  {
              format: featureFormat,
              url: function(extent) {
                return url + '&bbox=' + extent.join(',') + ',EPSG:4326';
              },
              strategy: bboxStrategy
          }
         let source = new Cluster({
              source: new VectorSource(param),
              distance: clusterDistance
            })
         this.originInstance = new VectorLayer({
            source,
            id,
            name
         })
      } else {
        this.originInstance = new VectorLayer({
            source: new Cluster({
              source: new VectorSource({strategy: bboxStrategy}),
              distance: clusterDistance
            }),
            id,
            name
        })
         this.addFeatures()
      }
      this.originInstance.setZIndex(zIndex)
      this.originInstance.setStyle(style)
      this.map.addLayer(this.originInstance) 
      // this.map.addInteraction(new Select({
      //     condition: function(evt) {
      //       return evt.type == 'pointermove' ||
      //           evt.type == 'singleclick'
      //     },
      //     style: this.selectStyleFunction,
      //     layers:[this.originInstance]
      //   })) 
    },
    // 图层添加要素
    addFeatures () {
      const { features} = this
        let vectors = []
        for (var index in features) {
          var feature = features[index]
          let { geom, attributes, symbol } = feature
          var geometry = covertObjToGeometry(geom)
          var vector = new Feature()
          vector.setGeometry(geometry)
          if (attributes) {
            vector.set('attributes', attributes)
          }
          if (attributes && attributes.id) {
             vector.setId(attributes.id)
          }    
          if (symbol) {
            vector.set('symbol', symbol)
          } else {
            vector.set('symbol', {})
          }
          vectors.push(vector)
        }
        this.originInstance.getSource().getSource().addFeatures(vectors)
    },
    // 刷新图层（触发change事件）
    refresh () {
      const source = this.originInstance.getSource()
      source.refresh()
    },
    styleFunction(feature, resolution) {
        if (resolution != this.currentResolution) {
          this.calculateClusterInfo(resolution)
          this.currentResolution = resolution
        }
        var textFill = new Fill({
          color: '#fff'
        })
        var textStroke = new Stroke({
          color: 'rgba(0, 0, 0, 0.6)',
          width: 3
        })
        var style = null
        var size = feature.get('features').length
        if (size > 1) {
          style = new Style({
            image: new CircleStyle({
              radius: feature.get('radius'),
              fill: new Fill({
                color: [255, 153, 0, Math.min(0.8, 0.4 + (size / this.maxFeatureCount))]
              })
            }),
            text: new Text({
              text: size.toString(),
              fill: textFill,
              stroke: textStroke
            })
          })
        } else {
          var originalFeature = feature.get('features')[0]
          style = this.createFeatureStyle(originalFeature)
        }
        return style
      },
      createFeatureStyle(feature) {
        let sys = SymbolConfig.defaultClusterPointStyle
        let {src = sys.src, size, rotation = sys.srotation, opacity = sys.opacity, color} = feature.get("symbol")
        return new Style({
            geometry: feature.getGeometry(),
            image: new Icon({
              src,
              size,
              rotation,
              opacity,
              color
            })
        })
      },
      // 计算聚合信息-----胡红勋------
      calculateClusterInfo (resolution) {
        var vectors = this.originInstance.getSource().getFeatures()
        var vector = null
        var radius =0
        for (var i = vectors.length - 1; i >= 0; --i) {
          vector = vectors[i]
          var originalFeatures = vector.get('features')
          // 获取一空范围
          var extent = createEmpty()
          for (var j = 0; j < originalFeatures.length; ++j) {
            // 修改一范围包含另外一个范围----
            extend(extent, originalFeatures[j].getGeometry().getExtent())
          }
          this.maxFeatureCount = Math.max(this.maxFeatureCount, j)
          radius = 0.25 * (getWidth(extent) + getHeight(extent)) /resolution
          vector.set('radius', radius)
        }
      },
      selectStyleFunction(feature) {
        let invisibleFill = new Fill({
          color: 'rgba(255, 255, 255, 0.01)'
       })
        var styles = [new Style({
          image: new CircleStyle({
            radius: feature.get('radius'),
            fill: invisibleFill
          })
        })]
        var originalFeatures = feature.get('features')
        var originalFeature = null
        for (var i = originalFeatures.length - 1; i >= 0; --i) {
          originalFeature = originalFeatures[i]
          styles.push(this.createFeatureStyle(originalFeature))
        }
        return styles
      }
  }
}
</script>
