Created
June 15, 2012 08:30
-
-
Save k4200/2935406 to your computer and use it in GitHub Desktop.
Handling MySQL point type with Squeryl
This file contains 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
// 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