Today I wrote a VB.Net function for decoding an OSM shortlink, based on the Ruby example.
This is now part of my map viewer application:
http://code.google.com/p/vataviamap/
The source file containing this function is available at:
http://code.google.com/p/vataviamap/source/browse/trunk/VataviaMap/Shared/clsServer.vb
Private Const OSMshortlinkEncoding As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_~"
''' <summary>
''' Parse an OpenStreetMap shortlink code into Latitude, Longitude and Zoom
''' </summary>
''' <param name="aCode">OpenStreetMap shortlink code</param>
''' <param name="aCenterLatitude">returns latitude at center of area</param>
''' <param name="aCenterLongitude">returns longitude at center of area</param>
''' <param name="aZoom">returns zoom level</param>
''' <returns>True if link was parsed and reasonable values for the ByRef arguments were found</returns>
''' <remarks>https://help.openstreetmap.org/questions/9566/shortlink-class-in-c</remarks>
Private Function ParseOSMshortlink(ByVal aCode As String, _
ByRef aCenterLatitude As Double, _
ByRef aCenterLongitude As Double, _
ByRef aZoom As Integer) As Boolean
'http://osm.org/go/0MbEUuTq = http://www.openstreetmap.org/?lat=52.50547&lon=13.36932&zoom=16
Dim x As Long = 0
Dim y As Long = 0
Dim z As Long = 0
Dim z_offset As Long = 0
Try
' replace @ in old shortlinks with ~
aCode = aCode.Replace("@", "~")
For Each ch As Char In aCode.ToCharArray
Dim t As Integer = OSMshortlinkEncoding.IndexOf(ch)
If t < 0 Then
z_offset -= 1
Else
For index As Integer = 1 To 3
x <<= 1
If t And 32 Then x += 1
t <<= 1
y <<= 1
If t And 32 Then y += 1
t <<= 1
Next
z += 3
End If
Next
' pack the coordinates out to their original 32 bits.
x <<= (32 - z)
y <<= (32 - z)
' project the parameters back to their coordinate ranges.
aCenterLongitude = (x * 360.0 / 2 ^ 32) - 180.0
aCenterLatitude = (y * 180.0 / 2 ^ 32) - 90.0
aZoom = z - 8 - (z_offset Mod 3)
Return aCenterLatitude > -90 AndAlso aCenterLatitude < 90 AndAlso _
aCenterLongitude >= -180 AndAlso aCenterLongitude <= 180
Catch
Return False
End Try
End Function
answered
19 Nov '12, 21:42
Mark Gray
16●1
accept rate:
0%
I do not want to sound unfriendly here, but looking at the code it seems quite easy. I wonder if someone who is not able to rewrite it within half an hour can use the result...