类名 common/base/ArcGisGeometry/Extent.js
import * as T from '@turf/turf'
import * as H from '@turf/helpers'
import { extend, notNULL } from '../../util'
import Zondy from '../Zondy'
import ArcGisGeometry from './Geometry'
import ArcGisPoint from './Point'

function initCenter(me) {
  const points = [
    H.point([me.xmin, me.ymin]),
    H.point([me.xmin, me.ymax]),
    H.point([me.xmax, me.ymax]),
    H.point([me.ymax, me.ymin]),
    H.point([me.xmin, me.ymin])
  ]
  const featureCollection = H.featureCollection(points)
  const coordinates = T.center(featureCollection).geometry.coordinates
  return new ArcGisPoint({
    longitude: coordinates[0],
    latitude: coordinates[1]
  })
}

/**
 * @class module:ArcGis.ArcGisExtent
 * @description ArcGisExtent对象
 * @author 基础平台-杨琨
 * @param options - {Object} 必选项,构造Extent对象参数。
 * @param {String} [query.xmin] 可选项,x轴最小坐标。
 * @param {String} [query.ymin] 可选项,x轴最大坐标。
 * @param {String} [query.ymin] 可选项,y轴最小坐标。
 * @param {String} [query.ymax] 可选项,y轴最小坐标。
 * @param {String} [query.zmin] 可选项,z轴最小坐标。
 * @param {String} [query.zmax] 可选项,z轴最小坐标。
 * @param {String} [query.mmin] 可选项,m轴最小坐标。
 * @param {String} [query.mmax] 可选项,m轴最小坐标。
 */

class ArcGisExtent extends ArcGisGeometry {
  constructor(options) {
    super(options)
    this.center = undefined
    this.hasM = false
    this.hasZ = false
    this.height = 0
    this.mmax = undefined
    this.mmin = undefined
    this.type = 'extent'
    this.width = 0
    this.xmax = 0
    this.xmin = 0
    this.ymax = 0
    this.ymin = 0
    this.zmax = undefined
    this.zmin = undefined
    this.extent = this

    // 确保私有变量不能被options修改
    this.private = [
      'center',
      'hasM',
      'hasZ',
      'height',
      'width',
      'type',
      'extent'
    ]
    for (const key in this.private) {
      if (notNULL(options[this.private[key]])) {
        throw new Error(
          `[accessor] cannot assign to read-only property '${this.private[key]}' of ArcGisExtent`
        )
      }
    }

    extend(this, options)

    // 如果z、m有值,hasZ、hasM采薇true
    if (this.zmax || this.zmin) {
      this.hasZ = true
    }
    if (this.mmax || this.mmin) {
      this.hasM = true
    }

    // 生成bbox
    this._extentPolygon = T.polygon(
      [
        [
          [this.xmin, this.ymin],
          [this.xmin, this.ymax],
          [this.xmax, this.ymax],
          [this.ymax, this.ymin],
          [this.xmin, this.ymin]
        ]
      ],
      { name: '_extentPlygon' }
    )

    // 生成中心点
    this.center = initCenter(this)

    // 计算width,height
    this.width = this.xmax - this.xmin
    this.height = this.ymax - this.ymin
  }
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.equals
 * @description 比较两个Extent对象是否相等
 * @param extent - {ArcGisExtent} 必选项,要比较的ArcGisExtent对象。
 * @returns Boolean,对象是否相等
 */
ArcGisExtent.prototype.equals = function (extent) {
  return (
    this.mmax === extent.mmax &&
    this.mmin === extent.mmin &&
    this.xmax === extent.xmax &&
    this.xmin === extent.xmin &&
    this.ymax === extent.ymax &&
    this.ymin === extent.ymin &&
    this.zmax === extent.zmax &&
    this.zmin === extent.zmin
  )
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.contains
 * @description 判断是否包含一个点或者一个ArcGisExtent对象
 * @param geometry - {Geometry} 必选项,要比较的ArcGisExtent对象或者ArcGisPoint对象。
 * @returns Boolean,是否包含
 */
ArcGisExtent.prototype.contains = function (geometry) {
  if (geometry.type === 'point') {
    let point = geometry.toArray()
    point = T.point([point[0], point[1]])
    return T.booleanContains(this._extentPolygon, point)
  }
  if (geometry.type === 'extent') {
    return T.booleanContains(this._extentPolygon, geometry._extentPolygon)
  }
  return false
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.expand
 * @description 根据输入的值,扩大或缩小一个ArcGisExtent
 * @param factor - {Number} 必选项,放大或缩小系数。
 * @returns ArcGisExtent,缩放后的ArcGisExtent
 */
ArcGisExtent.prototype.expand = function (factor) {
  if (factor instanceof Number) {
    factor = Math.abs(factor)
    this.width *= factor
    this.height *= factor
    this.xmin = this.center.x - this.width / 2
    this.xmax = this.center.x + this.width / 2
    this.ymin = this.center.y - this.height / 2
    this.ymax = this.center.y + this.height / 2
    return this
  } else {
    throw new Error('require is not defined')
  }
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.intersects
 * @description 比较点、多点、线、多边形、extent是否与当前extent相交
 * @param geometry - {Geometry} 必选项,要比较的几何对象。
 * @returns Boolean,是否相交
 */
ArcGisExtent.prototype.intersects = function (geometry) {
  if (!geometry.type) {
    return false
  }
  let geom
  if (geometry.type === 'polyline') {
    geom = H.multiLineString(geometry.paths)
  } else if (geometry.type === 'point') {
    geom = H.point(geometry.toArray())
  } else if (geometry.type === 'multipoint') {
    geom = H.multiPoint(geometry.points)
  } else if (geometry.type === 'extent') {
    geom = geometry._extentPolygon
  } else if (geometry.type === 'polygon') {
    geom = H.polygon(geometry.rings)
  }
  return !T.booleanDisjoint(geom, this._extentPolygon)
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.offset
 * @description 根据输入的dx, dy, dz值,平移extend
 * @param dx - {Number} 必选项,要平移的x值。
 * @param dx - {Number} 必选项,要平移的y值。
 * @param dx - {Number} 必选项,要平移的z值。
 * @returns ArcGisExtent,平移后的ArcGisExtent对象
 */
ArcGisExtent.prototype.offset = function (dx, dy, dz) {
  this.xmax += dx
  this.xmin += dx
  this.ymax += dy
  this.ymin += dy
  if (this.hasZ) {
    this.zmax += dz
    this.zmin += dz
  } else {
    this.hasZ = true
    this.zmax = 0
    this.zmin = 0
  }
  return this
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.centerAt
 * @description 根据输入的ArcGisPoint对象,生成衣蛾新的中心点
 * @param point - {ArcGisPoint} 必选项,新的中心点。
 * @returns ArcGisExtent
 */
ArcGisExtent.prototype.centerAt = function (point) {
  if (point instanceof ArcGisPoint) {
    this.center = new ArcGisPoint({
      longitude: point.x,
      latitude: point.y
    })
    this.xmin = this.center.x - this.width / 2
    this.xmax = this.center.x + this.width / 2
    this.ymin = this.center.y - this.height / 2
    this.ymax = this.center.y + this.height / 2
    return this
  }
}

ArcGisExtent.prototype.normalize = function () {
  return [this]
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.union
 * @description 输入一个ArcGisExtent对象,与原extent对象合并,生成一个新的extent
 * @param extent - {ArcGisExtent} 必选项,要合并的ArcGisExtent对象。
 * @returns ArcGisExtent,新的Extent对象
 */
ArcGisExtent.prototype.union = function (extent) {
  const cur = this.center
  const nex = extent.center
  if (
    (nex.x - cur.x > 0 && nex.y - cur.y > 0) ||
    (nex.x - cur.x === 0 && nex.y - cur.y > 0) ||
    (nex.x - cur.x === 0 && nex.y - cur.y === 0) ||
    (nex.x - cur.x > 0 && nex.y - cur.y === 0)
  ) {
    this.xmax = extent.xmax
    this.ymax = extent.ymax
  } else if (
    (nex.x - cur.x > 0 && nex.y - cur.y < 0) ||
    (nex.x - cur.x === 0 && nex.y - cur.y < 0)
  ) {
    this.xmax = extent.xmax
    this.ymin = extent.ymin
  } else if (nex.x - cur.x < 0 && nex.y - cur.y < 0) {
    this.xmin = extent.xmin
    this.ymin = extent.ymin
  } else if (
    nex.x - cur.x < 0 &&
    (nex.y - cur.y || (nex.x - cur.x < 0 && nex.y - cur.y < 0)) === 0
  ) {
    this.xmin = extent.xmin
    this.ymax = extent.ymax
  }
  this.center = initCenter(this)
  // 计算width,height
  this.width = this.xmax - this.xmin
  this.height = this.ymax - this.ymin
  return this
}

/**
 * @function module:ArcGis.ArcGisExtent.prototype.toString
 * @description 返回如下格式的字符串:"xmin,ymin,xmax,ymax"
 * @returns Sting
 */
ArcGisExtent.prototype.toString = function () {
  return `${this.xmin},${this.ymin},${this.xmax},${this.ymax}`
}

export default ArcGisExtent
Zondy.Service.ArcGisExtent = ArcGisExtent
构造函数
成员变量
方法
事件