import * as T from '@turf/turf'
import { Log, defaultValue } from '../../util'
import { GeometryType } from '../enum'
import {
Circle,
Extent,
LineString,
MultiLineString,
MultiPolygon,
Point,
Polygon,
MultiPoint,
GeometryEngine
} from './index'
import { Feature } from '../feature'
/**
* @function createGeometry
* @private
* @param options 生成参数
* @description 根据参数生成几何
* @return Geometry 生成的几何对象
*/
function createGeometry(options) {
options = defaultValue(options, {})
switch (options.type) {
case GeometryType.point:
return new Point(options)
case GeometryType.multiPoint:
return new MultiPoint(options)
case GeometryType.lineString:
return new LineString(options)
case GeometryType.multiLineString:
return new MultiLineString(options)
case GeometryType.polygon:
return new Polygon(options)
case GeometryType.multiPolygon:
return new MultiPolygon(options)
case GeometryType.circle:
return new Circle(options)
case GeometryType.extent:
return new Extent(options)
default:
Log.error('未输入正确的几何类型')
}
}
/**
* @function createGeometryByGeoJSON
* @private
* @param options 生成参数
* @description 根据参数生成几何
* @return Geometry 生成的几何对象
*/
function createGeometryByGeoJSON(geojson) {
let geometry
if (geojson.type === 'Feature') {
geometry = geojson.geometry
} else {
geometry = geojson
}
switch (geometry.type) {
case GeometryType.point: {
return new Point({
coordinates: geometry.coordinates
})
}
case GeometryType.multiPoint: {
return new LineString({
coordinates: geometry.coordinates
})
}
case GeometryType.lineString:
return new LineString({
coordinates: geometry.coordinates
})
case GeometryType.multiLineString:
return new MultiLineString({
coordinates: geometry.coordinates
})
case GeometryType.polygon:
return new Polygon({
coordinates: geometry.coordinates
})
case GeometryType.multiPolygon:
return new MultiPolygon({
coordinates: geometry.coordinates
})
default:
Log.error('无法解析geojson')
}
}
/**
* 通过三点弧段改造要素几何,打散成离散点
* @param {Feature} feature 要素对象
* @return {Feature} 改造后的要素对象
* */
function editFeatureByArc3(feature) {
// 拷贝要素
let _feature = Feature.fromJSON(feature)
// 生成一个弧段几何
const _arcGeometry = GeometryEngine.getArcFromGeometry({
geometry: _feature.geometry,
arcInfo: _feature.additional.arc3
})
// 转成json数据
const _featureJSON = _feature.toJSON()
// 更新点坐标
_featureJSON.geometry.coordinates = _arcGeometry.coordinates
// 构造一个新的要素
_feature = Feature.fromJSON(_featureJSON)
return _feature
}
/**
* 通过三点弧段改造几何对象,打散成离散点
* @param {Geometry} geometry 几何对象
* @param {Object} additional 额外参数
* @return {Geometry} 改造后的几何对象
* */
function editGeometryByArc3(geometry, additional) {
// 判断是不是三点弧段
if (additional && additional.arc3) {
// 生成一个弧段几何
return GeometryEngine.getArcFromGeometry({
geometry,
arcInfo: additional.arc3
})
}
return geometry
}
/**
* 计算并返回多边形的外包盒
* @param {Array} coordinates 坐标点
* @param {Boolean} hasZ 是否是三维
* @param {GeometryType} type 几何类型
* @returns {Extent} 外包盒对象
* */
function calcExtent(coordinates, hasZ, type) {
type = defaultValue(type, GeometryType.polygon)
let _geometry
switch (type) {
case GeometryType.polygon:
_geometry = T.polygon(coordinates)
break
case GeometryType.lineString:
_geometry = T.lineString(coordinates)
break
case GeometryType.multiPolygon:
_geometry = T.multiPolygon(coordinates)
break
case GeometryType.multiLineString:
_geometry = T.multiLineString(coordinates)
break
default:
break
}
const bbox = T.bbox(_geometry)
if (!hasZ) {
return new Extent({
xmin: bbox[0],
ymin: bbox[1],
xmax: bbox[2],
ymax: bbox[3]
})
}
const _zValues = []
switch (type) {
case GeometryType.polygon:
case GeometryType.multiLineString:
for (let i = 0; i < coordinates.length; i++) {
for (let j = 0; j < coordinates[i].length; j++) {
_zValues.push(coordinates[i][j][2])
}
}
break
case GeometryType.lineString:
for (let i = 0; i < coordinates.length; i++) {
_zValues.push(coordinates[i][2])
}
break
case GeometryType.multiPolygon:
for (let i = 0; i < coordinates.length; i++) {
for (let j = 0; j < coordinates[i].length; j++) {
for (let k = 0; k < coordinates[i][j].length; k++) {
_zValues.push(coordinates[i][j][k][2])
}
}
}
break
default:
break
}
_zValues.sort(function (a, b) {
return a - b
})
const _zmin = _zValues[0]
const _zmax = _zValues[_zValues.length - 1]
return new Extent({
xmin: bbox[0],
ymin: bbox[1],
xmax: bbox[2],
ymax: bbox[3],
zmin: _zmin,
zmax: _zmax
})
}
export {
createGeometry,
createGeometryByGeoJSON,
editFeatureByArc3,
editGeometryByArc3,
calcExtent
}