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

commonMain.jetbrains.datalore.base.spatial.GeoRectangle.kt Maven / Gradle / Ivy

There is a newer version: 4.5.3-alpha1
Show newest version
/*
 * Copyright (c) 2020. JetBrains s.r.o.
 * Use of this source code is governed by the MIT license that can be found in the LICENSE file.
 */

package jetbrains.datalore.base.spatial

import jetbrains.datalore.base.gcommon.collect.ClosedRange
import jetbrains.datalore.base.typedGeometry.Rect
import jetbrains.datalore.base.typedGeometry.Vec
import jetbrains.datalore.base.typedGeometry.newSpanRectangle

class GeoRectangle(startLongitude: Double, minLatitude: Double, endLongitude: Double, maxLatitude: Double) {
    private val myLongitudeSegment: LongitudeSegment
    private val myLatitudeRange: ClosedRange

    val isEmpty: Boolean
        get() = myLongitudeSegment.isEmpty && latitudeRangeIsEmpty(myLatitudeRange)

    private fun latitudeRangeIsEmpty(range: ClosedRange): Boolean {
        return range.upperEnd == range.lowerEnd
    }

    init {
        require(minLatitude <= maxLatitude) { "Invalid latitude range: [$minLatitude..$maxLatitude]" }

        myLongitudeSegment = LongitudeSegment(startLongitude, endLongitude)
        myLatitudeRange = ClosedRange(minLatitude, maxLatitude)
    }

    fun startLongitude(): Double = myLongitudeSegment.start()
    fun endLongitude(): Double = myLongitudeSegment.end()

    fun minLatitude(): Double = myLatitudeRange.lowerEnd
    fun maxLatitude(): Double = myLatitudeRange.upperEnd

    fun encloses(rect: GeoRectangle): Boolean {
        return myLongitudeSegment.encloses(rect.myLongitudeSegment) && myLatitudeRange.encloses(rect.myLatitudeRange)
    }

    fun splitByAntiMeridian(): List> {
        val rects = ArrayList>()

        val longitudeRanges = myLongitudeSegment.splitByAntiMeridian()
        for (longitudeRange in longitudeRanges) {
            rects.add(
                newSpanRectangle(
                    Vec(longitudeRange.lowerEnd, myLatitudeRange.lowerEnd),
                    Vec(longitudeRange.upperEnd, myLatitudeRange.upperEnd)
                )
            )
        }
        return rects
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other == null || this::class != other::class) return false
        val that = other as GeoRectangle?
        return myLongitudeSegment == that!!.myLongitudeSegment && myLatitudeRange == that.myLatitudeRange
    }

    override fun hashCode(): Int {
        return listOf(myLongitudeSegment, myLatitudeRange).hashCode()
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy