    // 要素转leaflet图元
    import {
      Log,
      GeometryType,
      SymbolType,
      Feature,
      SimpleMarkerSymbol
    } from '@mapgis/webclient-common'
    import * as L from '@mapgis/leaflet'
    import ConvertGeometryUtil from './ConvertGeometryUtil'
    import ConvertSymbolUtil from './ConvertSymbolUtil'
    import LeafletPlugin from './LeafletPlugin'

    const toLeafletCoords = ConvertGeometryUtil.toLeafletCoords
    const toLeafletStyle = ConvertSymbolUtil.convertSymboltoLeafletStyle

    /**
     * @description 根据类型创建marker
     * @public
     * @param {*} type
     * @param {*} coords
     * @param {*} style
     * @return {*}
     */
    function createGraphic(symbolType, coords, style) {
      let graphic
      switch (symbolType) {
        case SymbolType.simpleMarker: {
          graphic = L.shapeMarker(coords, style)
          break
        }
        case SymbolType.pictureMarker: {
          graphic = L.marker(coords, style)
          break
        }
        case SymbolType.line: {
          graphic = L.polyline(coords, style)
          break
        }
        case SymbolType.text: {
          graphic = L.marker(coords, style)
          break
        }
        case SymbolType.fill: {
          graphic = L.polygon(coords, style)
          break
        }
        case SymbolType.pictureFill: {
          graphic = L.polygon(coords, style)
          break
        }
        default: {
          Log.error('符号类型错误，不合法的符号类型')
        }
      }
      return graphic
    }

    function convertPointToGraphic(feature) {
      const coords = toLeafletCoords(feature.geometry)
      const style = toLeafletStyle(feature.symbol)
      const symbolType = feature.symbol.type
      return createGraphic(symbolType, coords[0], style)
    }

    function convertMultiPointToGraphic(feature) {
      const coords = toLeafletCoords(feature.geometry)
      const style = toLeafletStyle(feature.symbol)
      const symbolType = feature.symbol.type
      const layers = []
      coords.forEach((coord) => {
        const marker = createGraphic(symbolType, coord, style)
        layers.push(marker)
      })
      return new L.FeatureGroup(layers)
    }

    function convertPolylineMarker(marker, width, coordinates) {
      const layers = []
      if (marker) {
        const { color, style, placement } = marker
        const markerDetail = LeafletPlugin.calcLineMarkerDetail(coordinates)
        const { angle1, angle2, latlng1, latlng2 } = markerDetail
        const leafletStyle = toLeafletStyle(
          new SimpleMarkerSymbol({
            angle: angle1,
            color,
            outline: {
              color,
              width
            },
            style,
            size: Math.max(15, 4 * width)
          })
        )

        const p1 = createGraphic(SymbolType.simpleMarker, latlng1, leafletStyle)
        const p2 = createGraphic(
          SymbolType.simpleMarker,
          latlng2,
          toLeafletStyle(
            new SimpleMarkerSymbol({
              angle: angle2,
              color,
              outline: {
                color,
                width
              },
              style,
              size: Math.max(15, 4 * width)
            })
          )
        )
        if (placement === 'begin') {
          layers.push(p1)
        } else if (placement === 'end') {
          layers.push(p2)
        } else {
          layers.push(p1)
          layers.push(p2)
        }
      }
      return layers
    }

    function updatePolylineMarkers(feature, graphic) {
      if (graphic['__marker__group']) {
        graphic.removeLayer(graphic['__marker__group'])
      }
      const width = feature.symbol.width
      const marker = feature.symbol.marker
      const layers = convertPolylineMarker(
        marker,
        width,
        feature.geometry.coordinates
      )
      const markerGroup = new L.FeatureGroup(layers)
      graphic['__marker__group'] = markerGroup
      graphic.addLayer(markerGroup)
    }

    function updateMultiPolylineMarkers(feature, graphic) {
      if (graphic['__marker__group']) {
        graphic.removeLayer(graphic['__marker__group'])
      }
      const width = feature.symbol.width
      const marker = feature.symbol.marker
      let layers = []
      feature.geometry.coordinates.forEach((coords) => {
        const v = convertPolylineMarker(marker, width, coords)
        layers = layers.concat(v)
      })
      const markerGroup = new L.FeatureGroup(layers)
      graphic['__marker__group'] = markerGroup
      graphic.addLayer(markerGroup)
    }

    function convertPolylineToGraphic(feature) {
      const coords = toLeafletCoords(feature.geometry, {
        additional: feature.additional
      })
      const style = toLeafletStyle(feature.symbol)
      const symbolType = feature.symbol.type
      const featureGroup = new L.FeatureGroup()
      const lineGraphic = createGraphic(symbolType, coords, style)
      featureGroup['__line__graphic'] = lineGraphic
      featureGroup.addLayer(lineGraphic)
      // 转换线首尾角marker
      if (feature.symbol.marker) {
        updatePolylineMarkers(feature, featureGroup)
      }
      return featureGroup
    }

    function convertMultiLineStringToGraphic(feature) {
      const coords = toLeafletCoords(feature.geometry, {
        additional: feature.additional
      })
      const style = toLeafletStyle(feature.symbol)
      const symbolType = feature.symbol.type
      const featureGroup = new L.FeatureGroup()
      const lineGraphic = createGraphic(symbolType, coords, style)
      featureGroup['__line__graphic'] = lineGraphic
      featureGroup.addLayer(lineGraphic)
      // 转换线首尾角marker
      if (feature.symbol.marker) {
        updateMultiPolylineMarkers(feature, featureGroup)
      }
      return featureGroup
    }

    function getAreaCoords(symbolType, geometry, feature) {
      let coords
      // 如果类型为点，则重新设置几何
      if (
        SymbolType.simpleMarker === symbolType ||
        SymbolType.text === symbolType ||
        SymbolType.pictureMarker === symbolType
      ) {
        coords = LeafletPlugin.getAreaCenter(geometry)
      } else {
        coords = toLeafletCoords(geometry, {
          additional: feature.additional
        })
      }

      return coords
    }

    function convertPolygonToGraphic(feature) {
      const style = toLeafletStyle(feature.symbol)
      const symbolType = feature.symbol.type
      const coords = getAreaCoords(symbolType, feature.geometry, feature)
      return createGraphic(symbolType, coords, style)
    }

    function convertCircleToGraphic(feature) {
      const style = toLeafletStyle(feature.symbol)
      const symbolType = feature.symbol.type
      const coords = getAreaCoords(
        symbolType,
        feature.geometry.toPolygon(),
        feature
      )
      return createGraphic(symbolType, coords, style)
    }

    function convertExtentToGraphic(feature) {
      const style = toLeafletStyle(feature.symbol)
      const symbolType = feature.symbol.type
      const coords = getAreaCoords(symbolType, feature.geometry, feature)
      if (symbolType !== SymbolType.simpleFill) {
        return createGraphic(symbolType, coords, style)
      }
      return L.rectangle(coords, style)
    }

    /**
     * @description 转换要素为几何图形
     * @public
     * @param {Feature} feature
     * @return {*}
     */
    function convertFeature(feature) {
      let graphic = null
      if (!(feature instanceof Feature)) return graphic
      if (!feature.geometry) {
        Log.error('几何不存在')
        return graphic
      }
      switch (feature.geometry.type) {
        case GeometryType.point: {
          graphic = convertPointToGraphic(feature)
          break
        }
        case GeometryType.lineString: {
          graphic = convertPolylineToGraphic(feature)
          break
        }
        case GeometryType.multiPolygon:
        case GeometryType.polygon: {
          graphic = convertPolygonToGraphic(feature)
          break
        }
        case GeometryType.extent: {
          graphic = convertExtentToGraphic(feature)
          break
        }
        case GeometryType.circle: {
          graphic = convertCircleToGraphic(feature)
          break
        }
        case GeometryType.multiPoint: {
          graphic = convertMultiPointToGraphic(feature)
          break
        }
        case GeometryType.multiLineString: {
          graphic = convertMultiLineStringToGraphic(feature)
          break
        }
        default: {
          break
        }
      }
      return graphic
    }

    export {
      convertFeature,
      createGraphic,
      updatePolylineMarkers,
      updateMultiPolylineMarkers,
      getAreaCoords
    }