类名 util/convertFeatureToLeafletGraphicUtil.js
// 要素转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 = new 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
}
构造函数
成员变量
方法
事件