Page 2 of 2

Posted: Sun Jun 07, 2009 1:52 pm
by Michael Vogel
blueznl wrote:I'm very interested in this, keep the samples coming, I'm watching this space!
Here we are, now it works fine, but there are some small points you should check before using this code...

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 :shock:). So there are some variables and constants you should modify for your needs:

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

Posted: Sun Jun 07, 2009 4:59 pm
by blueznl
Key?

Posted: Mon Jun 08, 2009 6:37 pm
by Michael Vogel
blueznl wrote:Key?
This one?

Posted: Mon Jun 08, 2009 7:22 pm
by blueznl
Ah, ok. Now I understand :-)

Posted: Tue Jun 09, 2009 11:33 am
by Michael Vogel
blueznl wrote:Ah, ok. Now I understand :-)
I should have added the link already in the previous posting :?

When you play around with the code, just tell me, if you like it (or find some issues :roll:)

The actual Forerunner program demonstrate the usage of google maps, but you have to do the following steps to see a result:
• store the forerunner program to a directory and create a subdirectory 'Maps'
• download an example file or use your own sport tracks
• start the forerunner
• press 'o' for options to select google maps and satellite view
• press 'h' to load the history file
• select the sport track and press 'enter'

Michael

Image

Posted: Mon Jun 15, 2009 10:38 am
by dige
ForeRunner.exe crashes while start fullscreen view.. there are no further informations...
Tried the provided Aschenbahn example..

Posted: Sat Jul 18, 2009 3:38 pm
by Michael Vogel
dige wrote:ForeRunner.exe crashes while start fullscreen view.. there are no further informations...
Tried the provided Aschenbahn example..
Thanks for this information, beside the Intel G965 chipset there seem to be another graphic card which crashes when DirectX7 3D graphic commands are used.

Maybe the actual version will work already, maybe you can check it once more. Otherwise, the DirectX9 version will work (hopefully :lol: )...

If not, I would ask you to tell me which graphic card you are using, I would add a filter that no 3D graphic is used with this card in the DirectX7 version.

Thanks,
Michael

PS there is one open issue, which could cause problems (but only if you use more tracks and change between them very fast)...

CreateSprite() seems to fail in around 1 of 500 calls :evil:

I know, there won't be a solution for that, but I want to warn others to be careful using it :roll:...

Code: Select all

