Keywords: Tilastokeskus, Ruututietokanta, GPS, WGS84, EUREF-FIN, ETRS89-TM35FIN
The Grid database contains 250m x 250m squares. The square is definied by the x- and y-koordinates of the lower left corner of the grid. This corner defines the square. In the database, they are even meters without decimals.
This example is using Scala and the Sanoma-CDA / maxmind-geoip2-scala library. To use that library, you should doanload it and publish either locally or to your artifactory.
Conversion is done simply by:
import com.sanoma.cda.geo.Point
import com.sanoma.cda.geo.CoordinateConversions._
val GPS_point = Point(60.1672065,24.943796)
val EUREF_FIN = wgs842etrs89tm35fin(GPS_point)
// EUREF_FIN: (Double, Double) = (6671809.459860587,385901.3059246596)
Matching to DB squares is easy as you recall that the square is defined by the lower left corner. Therefore define a helper function:
def floorTo250m(c: Double) = {
def toStr(d: Double) = d.intValue.toString
val floored = math.floor(c / 250.0) * 250.0
toStr(floored)
}
// and I suggest you combine the coordinates for example like this (and do the same in the DB):
def pointToGridID(p: (Double, Double)): String = {
floorTo250m(p._1) + ":" +floorTo250m(p._2)
}
// For example:
val gridID = pointToGridID(EUREF_FIN)
//gridID: String = 6671750:385750
And then you can use that gridID to join to the data in the Grid DB if you created the same concatenated field in there (or join with 2 fields if you didn't concatenate these).
If you need to plot the squares with GPS coordinates, you should probably convert all the square corners separately, like this:
val lowerLeftCorner = ("6671750","385750")
def gridIDToGPSSquare(llc: (String, String)) = {
val northing = llc._1.toDouble
val easting = llc._2.toDouble
val corners = List(
(northing, easting),
(northing + 250, easting),
(northing, easting + 250),
(northing + 250, easting + 250)
)
corners.map(etrs89tm35fin2wgs84)
}
gridIDToGPSSquare(lowerLeftCorner)
//List[com.sanoma.cda.geo.Point] = List(Point(60.16663063879607,24.94110472172945), Point(60.16887394708703,24.940964317230154), Point(60.166700521644,24.94560657539308), Point(60.168943836243876,24.945466477366548))
Or you can create a KML out of this for example like this:
import com.sanoma.cda.geo._
import com.sanoma.cda.geo.KML._
val square = Polygon(gridIDToGPSSquare(lowerLeftCorner))
val squarePlacemark = polygon2KMLPlacemark(poly = square, name = "test square", height = 1.0, lineColorHex = Some(rgb2KMLColor(rgb = (1.0, 0.0, 0.0))), polyColorHex = Some(rgba2KMLColor(1.0, 0.0, 0.0, 0.7)))
val docs = List(getKMLFolder("squares", List(squarePlacemark)))
val master = getKMLMasterDoc(docs)
// and then write it like this:
import scala.xml.XML
val out = new java.io.PrintWriter("foo.kml")
XML.write(out, master, "utf-8", xmlDecl = true, doctype = null)
out.close
// master is:
/*
master: scala.xml.Elem =
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="Geo areas">
<open>1</open>
<Folder id="squares">
<name>squares</name>
<open>0</open>
<visibility>1</visibility>
<Placemark>
<name>test square</name>
<visibility>1</visibility>
<Style>
<LineStyle><color>FF0000FF</color></LineStyle><PolyStyle><color>B30000FF</color></PolyStyle>
</Style>
<Polygon id="P_test square">
<extrude>1</extrude>
<altitudeMode>relativeToGround</altitudeMode>
<outerBoundaryIs>
<LinearRing id="LR_test square">
<coordinates>
24.94110472172945,60.16663063879607,1.0 24.940964317230154,60.16887394708703,1.0 24.94560657539308,60.166700521644,1.0 2...
*/