GEO map 'library' - mdijkens - 09-12-2024
Since we are into globes/spheres and maps, I thought I'd post my 'library' that I use to show a map in my programs and being able to draw on it in Lat/Lon values. The hard work is in the conversion from lat/lon to x/y and vice versa.
Maybe someone can use it or parts of it.
Only the 5 GEO.* functions are needed, the rest is samplecode to use it.
Prereqs:
- Create your own API KEY at geoapify.com and enter in line 32
- have wget utility sourceforge.net on your system and optionally set path to wget in line 33
Code: (Select All)
samplecode: ' How to use
Screen _NewImage(_DesktopWidth, _DesktopHeight, 32): Do: _Delay .01: Loop Until _ScreenExists
_FullScreen _Stretch , _Smooth
mheight% = .9 * _Height: mwidth% = .85 * mheight%
xoffset% = (_Width - mwidth%) / 2: yoffset% = (_Height - mheight%) / 2
mlat0! = 50.6: mlon0! = 5
mlat1! = 53.8: mlon1! = 5.3
h& = GEO.Map(mlat0!, mlon0!, mlat1!, mlon1!, mwidth%, mheight%)
If h& <> 0 Then _PutImage (xoffset%, yoffset%), h&: _FreeImage h&
Do
_Limit 100
Do While _MouseInput
mlon! = GEO.x2lon(_MouseX - xoffset%, 0, mwidth% - 1, mlon0!, mlon1!)
mlat! = GEO.y2lat(_MouseY - yoffset%, 0, mheight% - 1, mlat0!, mlat1!)
mb% = _MouseButton(1)
Loop
If mb% Then
Circle (xoffset% + GEO.lon2x(mlon!, mlon0!, mlon1!, 0, mwidth% - 1), yoffset% + GEO.lat2y(mlat!, mlat0!, mlat1!, 0, mheight% - 1)), 5, &HFFFF0000
mb% = 0
End If
If mlat! >= mlat0! And mlat! <= mlat1! And mlon! >= mlon0 And mlon! <= mlon1! Then
Locate 1, 1, 0: Print Using "###.###### ###.######"; mlat!; mlon!;
End If
_Display
Loop Until InKey$ = Chr$(27)
System
Function GEO.Map& (mlat0!, mlon0!, mlat1!, mlon1!, mwidth%, mheight%)
Const APIKEY = "get yours at https://apidocs.geoapify.com/"
Const WGET = "wget" ' include path if needed
'https://apidocs.geoapify.com/playground/static-maps/
'https://apidocs.geoapify.com/docs/maps/static/#post-requests
'https://maps.geoapify.com/v1/staticmap?style=osm-bright&width=1920&height=1080&area=rect:5,52,5,53&apiKey=APIKEY
If mwidth% > 4096 Then mwidth% = 4096 Else If mwidth% < 100 Then mwidth% = 100
If mheight% > 4096 Then mheight% = 4096 Else If mheight% < 100 Then mheight% = 100
If mlat0! <= -90 Then mlat0! = -89.99999 Else If mlat0! >= 90 Then mlat0! = 90
If mlat1! <= -90 Then mlat1! = -89.99999 Else If mlat1! >= 90 Then mlat1! = 90
If mlat0! <> 0 And Abs(mlat0! < 1) Then lat0$ = Right$("-0", 2 - Sgn(Sgn(mlat0!) + 1)) + _Trim$(Str$(Abs(mlat0!))) Else lat0$ = _Trim$(Str$(mlat0!))
If mlon0! <> 0 And Abs(mlon0! < 1) Then lon0$ = Right$("-0", 2 - Sgn(Sgn(mlon0!) + 1)) + _Trim$(Str$(Abs(mlon0!))) Else lon0$ = _Trim$(Str$(mlon0!))
If mlat1! <> 0 And Abs(mlat1! < 1) Then lat1$ = Right$("-0", 2 - Sgn(Sgn(mlat1!) + 1)) + _Trim$(Str$(Abs(mlat1!))) Else lat1$ = _Trim$(Str$(mlat1!))
If mlon1! <> 0 And Abs(mlon1! < 1) Then lon1$ = Right$("-0", 2 - Sgn(Sgn(mlon1!) + 1)) + _Trim$(Str$(Abs(mlon1!))) Else lon1$ = _Trim$(Str$(mlon1!))
url$= "maps.geoapify.com/v1/staticmap?style=osm-bright&width=" + _Trim$(Str$(mwidth%)) + "&height=" + _Trim$(Str$(mheight%)) + _
"&area=rect:" + lon0$ + "," + lat0$ + "," + lon1$ + "," + lat1$ + "&apiKey=" + APIKEY
tfile$ = "~wget.jpg"
cmd$ = WGET + " -q --secure-protocol=TLSv1 --no-check-certificate --output-document=" + tfile$ + " " + Chr$(34) + url$ + Chr$(34)
Shell _Hide cmd$
gmap$ = _ReadFile$(tfile$)
Kill tfile$
If Len(gmap$) < 10000 Then GMap& = 0: Exit Function
lons! = mlon1! - mlon0!: lats! = mlat1! - mlat0!
midLat! = (mlat0! + mlat1!) / 2: cosLat! = Cos(midLat! * _Pi / 180)
cosLons! = (mwidth% / mheight%) * lats! / cosLat!
If cosLons! >= lons! Then
midLon! = (mlon0! + mlon1!) / 2: mlon0! = midLon! - cosLons! / 2: mlon1! = midLon! + cosLons! / 2
Else
cosLats! = (mheight% / mwidth%) * lons! * cosLat!
mlat0! = midLat! - cosLats! / 2: mlat1! = midLat! + cosLats! / 2
End If
GEO.Map = _LoadImage(gmap$, 32, "memory")
End Function
Function GEO.x2lon! (x!, x0!, x1!, mlon0!, mlon1!)
GEO.x2lon! = mlon0! + ((x! - x0!) / (x1! - x0!)) * (mlon1! - mlon0!)
End Function
Function GEO.y2lat! (y!, y0!, y1!, mlat0!, mlat1!)
Const PI2 = _Pi / 2, PI180 = -180 / _Pi, PI4 = _Pi / 4, PI360 = _Pi / 360
tlat0! = Log(Tan(PI4 + mlat0! * PI360)): tlat1! = Log(Tan(PI4 + mlat1! * PI360))
GEO.y2lat! = PI180 * (PI2 - 2 * Atn(Exp(tlat1! - ((y! - y0!) / (y1! - y0!)) * (tlat1! - tlat0!))))
End Function
Function GEO.lon2x! (lat!, mlat0!, mlat1!, y0!, y1!)
GEO.lon2x! = x0! + ((lat! - mlat0!) / (mlat1! - mlat0!)) * (y1! - y0!)
End Function
Function GEO.lat2y! (lat!, mlat0!, mlat1!, y0!, y1!)
Const PI4 = _Pi / 4, PI360 = _Pi / 360
tlat0! = Log(Tan(PI4 + mlat0! * PI360)): tlat1! = Log(Tan(PI4 + mlat1! * PI360))
GEO.lat2y! = y1! - ((Log(Tan(PI4 + lat! * PI360)) - tlat0!) / (tlat1! - tlat0!)) * (y1! - y0!)
End Function
|