The power of SAS-generated InfoWindows in Google maps

9

➤ DISCLOSURE!

In June 2018 Google introduced changes to the way it handles its Maps platform. They now require API key in order to embed a map, plus Google Maps "projects" must now be associated with a billing account. Unless these new Google rules are met, Google maps described in the blog post will display with "For development purposes only" watermark but still retain its functionality.

Google Maps with SASIn my prior posts on displaying Google maps in SAS, I used Google map InfoWindows to display text information when user clicks on a marker or area of the map.  Thanks to reader Tom Bellmer’s questions, today I am going to explore some additional possibilities that the Google map InfoWindow can provide.

According to the Google Maps documentation, the content of the Info Window may contain a string of text, a snippet of HTML, or a DOM element. Let’s use that “snippet of HTML” creatively.

I am going to expand the earlier example, Live Google maps in SAS -- multiple markers by enhancing the InfoWindow so that, in addition to text, it includes hyperlinks, images and even embedded YouTube video. There are just two differences of this code from the prior implementations of the Google map with markers and info windows. These differences are: 1) the data preparation step shown below and 2) the line of the code that defines the contents of the InfoWindow. This example also uses a simpler method for handling quotes.

Adding new variables to the source data

To make our example data-driven, we add the following data columns to the source data: manager name, e-mail, website url, manager picture, youtube id. To make our SAS code self-contained, we will create our source data within the code itself:

/* data preparation */
data organizations;
  length
    oname $15
    addr1 $20
    addr2 $20
    phone $15
    lat 8
    lng 8
    pname $15
    email $12
    web $10
    pic $10
    utub $13
    ;
  input
    oname $ 1-14 addr1 $ 16-35 addr2 $ 37-55 phone $ 57-70 lat 72-80 lng 82-91
    pname $ 93-107 email $ 109-120 web $ 122-128 pic $ 130-137 utub $ 139-149;
  datalines;
SAS Institute  111 Rockville Pike   Rockville, MD 20850 (301) ###-5555 39.086137 -77.149283 Robert Anderson ra@org_A.com sas.com img1.jpg yIuGPcYNGO4
Organization B 14200 Shady Grove Rd Rockville, MD 20850 (301) ###-3333 39.092048 -77.207544 Kerri Evers     ke@org_B.com sas.com img2.jpg ODq6V69IX2Y
Organization C 14501 Avery Rd       Rockville, MD 20853 (301) ###-8888 39.093247 -77.122915 Medea Colchis   ps@org_C.com sas.com img3.jpg K5qTKCzI2Ek
;
run;

Note: while geographical locations in this example are real (they have to be real in order to show up on a Google map), some names as well as the contact information are fictitious. The YouTube videos from SAS are real!

Download the full sample SAS code here.

Defining the contents of the InfoWindow

In the prior implementation, the line of the code starting with 'var info' that defines the contents of the InfoWindow was quite simple:

'var info' i "= '" '<div style="' 'width:150px;"><b>' oname "</b><br>" addr1 "<br>" addr2 "<br>Phone: " phone "</div>" "';" /

For today’s purposes, this line naturally becomes somewhat more intense. In this code snippet, there are HTML tags with inline styles defining the layout and appearance of information in the InfoWindow and variable values that are fed from the source SAS data set. For the YouTube video, I use <iframe> tag, which allows embedding any external web contents.
  'var info' i '=''<div style="width:470px;height:300px;"><div style="float:left;margin-top:5px;margin-right:5px;"><b>'
    oname '</b><br>' addr1 '<br>' addr2 '<br> Phone: ' phone '<br><a href="http://www.' web +(-1) '" target="_blank">Website</a><br>Manager: '
    pname '<br><img src="images/' pic +(-1) '" style="margin:3px;"><br><a href="mailto:' email +(-1) '">E-mail</a></div>'
    '<div style="float:right;margin-top:40px"><iframe width="295" height="227" src="//www.youtube.com/embed/'
    utub +(-1) '" frameborder="0" allowfullscreen></iframe> </div> </div>'';' /

Simpler method for handling quotes

Please note, that in the prior code I used both, single and double quotes to secure proper quotation. However, in the new code, I relied on a simpler approach - dual single quotes when the first single quote serves as a masking or escape character for the second single quote.

In other words, within a SAS character expression, dual single quotation mark resolves to a single quotation mark being a part of the character value and not a closing quotation mark. The same is true for dual double quotation marks (see Using Quotation Marks with Character Constants in the documentation.)

