All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.tsingjyujing.geo.element.GeoBox.scala Maven / Gradle / Ivy

There is a newer version: 2.8.9-2.11
Show newest version
package com.github.tsingjyujing.geo.element

import com.github.tsingjyujing.geo.basic.IGeoPoint
import com.github.tsingjyujing.geo.basic.operations.IContains
import com.github.tsingjyujing.geo.element.immutable.GeoPoint

/**
  * A boundary box with min/max longitude/latitude
  *
  * @param minLongitude
  * @param maxLongitude
  * @param minLatitude
  * @param maxLatitude
  */
case class GeoBox(
                     minLongitude: Double,
                     maxLongitude: Double,
                     minLatitude: Double,
                     maxLatitude: Double
                 ) extends IContains[IGeoPoint] {

    assert(maxLongitude > minLongitude, "max longitude is less than min longitude: " + toString)
    assert(maxLatitude > minLatitude, "max latitude is less than min latitude: " + toString)

    override def contains(x: IGeoPoint): Boolean = (x.getLongitude > minLongitude && x.getLongitude < maxLongitude) && (x.getLatitude > minLatitude && x.getLatitude < maxLatitude)

    def anglePoints: Array[GeoPoint] = Array(
        GeoPoint(minLongitude, minLatitude),
        GeoPoint(minLongitude, maxLatitude),
        GeoPoint(maxLongitude, maxLatitude),
        GeoPoint(maxLongitude, minLatitude)
    )

    def getLongitudeRange = DoubleRange(minLongitude, maxLongitude)

    def getLatitudeRange = DoubleRange(minLatitude, maxLatitude)

    def isIntersect(b: GeoBox): Boolean = getLongitudeRange.isIntersect(b.getLongitudeRange) && getLatitudeRange.isIntersect(b.getLatitudeRange)

    /**
      * Get intersect zone of GeoBlock
      *
      * @param b geo-block
      * @return
      */
    def &(b: GeoBox): Option[GeoBox] = {
        val longitudeRange = getLongitudeRange & b.getLongitudeRange
        val latitudeRange = getLatitudeRange & b.getLatitudeRange
        if (longitudeRange.isDefined && latitudeRange.isDefined) {
            Option(GeoBox(longitudeRange.get, latitudeRange.get))
        } else {
            None
        }
    }

    /**
      * {{{
      *     assert x as longitude and y as latitude
      *     \delta_{x} = max longitude - min longitude
      *     y1 = max latitude
      *     y0 = min latitude
      *     S = R \times \Delta{x} \times \int_{y_0}^{y_1}{ cos(y) dy \times R}
      * }}}
      *
      * @return
      */
    def area: Double = IGeoPoint.EARTH_RADIUS * IGeoPoint.EARTH_RADIUS * (maxLongitude - minLongitude).toRadians * (math.sin(maxLatitude.toRadians) - math.sin(minLatitude.toRadians))

    /**
      * Get polygon of this block
      * @return
      */
    def toPolygon:GeoPolygon = GeoPolygon(anglePoints)
}

object GeoBox {

    def apply(points: Iterable[IGeoPoint]): GeoBox = GeoBox(
        points.map(_.getLongitude).min,
        points.map(_.getLongitude).max,
        points.map(_.getLatitude).min,
        points.map(_.getLatitude).max
    )

    def apply(
                 longitudeRange: DoubleRange,
                 latitudeRange: DoubleRange
             ): GeoBox = GeoBox(
        longitudeRange.min,
        longitudeRange.max,
        latitudeRange.min,
        latitudeRange.max
    )
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy