Embedding Google Maps in the IPFind.ahk GUI (AutoHotkey Web Trick)

Write a Local File to Load HTML iFrame Embedding Code into the ActiveX Control

May 26, 2021, Alert: Wow! That was fast! Google has already disabled this iFrame map embedding technique…at least for Google Maps. Oh, well, I’ve already reverted to using the original IPFindMap.ahk script using OpenStreetMap.org (“Use ActiveX Control to Embed World Maps in AutoHotkey GUI” May 10, 2021). The technique remains valid. I’ll offer another iFrame embedding application soon—this time probably with a weather forecast.

Last time “Embed Google Maps in an AutoHotkey GUI (No API Required!)” I discussed how you can bypass much of the clutter on Web pages by embedding the map, video, or image in an HTML iFrame read directly into the AutoHotkey ActiveX GUI control from a local file. Sites offering this service often supply HTML code generators for copying the appropriate link. Sometimes, as in the case of Google Maps, you will only find the legacy code by searching the Web. (Google wants you to signup for the API.)

I don’t know how long this Google Map feature will work, but for now, it provides a reasonable solution for AutoHotkey users wanting to embed a simple map into an application.

This time, I modified the IPFindMap.ahk script to write the HTML iFrame code to a separate .html file, then use that filename as the destination URL for the AutoHotkey ActiveX GUI control. This allows AutoHotkey to load an interactive Google map for each IP address found in the selected text.

I appreciate this solution because the embedded Google map looks cleaner than the previous OpenStreetMap.org map and displays the foreign map names in English.

Embedding Google Maps in the IPFindMap.ahk Script

While the original map script directly loaded a Web URL, this iFrame embedding technique requires a couple of extra steps to write and read the .html file:

  1. After parsing the target latitude and longitude (or city, state, and country) from the IP location site, write the HTML iFrame code to a local file.
  2. Use that new file as the URL target in the ActiveX control.

This requires a minimum number of changes to the IPFindMap.ahk script (discussed in the “Use ActiveX Control to Embed World Maps in AutoHotkey GUI” blog).

I modified the GetLocation(findip) function to return only two results: the IP location text (Location) and the latitude and longitude in Google Map format (Map):

Map := Map1 . "," . Map2

Return [Location,Map]

I removed the OpenStreetMap.org link-writing commands from the function since the script now saves a separate file using new HTML1 and HTML2 variables in the primary loop. I assigned the non-changing first and last portions of the iFrame embedding code to HTML1 and HTML2, respectively:

HTML1 := "<div style='width: 100%'><iframe width='100%' height='200' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='https://maps.google.com/maps?width=100%25&amp;height=200&amp;hl=en&amp;q="
HTML2 := "&amp;t=&amp;z=4&amp;ie=UTF8&amp;iwloc=B&amp;output=embed'></iframe></div>"

This allows AutoHotkey to piece together the HTML file contents by inserting the latitude and longitude (i.e. “lat,long”) between the two variables before writing the new file using the FileAppend command:

; For latitude, longitude map
MapEmbed := HTML1 . WhereIs[2] . HTML2

FileDelete, %A_ScriptDir%\GoogleMapEmbed.html
FileAppend , %MapEmbed%, %A_ScriptDir%\GoogleMapEmbed.html

Note: To prevent appending the new code to an old file, I use the FileDelete command to remove the existing file before issuing the FileAppend command.

Now, Navigate() to the file rather than directly to the URL:

Gui Add, ActiveX, ys x250 w200 h200 vWB%A_Index%, Shell.Explorer
FilePathName := A_ScriptDir . "\GoogleMapEmbed.html"
WB%A_Index%.Navigate(FilePathName)

Note: Constructing file path and name in the variable FilePathName simplifies reading the Navigate() function parameter and prevents errors from %var% macro substitution.

These changes to the IPFindMap.ahk script create the GUI displayed at the top of this blog.

CTRL+Scroll wheel out until the latitude (or city) appears (boxed in red) above the “View larger map” link. Then, scrolling in and out should response intuitively.

Embedded Google Maps Tip: The key combination CTRL+Scroll wheel zooms in and out while hovering the mouse cursor over the map. However, for the proper operation of the interactive map, first CTRL+Scrollwheel out (down) until the latitude label pops up in the “View larger map” area (as shown in the red box at right), then scroll in (up) again for map details. Otherwise, the scrolling does not operate properly. Also, after zooming out two clicks, hold down the left mouse button and drag to reposition the map—plus, the terrestrial view button will now appear on the map.

With a few more changes to the script, you can embed a Google map based upon city, state, and country rather than latitude and longitude. You may want this technique in those situations where you find the latitude and longitude unavailable.

Use City, State, and Country to Embed a Google Map

Modifying the embedded map in the IPFindGoogleMap.ahk script to city, state, and country required no changes to the GetLocation(findip) function. I used the RegExMatch() function to parse the city, state (region), and country from the IP location text returned by the function.

RegExMatch(WhereIs[1], "City(.*?)Region", City)
RegExMatch(WhereIs[1], "Region(.*?)\s\(", State)
RegExMatch(WhereIs[1], "Country(.*?)\s\(", Country)

MapEmbed := HTML1 . City1 . "," . State1 . "," Country1 . HTML2

The new value for MapEmbed uses the parsed location parameters to form the proper format for the Google Map query. Everything else remains the same. Rather than inserting latitude and longitude between HTML1 and HTML2, we add the city, state, and country.

The resulting image looks identical to the latitude/longitude map except the two-click zoom out (CTRL+Scroll wheel down) now pops up the city name above the “View larger map” link.

Why the IPFindGoogleMap.ahk Script?

I wrote the IPFind.ahk script out of curiosity. People worldwide buy my books, but most of them use a PayPal account when making a purchase. PayPal does not provide me with an address. I can only guess at their country of origin based upon a name or e-mail address. In most cases, that data does not help determine probable nationality.

I do get an IP address for each sale which at a minimum can help me find the location of the buyer’s ISP. The IPFind.ahk script affords me the geographic location of that provider. The clean, embedded Google map gives me a quick look at where in the world they live. I only use the script occasionally to satisfy my inquisitiveness, but when I do, it saves me the tedious work of looking up each IP address individually.

The IPFindGoogleMap.ahk Script

Note: I’ve include the Windows Registry setting code appearing in the first lines of the script below as a convenience (see the previous blog). It only needs to run once to set up your Windows computer for all future uses of the ActiveX control. If you like, after setting the new value, you can remove or comment-out those lines of code.

I call the following script IPFindGoogleMap.ahk:

; Windows Registry change for IE compatibility with AutoHotkey
; Discussed in https://jacks-autohotkey-blog.com/2021/05/17/embed-google-maps-in-an-autohotkey-gui-no-api-required/ 
RegRead,KeyValue,HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION,AutoHotkey.exe
If ErrorLevel
    RegWrite, REG_DWORD,HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION,AutoHotkey.exe,11001


; Code needed to write the c:\AutoHotkey\GoogleMapEmbed.html file
HTML1 := "<div style='width: 100%'><iframe width='100%' height='200' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='https://maps.google.com/maps?width=100%25&amp;height=200&amp;hl=en&amp;q="
HTML2 := "&amp;t=&amp;z=4&amp;ie=UTF8&amp;iwloc=B&amp;output=embed'></iframe></div>"

Return

^!i::
  OldClipboard:= ClipboardAll
  Clipboard:= ""
  Send, ^c ;copies selected text
  ClipWait 0
  If ErrorLevel
    {
      MsgBox, No Text Selected!
      Return
    }
CountIP := 1
Next := 1
Loop
{
  FoundPos := RegExMatch(Clipboard, "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b" , ipaddress%CountIP%, Next)
  Next := FoundPos + StrLen(ipaddress%CountIP%)
  If FoundPos = 0
    Break
  CountIP++
}
Gui, +AlwaysOnTop
If IPAddress1
  {
    CountIP--
    Loop, %CountIP%
    {
       	CheckIP := ipaddress%A_Index%
       	WhereIs := GetLocation(CheckIP)

; For city, state, country map
		RegExMatch(WhereIs[1], "City(.*?)Region", City)
		RegExMatch(WhereIs[1], "Region(.*?)\s\(", State)
		RegExMatch(WhereIs[1], "Country(.*?)\s\(", Country)

		MapEmbed := HTML1 . City1 . "," . State1 . "," Country1 . HTML2

; For latitude, longitude map
;		MapEmbed := HTML1 . WhereIs[2] . HTML2

		FileDelete, %A_ScriptDir%\GoogleMapEmbed.html
		FileAppend , %MapEmbed%, %A_ScriptDir%\GoogleMapEmbed.html

		WhereIs[1] := StrReplace(WhereIs[1],"Postal code","`rPostal code:`t")
		WhereIs[1] := StrReplace(WhereIs[1],"Region","`rRegion/State:")
		WhereIs[1] := StrReplace(WhereIs[1],"Country","`rCountry:`t`t")
		WhereIs[1] := StrReplace(WhereIs[1],"State:","State:`t")
		WhereIs[1] := StrReplace(WhereIs[1],"Continent","`rContinent:`t")
		WhereIs[1] := StrReplace(WhereIs[1],"Metro code","`rMetro code:`t")
		WhereIs[1] := StrReplace(WhereIs[1],"City","`rCity:`t`t")
		WhereIs[1] := StrReplace(WhereIs[1],"Coordinates","`rCordinates:`t")

		
		Gui, Add , Text, xm section, % CheckIP . WhereIs[1] 
		Gui Add, ActiveX, ys x250 w200 h200 vWB%A_Index%, Shell.Explorer
		FilePathName := A_ScriptDir . "\GoogleMapEmbed.html"
		WB%A_Index%.Navigate(FilePathName)

		Gui, Add , Link, xs yp+120, % "<a href=""https://tools.keycdn.com/geo?host=" . CheckIp . """>IP Data" . "</a>" 
; For latitude, longitude map
;		Gui, Add , Link, yp+15, % WhereIs[2] 
    }
}
Else
  WhereIs := "No IPs Found!"

Clipboard := OldClipboard

Gui, Add, Button,xm section, Close
Gui, Show,,IP Locations Google Maps (CTRL+Scroll to zoom)

Return

GetLocation(findip)
{
UrlDownloadToFile, % "https://tools.keycdn.com/geo?host=" . findip, iplocate
	IPsearch := "https://tools.keycdn.com/geo?host=" . findip
	whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	whr.Open("GET", IPsearch)
	whr.Send()
	  sleep 100
	version := whr.ResponseText
	RegExMatch(version, "s)Location</p>(.*?)Time</dt>", Location)
    FileRead, version2, iplocate
	RegExMatch(version, "Coordinates</dt><dd class=""col-8 text-monospace"">(.*?) \(lat\) / (.*?)\(long\)", Map)
	Map := Map1 . "," . Map2
; Strip out HTML tags
	Location := RegExReplace(Location1,"<.+?>")
; For Google Map 
	Return [Location,Map]

}

ButtonClose:
	WinClose
Return

GuiClose:
	Gui, Destroy
Return

Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)

jack

This post was proofread by Grammarly
(Any other mistakes are all mine.)

(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)

Find my AutoHotkey books at ComputorEdge E-Books!

Find quick-start AutoHotkey classes at “Robotic Desktop Automation with AutoHotkey“!

One thought on “Embedding Google Maps in the IPFind.ahk GUI (AutoHotkey Web Trick)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s