Although in many cases this might be superfluous, I use the +(-1) pointer control expression to secure clean (without an extra space) double quotation mark closure. This technique becomes essential when you construct Javascript variable property references using dot notation.

Implementation

In this code, the assumption was made that if the location of the output HTML file is the c:\\ folder (as shown in the code), then the images are stored in c:\\images folder. For the Youtube videos to be functional within the InfoWindows, the output HTML files have to be viewed on the web server, not on your local computer.

Running the above code sample produces the gmapoutput_iw.html file, which, when opened in a web browser, produces a Google map containing markers as shown in the image below.

In this example, not only is this Google map interactive (you can move it around, zoom in, zoom out, change view between Street View, Satellite View and Terrain View), you can also click on markers to display detail information about that location in a popped information window. The content of InfoWindows itself is interactive too.  You can click on a hyperlink to go to a website, or click on an e-mail link to send an e-mail, or watch a YouTube video and interact with it (view and listen, pause, play, adjust volume, fast forward and backward; you can double-click on it to view in a full screen mode.)

Click on the Google maps image to see an interactive version.  Alternatively, you can click here for an interactive version of the map.

Screenshot of a SAS-generated interactive Google map with image, hyperlinks and Youtube video displayed in Info Window

Enhanced InfoWindows can be used not just in conjunction with Google map markers, they can also be used in a similar manner with Google map overlays shown in my prior post Drawing overlays on SAS-generated Google maps.

I hope this post gives you more “food for thought” on possible Google map visualizations in your SAS applications. Please, continue sending your feedback, ideas and questions by commenting on this post.

Share

About Author

Leonid Batkhan

Leonid Batkhan is a long-time SAS consultant and blogger. Currently, he is a Lead Applications Developer at F.N.B. Corporation. He holds a Ph.D. in Computer Science and Automatic Control Systems and has been a SAS user for more than 25 years. From 1995 to 2021 he worked as a Data Management and Business Intelligence consultant at SAS Institute. During his career, Leonid has successfully implemented dozens of SAS applications and projects in various industries. All posts by Leonid Batkhan >>>

9 Comments

  1. Pingback: Integrating SAS reports with Google maps: two-pane solution - SAS Users

  2. Leonid,
    This is just another way to show SAS capability to do something new.
    Also I’d like to add the scale bar on Mile at the bottom of map you created here. It will help me to estimate the distance between two locations without typing their address on Google map. Do you have any idea on how to accomplish it?
    Thank you.

    Ethan.

    • Ethan, Google API allows to add the scale bar by adding the following property to the mapOptions list - scaleControl: true. However, Google Map API initializes this scale control in kilometers (km) by default. You can change your scale to miles (mi) by clicking on the scale control. Each click will toggle between km and mi. However, it appears there is no clear-cut programmatic method to set mile as initial unit for the scale control. I wish Google develops some unit scaleControl property to allow initializing the scale control unit as miles.

  3. Leonid

    Just to let you know, on my Win 7 box, I was not able to write to the root directory. I assume that it is the permissions that I have set up.

    Also, the output file was generated but the map did not display.

    I'm running 9.3 TS 1M1

    By the way, the system will not allow the Check to Confirm box to be left unchecked.

    Nat Wooding

    • Leonid Batkhan

      Nat, you can create your output file in any directory, not just in C:\ root. In order to do that, just modify the filename statement.
      As for the map not displayed, please try the following statement at the beginning of your code: options lrecl=max;
      Also note that your code must be placed on a web server in order to get the full functionality, such as YouTube video.
      "Check to Confirm" is working exactly as intended: you have to check it.

      • Hi Leonid,
        I used your code to create a JOBS in SAS Viya. The result showed up in _webout but the map didn't display even after I added the options lrect=max;
        Any idea how to fix it?
        Tran

        • Leonid Batkhan

          Hi Tran,
          Without seeing your code and the result, it's hard for me to say what's going on. You could post the question with these details to SAS Support Communities and see if an expert can help. Or work with SAS Technical Support.

          Also, keep in mind that in June 2018 Google introduced changes to the way it handles its Maps platform. They now require API key in order to embed a map, plus Google Maps “projects” must now be associated with a billing account...

  4. Leonid, thanks for putting this outstanding blog post together. this is extremely informative as I learn from examples. Using SAS to create google maps and control the content displayed is a very powerful combination. I was getting a lot of ideas of how this might be used and it is now all coming together thanks to you! Great stuff!

Leave A Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to Top