Posted: Sun Jun 07, 2009 1:52 pm
Here we are, now it works fine, but there are some small points you should check before using this code...blueznl wrote:I'm very interested in this, keep the samples coming, I'm watching this space!
I've done this for a report and 3D tool for sport tracks, which has around 10.000 lines of code now (all in one single file

Global vars:
OptGoogleType = 0/1 for the selected map type
GoogleMapLoaded = 0/1 indicator, if the map has been loaded
LatA/LonA = world coordinates of the lower left corner of the map (double)
LatB/LonB = world coordinates of the upper right corner of the map (double)
Procedures:
GoogleMaps() will download the map to a (existing) directory called Maps
DoGoogleMaps() won't be needed but is the entry point in my program to do the whole thing in the background
Constants:
#GoogleMapsKey must contain your Key for Google Maps
#GoogleMapSprite and #GoogleMapBitmap any values
All calculations for finding the right position of the coordinates in a google map have been developed by me - hopefully all bugs have been eliminated :roll:
Michael
Code: Select all
Procedure.d GoogleMapsHeight(grad.d)
#Skalierung256Pixel=81.75513713869655
ProcedureReturn Log(Tan(#PI/4+Radiant(grad)/2))*#Skalierung256Pixel
EndProcedure
Procedure.d GoogleMapsWidth(grad.d)
ProcedureReturn 256*Radiant(grad)/#ZweiPi
EndProcedure
Procedure GoogleMaps(Dummy.l)
Protected OptMapsZoom=256; (minimale) Zielhöhe der Karte in Pixel (-> 512x512 Pixel)
Protected PixA.d,PixB.d; vertikale Pixelwerte gemäß Google-Projektion
Protected LonM.d,LatM.d,PixM.d; Punkte in der "Mitte" (M)
Protected BiggerFlag; Definition der größeren Kartenhälfte
Protected BiggerSize.d; Pixelhöhe der größeren Kartenhälfte
Protected OtherSize.d; Kartenbreite in Pixel
Protected MapX,MapY,MapZoom; Kartendimensionen
Protected MapName.s,Webpage.s; Dateiname der Karte (Cache) und Webstring
; Koordinaten ordnen
If LonB<LonA : Swap LonA,LonB : EndIf
If LatB<LatA : Swap LatA,LatB : EndIf
; Kartenmittelpunkt
LonM=(LonA+LonB)/2
LatM=(LatA+LatB)/2
; Verzerrung der Mercatorprojektion bezüglich Mittelpunkt prüfen...
If LatA<0
If LatB<0
BiggerFlag=1; untere Kartenhälfte (A-M) ist größer (A und B auf südlicher Hemisphäre)
ElseIf LatA>-LatB
BiggerFlag=0; obere Kartenhälfte (M-B) ist größer (Distanz A-Äquator kleiner als B-Äquator)
Else
BiggerFlag=1; untere Kartenhälfte (A-M) ist größer (Distanz A-Äquator größer als B-Äquator)
EndIf
Else
BiggerFlag=0; obere Kartenhälfte (M-B) ist größer (A und B auf nördlicher Hemisphäre)
EndIf
; Breitengrade in Pixel umrechnen...
PixA=GoogleMapsHeight(LatA)
PixM=GoogleMapsHeight(LatM)
PixB=GoogleMapsHeight(LatB)
; Größere Kartenhälfte bestimmen (Kartenverzerrung auf Nord-/Südhalbkugel)
If BiggerFlag=0
BiggerSize=PixB-PixM
Else
BiggerSize=PixM-PixA
EndIf
If BiggerSize<0
BiggerSize=-BiggerSize
EndIf
BiggerSize*2; Kartenhöhe = doppelte Höhe der größeren Kartenhälfte
OtherSize=(GoogleMapsWidth(LonB)-GoogleMapsWidth(LonA))*2; Kartenbreite
MapZoom=1
MapX=2
While (BiggerSize<OptMapsZoom) And (OtherSize<OptMapsZoom)
MapZoom+1
MapX*2
BiggerSize*2
OtherSize*2
PixA*2
PixM*2
PixB*2
Wend
; Kartendimensionen in Pixel
MapY=BiggerSize
MapX=(GoogleMapsWidth(LonB)-GoogleMapsWidth(LonA))*MapX
MapName="Maps"+Chr(OptGoogleType+'0')+RSet(Hex(LatA*5800),5,"0")+RSet(Hex(LonA*2900),5,"0")+RSet(Hex(LatB*5800),5,"0")+RSet(Hex(LonB*2900),5,"0")+".jpg"
; Informationen zur Google Maps Karte
; Debug "Google Maps: "+MapName
; Debug "Center: "+StrF(LonM,2)+"/"+StrF(LatM,2)
; Debug "Zoom: " +Str(MapZoom)
; Debug "Offset: " +Str(BiggerFlag)
; Debug ""
; Debug "Map Total Height: "+StrF(BiggerSize,1)
; Debug "Map Real Height: "+StrF(PixB-PixA,1)
; Debug "Map Total Width: "+StrF(MapX,1)
; Debug "Upper Half Height: "+StrF(PixM-PixA,1)
; Debug "Lower Half Height: "+StrF(PixB-PixM,1)
; Debug ""
If FileSize(MapName)<0
#GoogleMapsKey="ABC...XYZ"
Webpage="http://maps.google.com/staticmap?center="+StrD(LatM)+","+StrD(LonM)+"&zoom="+Str(MapZoom)+"&size=512x512&format=jpg&maptype="
If OptGoogleType
Webpage+"satellite"
Else
Webpage+"mobile"
EndIf
;Webpage+"&format=jpg"; gif, jpg, jpg-baseline, png8, png32
;Webpage+"&maptype=mobile"; roadmap, mobile, satellite, terrain, hybrid, mapmaker-roadmap, mapmaker-hybrid
;Webpage+"&markers="+StrD(LatA)+","+StrD(LonA)+",blue1|"+StrD(LatB)+","+StrD(LonB)+",green2|"
Webpage+"&key="+#GoogleMapsKey
; Debug "Webpage: "+Webpage
URLDownloadToFile_(0,Webpage,MapName,0,0); 0, wenn alles ok...
EndIf
If FileSize(MapName)>0
If LoadImage(#GoogleMapBitmap,MapName)
MapZoom=ImageHeight(#GoogleMapBitmap)-(PixB-PixA); Long-Variable ausborgen (>>1 funktioniert nicht bei Floats) und...
BiggerFlag+MapZoom>>1; ...oberen Kartenausschnitt korrigieren
MapZoom=(ImageWidth(#GoogleMapBitmap)-MapX)>>1; Linke Kante berechnen und in MapZoom speichern
; Debug "Map Corners: "+Str(MapZoom)+" - "+Str(BiggerFlag)+" - "+Str(MapX)+" - "+Str(PixB-PixA)
GrabImage(#GoogleMapBitmap,#GoogleMapBitmap,MapZoom,BiggerFlag,MapX,PixB-PixA)
;RotateMap(#GoogleMapBitmap)
CreateSprite(#GoogleMapSprite,MapX,MapY,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#GoogleMapSprite))
DrawImage(ImageID(#GoogleMapBitmap),0,0)
StopDrawing()
TransparentSpriteColor(#GoogleMapSprite,#TransparentColor)
CreateSprite3D(#GoogleMapSprite,#GoogleMapSprite)
GoogleMapLoaded=#True
SendMessage_(win,#WM_COMMAND,#MAP_UPDATE,0)
EndIf
EndIf
EndProcedure
Procedure DoGoogleMaps()
GoogleMapLoaded=#False
If OptGoogleMap
; provisorische Bodenplatte anzeigen bis eine "Google Maps" vorliegt...
CreateSprite(#GoogleMapSprite,64,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#GoogleMapSprite))
Box(0,0,256,256,PlotColor(OptPalette,#ColPlaneFill))
StopDrawing()
TransparentSpriteColor(#GoogleMapSprite,#TransparentColor)
CreateSprite3D(#GoogleMapSprite,#GoogleMapSprite)
CreateThread(@GoogleMaps(),0); Google-Maps holen...
EndIf
EndProcedure