LockMutex(ThreadMutex)
If CreateSprite(#GoogleMapBitmap,MapX,MapY,#PB_Sprite_Texture)

	StartDrawing(SpriteOutput(#GoogleMapBitmap))
	DrawImage(ImageID(#GoogleMapBitmap),0,0)
	StopDrawing()
	TransparentSpriteColor(#GoogleMapBitmap,#TransparentColor)
	CreateSprite3D(#GoogleMapSprite,#GoogleMapBitmap)

	GoogleMapLoaded=#True
	SendMessage_(win,#WM_COMMAND,#MAP_UPDATE,0)

Else
	Debug "CreateSprite() fehlgeschlagen..."
EndIf
UnlockMutex(ThreadMutex)

Re: Google Maps

Posted: Thu Feb 04, 2010 8:59 am
by Michael Vogel
Just two comments to my google maps projects:

• the Forerunner program (see above) is 99% complete - all sprite problems have been fixed, only the well-known DX9-Vista+ compatibility issues are left

• the Map Fixer creates custom maps for GPS devices -- is working already, but (hopefully) will get some enhancements in the future...

...one thing I want to implement is to open a window by PB which show google maps and allows to get the coordinates from a location into the running PB program. Has anyone has done something like this already?

Michael

Re: Google Maps

Posted: Fri Feb 05, 2010 9:26 am
by Michael Vogel
Maybe someone needs to get geo coordinates from an named address, here's the code to do so (the replacestring section should be optimized, anything else should work fine for everyone :wink:)...

Have fun,
Michael

Code: Select all

Procedure.s GetWebPage(URL.s)

	Global Proxy.s

	#GoogleMapsDataLength=256

	#INTERNET_FLAG_RELOAD=$80000000
	#INTERNET_OPTION_SECURITY_FLAGS=31
	#SECURITY_FLAG_IGNORE_UNKNOWN_CA=$100

	#INTERNET_OPEN_TYPE_PRECONFIG=0;										use registry configuration
	#INTERNET_OPEN_TYPE_DIRECT=1;											direct to net
	#INTERNET_OPEN_TYPE_PROXY=3;											via named proxy
	#INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY=4;	prevent using java/script/INS


	Protected HandleInet.l
	Protected HandleURL.l

	Protected Flags.l
	Protected FlagLen.l
	Protected Bytes.l=0

	Protected Html.s=Space(#GoogleMapsDataLength)

	If Len(Proxy)
		HandleInet=InternetOpen_("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)",#INTERNET_OPEN_TYPE_PRECONFIG,#Null,#Null,0)
	Else
		HandleInet=InternetOpen_("InetURL/1.0",#INTERNET_OPEN_TYPE_PROXY, Proxy,#Null,0)
	EndIf

	If HandleInet

		Flags=0
		FlagLen=SizeOf(Flags)

		InternetQueryOption_(HandleInet,#INTERNET_OPTION_SECURITY_FLAGS,@Flags,@FlagLen)
		Flags=Flags|#SECURITY_FLAG_IGNORE_UNKNOWN_CA
		InternetSetOption_(HandleInet,#INTERNET_OPTION_SECURITY_FLAGS,@Flags,SizeOf(Flags))

		HandleURL=InternetOpenUrl_(HandleInet,URL,#Null,0,#INTERNET_FLAG_RELOAD,0)

		If HandleURL
			If InternetReadFile_(HandleURL,@Html,Len(Html),@Bytes)
				InternetCloseHandle_(HandleURL)
				ProcedureReturn Trim(HTML)
			Else
				; ProcedureReturn "Failed InternetReadFile"
			EndIf
		Else
			InternetCloseHandle_(HandleInet)
			; ProcedureReturn "Failed InternetOpenUrl"
		EndIf
		InternetCloseHandle_(HandleInet)
	Else
		; ProcedureReturn "Failed InternetOpen"
	EndIf

	; ProcedureReturn "Failed Everything"
	ProcedureReturn ""

EndProcedure

Procedure.i GoogleMapsCheck(address.s)

	; THREAD;
	Protected Text.s
	Protected URL.s
	Protected Result.s

	Protected n.l
	Protected lat.d
	Protected lon.d

	Text=address

	URL=LCase(text)
	URL=ReplaceString(URL,"ä","ae")
	URL=ReplaceString(URL,"ö","oe")
	URL=ReplaceString(URL,"ü","ue")
	URL=ReplaceString(URL,"ß","ss")
	URL=ReplaceString(URL," ","%20")

	URL="http://maps.google.com/maps/geo?q="+URL+"&output=csv&key=<API_KEY>"

	Debug ""
	Debug URL
	Debug "---"
	Result=GetWebPage(URL)

	If Len(Result)=0
		Debug "Could not access Google Maps :-("
	Else
		n=Val(StringField(Result,1,","))
		If n=200
			n=Val(StringField(Result,2,","))
			lat=ValD(StringField(Result,3,","))
			lon=ValD(StringField(Result,4,","))

			Debug "Coordinates for '"+Text+"' received with "+StringField("low|moderate|good|high|excellent",n>>1+1,"|")+" accuracy  :-)"
			Debug lat
			Debug lon

		Else
			Debug "Could not find coordinates for '"+Text+"' :-("
		EndIf
	EndIf

EndProcedure

GoogleMapsCheck("Kärnterstraße 1,Vienna,Austria")
GoogleMapsCheck("Paris")
GoogleMapsCheck("Eiffeltower")
GoogleMapsCheck("Louvre")
GoogleMapsCheck("London")
GoogleMapsCheck("Tower Bridge"); oops
GoogleMapsCheck("Tower Bridge,London")