import {
Projection,
SpatialReference,
GeometryType,
defaultValue,
editGeometryByArc3
} from '@mapgis/webclient-common'
import * as L from '@mapgis/leaflet'
// @function coordsToLatLng(coords: Array): LatLng
// Creates a `LatLng` object from an array of 2 numbers (longitude, latitude)
// or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points.
function coordsToLatLng(coords) {
if (coords.length > 2) {
return new L.LatLng(coords[1], coords[0], coords[2])
}
return new L.LatLng(coords[1], coords[0])
}
// @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array
// Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array.
// `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default).
// Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function.
function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) {
const latlngs = []
for (let i = 0, len = coords.length, latlng; i < len; i++) {
latlng = levelsDeep
? coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng)
: (_coordsToLatLng || coordsToLatLng)(coords[i])
latlngs.push(latlng)
}
return latlngs
}
function transformToWGS84(spatialReference, geo) {
if (String(spatialReference.wkid) !== '4326') {
geo.spatialReference = spatialReference
return Projection.project(geo, new SpatialReference('EPSG:4326'))
}
return geo
}
// 二维转换geometry
class ConvertGeometryUtil {
/**
* @description 转换为leaflet坐标数组,注意leaflet的经纬度对象放置顺序是反的[lat,lng]
* @param {*} geometry
* @param {*} options
* @return {*}
*/
static toLeafletCoords(geometry, options) {
let latlngs = []
// 后面需要考虑几何上坐标系的问题,在此处统一转换为经纬度数据
const opt = defaultValue(options, {})
// 额外参数
const additional = defaultValue(opt.additional, undefined)
// 坐标系转换
let spatialReference = defaultValue(
SpatialReference.fromJSON(opt.spatialReference),
new SpatialReference('EPSG:4326')
)
if (geometry.spatialReference) {
spatialReference = geometry.spatialReference
}
switch (geometry.type) {
case GeometryType.point: {
let geo = geometry.clone()
geo = transformToWGS84(spatialReference, geo)
const coordinates = geo.coordinates
latlngs.push(coordsToLatLng(coordinates))
break
}
case GeometryType.multiPoint: {
let geo = geometry.clone()
geo = transformToWGS84(spatialReference, geo)
const coordinates = geo.coordinates
latlngs = coordsToLatLngs(coordinates, 0, coordsToLatLng)
break
}
case GeometryType.lineString: {
let geo = geometry.clone()
// 处理三点弧段几何
geo = editGeometryByArc3(geo, additional)
geo = transformToWGS84(spatialReference, geo)
const coordinates = geo.coordinates
latlngs = coordsToLatLngs(coordinates, 0, coordsToLatLng)
break
}
case GeometryType.multiLineString: {
let geo = geometry.clone()
// 处理三点弧段几何
geo = editGeometryByArc3(geo, additional)
geo = transformToWGS84(spatialReference, geo)
const coordinates = geo.coordinates
latlngs = coordsToLatLngs(coordinates, 1, coordsToLatLng)
break
}
case GeometryType.polygon: {
let geo = geometry.clone()
// 处理三点弧段几何
geo = editGeometryByArc3(geo, additional)
geo = transformToWGS84(spatialReference, geo)
const coordinates = geo.coordinates
latlngs = coordsToLatLngs(coordinates, 1, coordsToLatLng)
break
}
case GeometryType.multiPolygon: {
let geo = geometry.clone()
// 处理三点弧段几何
geo = editGeometryByArc3(geo, additional)
geo = transformToWGS84(spatialReference, geo)
const coordinates = geo.coordinates
latlngs = coordsToLatLngs(coordinates, 2, coordsToLatLng)
break
}
case GeometryType.extent: {
let geo = geometry.clone()
geo = transformToWGS84(spatialReference, geo)
const minX = geo.xmin
const maxX = geo.xmax
const minY = geo.ymin
const maxY = geo.ymax
latlngs.push([minY, minX])
latlngs.push([maxY, maxX])
break
}
case GeometryType.circle: {
let geo = geometry.clone()
geo = transformToWGS84(spatialReference, geo)
const center = geo.center
latlngs.push([center[1], center[0]])
break
}
default: {
break
}
}
return latlngs
}
}
export default ConvertGeometryUtil