Skip to content

Instantly share code, notes, and snippets.

@k4200
Created June 15, 2012 08:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k4200/2935406 to your computer and use it in GitHub Desktop.
Save k4200/2935406 to your computer and use it in GitHub Desktop.
Handling MySQL point type with Squeryl
// 1. Class for MySQL point type
class MySQLPoint(val lat: Double, val lng: Double) {
import MySQLPoint._
override def toString = {
lat.toString() + "," + lng.toString()
}
/**
* Gets a binary representation
*/
def asBinary: Array[Byte] = {
val srid: Array[Byte] = Array(0, 0, 0, 0)
val byteOrder: Array[Byte] = Array(1) //Little endian
val wkbType: Array[Byte] = Array(1, 0, 0, 0) //TODO hard coded
val latBinary = doubleToByteArray(lat)
val lngBinary = doubleToByteArray(lng)
srid ++ byteOrder ++ wkbType ++ latBinary ++ lngBinary
}
}
object MySQLPoint {
def apply(binary: Array[Byte]) = {
val latBinary = binary.slice(9, 17)
val lngBinary = binary.slice(17, 25)
new MySQLPoint(byteArrayToDouble(latBinary), byteArrayToDouble(lngBinary))
}
}
// 2. Utilities that handles ByteArray
import java.nio.ByteBuffer
import java.nio.ByteOrder
object ByteArrayUtils {
def printByteArray(ba: Array[Byte]) = {
for(b <- ba) {
print(Integer.toString( ( b & 0xff ) + 0x100, 16).substring( 1 ) + " ")
}
println
}
def byteArrayToDouble(ba: Array[Byte], byteOrder: ByteOrder = ByteOrder.LITTLE_ENDIAN): Double = {
val bb = ByteBuffer.wrap(ba)
bb.order(byteOrder)
val langval = bb.getLong()
java.lang.Double.longBitsToDouble(langval)
}
def doubleToByteArray(d: Double, byteOrder: ByteOrder = ByteOrder.LITTLE_ENDIAN): Array[Byte] = {
val longval = java.lang.Double.doubleToLongBits(d)
ByteBuffer.allocate(8).order(byteOrder).putLong(longval).array()
}
}
// 3. Entity that uses MySQLPoint
class Foo(
@Column("foo_id")
val id: Long,
@Column("latlng")
var rawLatLng: Array[Byte])
extends KeyedEntity[Long] {
def this() = {
this(0L, null)
}
def this(id: Long, latLng: MySQLPoint) = {
this(id, latLng.asBinary)
}
def latLng: MySQLPoint = {
MySQLPoint(rawLatLng)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment