Created
March 2, 2015 18:18
-
-
Save velvia/69ca1ab5e758d3b0ab13 to your computer and use it in GitHub Desktop.
JTS custom CoordinateSequence example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.vividsolutions.jts.geom._ | |
import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence | |
import com.vividsolutions.jts.geom.util.GeometryTransformer | |
/** | |
* A custom CoordSequence based on byte arrays for compactness and speed | |
* Just 2 dimensions for now. | |
* | |
* It's an example of creating a custom CoordinateSequence. | |
* NOTE: This is much more memory efficient, but slower because of deserialization cost. | |
* To achieve both speed and memory efficiency, the JTS libraries need to be modified to stop | |
* relying on Coordinate[]'s and more of the other methods. | |
*/ | |
class ByteArrayCoordSequence(coords: Array[Coordinate]) extends XYReadOnlyCoordSequence { | |
val xArray: Array[Double] = coords.map(_.x) | |
val yArray: Array[Double] = coords.map(_.y) | |
def getCoordinate(i: Int): Coordinate = | |
new Coordinate(xArray(i), yArray(i)) | |
// A mutable method to set the coordinate instance | |
def getCoordinate(i: Int, coord: Coordinate): Unit = { | |
coord.x = xArray(i) | |
coord.y = yArray(i) | |
} | |
def getX(i: Int): Double = xArray(i) | |
def getY(i: Int): Double = yArray(i) | |
def size(): Int = xArray.size | |
def expandEnvelope(env: Envelope): Envelope = { | |
env.expandToInclude(xArray.min, yArray.min) | |
env.expandToInclude(xArray.max, yArray.max) | |
env | |
} | |
} | |
trait XYReadOnlyCoordSequence extends CoordinateSequence { | |
def getCoordinate(i: Int): Coordinate | |
def getCoordinate(i: Int, coord: Coordinate): Unit | |
def getX(i: Int): Double | |
def getY(i: Int): Double | |
def size(): Int | |
def getDimension(): Int = 2 | |
def getCoordinateCopy(i: Int): Coordinate = getCoordinate(i) | |
def getOrdinate(index: Int, ordinateIndex: Int): Double = { | |
require(ordinateIndex < 2, "only 2 dimensions!") | |
ordinateIndex match { | |
case 0 => getX(index) | |
case 1 => getY(index) | |
} | |
} | |
def setOrdinate(index: Int, ordinateIndex: Int, value: Double) = ??? | |
def toCoordinateArray(): Array[Coordinate] = | |
(0 until size()).map(getCoordinate).toArray | |
} | |
object GeometryConverter { | |
// To easily transform another geometry to use our custom CoordinateSequence, do transformer.transform(geo) | |
val transformer = new GeometryTransformer { | |
override def transformCoordinates(coordSeq: CoordinateSequence, parent: Geometry): CoordinateSequence = { | |
new ByteArrayCoordSequence(coordSeq.toCoordinateArray) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment