import Zondy from '../Zondy'
import { Log, defaultValue, defined } from '../../util'
/**
* 空间参考系
* <br><br>[ES5引入方式]:<br/>
* Zondy.SpatialReference() <br/>
* [ES6引入方式]:<br/>
* import { SpatialReference } from "@mapgis/webclient-common" <br/>
* <br/>
* @class SpatialReference
* @moduleEX GeometryModule
* @param {Object|String} options 构造参数
* @param {Number|undefined} [options.wkid] 空间参考系的wkid
* @param {String|undefined} [options.wkt] 空间参考系Well Known Text 或 proj4js字符串,仅支持proj4js能够支持的字符串。OGC WKT标准{@link https://www.ogc.org/standard/wkt-crs/}, EPSG坐标系查询{@link https://epsg.io/}
* @param {String|undefined} [options.unit] 空间参考系单位
*/
class SpatialReference {
constructor(options) {
options = defaultValue(options, {})
const { wkid, wkt } = this._parseSpatialReferenceOptions(options)
/**
* 投影坐标系的id
* @member {Number} SpatialReference.prototype.wkid
*/
this.wkid = wkid
/**
* 投影坐标系的描述
* @member {String|undefined} SpatialReference.prototype.wkt
*/
this.wkt = wkt
/**
* 投影坐标系的描述
* @member {String|undefined} SpatialReference.prototype.unit
*/
this.unit = options.unit
}
/**
* 是否是WGS84相关坐标系
* @readonly
* @type {Boolean}
*/
get isWGS84() {
return this.wkid === 4326
}
/**
* 是否是地理坐标系
* @readonly
* @type {Boolean}
*/
get isGeographic() {
if ([4326, 4490, 4610, 4214].indexOf(this.wkid) > -1) {
return true
}
return false
}
/**
* 是否是Web墨卡托坐标系
* @readonly
* @type {Boolean}
*/
get isWebMercator() {
if ([102113, 102100, 900913, 3857].indexOf(this.wkid) > -1) {
return true
}
return false
}
/**
* 坐标系否支持环绕国际日期线,当参考系是Web Mercator或WGS84
* @readonly
* @type {Boolean}
*/
get isWrappable() {
if (
[4326, 4490, 4610, 4214, 102113, 102100, 900913, 3857].indexOf(
this.wkid
) > -1
) {
return true
}
return false
}
/**
* 一个便捷的Web墨卡托对象,只有当类型为Web墨卡托时才有
* @readonly
* @type {SpatialReference}
*/
get WebMercator() {
return this.isWebMercator ? this.clone() : undefined
}
/**
* 一个便捷的WGS84对象,只有当类型为WGS84时才有
* @readonly
* @type {SpatialReference}
*/
get WGS84() {
return this.isGeographic ? this.clone() : undefined
}
/**
* @private
* @description: 解析传入的options
* @param {*} options
* @return {*}
*/
_parseSpatialReferenceOptions(options) {
let wkid = 4326
let wkt
if (typeof options === 'string') {
const req = /^(EPSG|epsg)(:)?\d+$/
const reqWkid = /\d+$/
const wkidStr = options.match(reqWkid)
if (req.test(options) && wkidStr) {
wkid = parseInt(wkidStr[0])
wkt = undefined
} else {
// 字符串设置为wkt
wkt = options
wkid = undefined
}
} else if (typeof options === 'object') {
if (defined(options['wkid'])) {
wkid = parseInt(options['wkid'])
}
if (options['wkt']) {
wkt = options['wkt']
wkid = undefined
}
} else {
Log.error('无法解析传入的空间参考系参数')
}
return {
wkid,
wkt
}
}
/**
* 克隆几何对象
* @return {Geometry} 克隆后的几何对象
*/
clone() {
return new SpatialReference(this.toJSON())
}
/**
* 将JSON里的数据导入到几何中
* @param {Object} json JSON对象
*/
static fromJSON(json) {
json = defaultValue(json, {})
return new SpatialReference(json)
}
/**
* 导出为json对象
* @return {Object} json对象
*/
toJSON() {
return {
wkid: this.wkid,
wkt: this.wkt
}
}
/**
* 导出为字符串(此处语义和设计不符,为igs服务参数专用,后续需要修改)
* @private
* @return {String} 坐标系字符串
*/
toString() {
let wkt = ''
switch (this.wkid) {
case 4326:
wkt = 'EPSG:4326'
break
case 3857:
wkt = 'EPSG:3857'
break
default:
wkt = this.wkt
}
return wkt
}
/**
* 判断坐标系对象的wkid和wkt的值是否相等
* @param {SpatialReference | Object} spatialReference 坐标系对象
* @return {Boolean} wkid和wkt的值是否相等
* */
equals(spatialReference) {
if (!(spatialReference instanceof SpatialReference)) {
if (
!(
spatialReference instanceof Object &&
spatialReference.hasOwnProperty('wkid') &&
spatialReference.hasOwnProperty('wkt')
)
) {
throw new Error('spatialReference的格式不正确!')
}
}
// 暂时无法保证wkt值一致,因此只比较wkid一致即可
if (this.wkid === spatialReference.wkid) {
return true
} else if (
this.wkt &&
spatialReference.wkt &&
this.wkt === spatialReference.wkt
) {
return true
}
return false
}
}
Zondy.SpatialReference = SpatialReference
export default SpatialReference