Live Google maps in SAS -- multiple markers

25

➤ 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 post, Spice up SAS output with live Google maps, I discussed the idea of delivering live Google map through SAS output and demonstrated the feasibility of doing so in SAS Information Delivery portal. Similarly, it can be done for any SAS HTML output.  You would just need to replace file _webout for SAS portal with any file reference pointing to an HTML file.

Handpicked Related Content: The power of SAS-generated InfoWindows in Google maps

Since the first post was well received by the SAS community and generated numerous questions, I have decided to expand on it and show some additional functionality that can be incorporated into SAS output in regards to the Google maps.

In this post, I will demonstrate how to use SAS to generate Google map with multiple points (or markers, using Google terminology) and incorporate it into SAS HTML output.

Using SAS data sets as input 

In the first post I used SAS macro variables to pass the data into SAS-generated Javascript that embeds Google map into SAS output. It was adequate for proving the concept; however, here I will use SAS dataset as a natural source of the data.

Let’s assume that we have the following data table with three observations, each corresponding to a single point on the Google map:

Figure 1. SAS data set with variables for three location markers.
Figure 1. SAS data set with variables for three location markers.
Figure 2. Information displayed with each marker.
Figure 2. Information displayed with each marker.

Although for showing three points on map as markers, we only need the latitude and longitude (lat and lng variables in our table), the remaining variables will be used to display an information window when user clicks on a marker, as shown in Figure 2:

Writing the code 

Displaying multiple live Google map markers in your SAS output can be accomplished in six fairly easy steps.  You can view and download the full sample SAS code.  Here are explanations and clarifications for each section in this example:

1. Specify the HTML output file location.  Use the FILENAME statement to assign a fileref to the physical location of the HTML file you are going to generate.

2. Prepare the data. To make this example more self-contained, I generate the SAS table in Figure 1 within the code itself.  In reality, you would prepare your data table by pulling or combining data from a database or other data storage.

3. Determine the map center. For a single marker implementation, a trivial solution would be to assign map center to the same location as the marker.  When there are multiple markers, some map center considerations have to be made. In the latter case, you would want Google map center to be somewhere between the multiple markers. A geometrical way of handling this problem is to let the midpoint of the latitude and longitude range determine the center coordinates. Here is the formula to calculate the center coordinates:

C(lat, lng) = {min(lat) + [max(lat)-min(lat)]/2, min(lng) + [max(lng)-min(lng)]/2}

In this implementation, I chose a less geometrical, but a simpler and viable approach using averages and used the MEANS procedure in the sample code to implement it:
C(lat, lng) = ( avg(lat),  avg(lng) )

4. Initialize the map. This code portion uses a DATA _NULL_ step to generate a non-repeatable section of the code, and it mostly coincides with the code from a previous post with an exception.  In this example, I use the map center coordinate variables that were calculated in the previous step instead of macro variables. To simplify, I also use a constant zoom level (zoom: 12) to control the Google map scale. Obviously, if needed, you can determine the scale dynamically based on your data.

5. Add multiple markers. This portion of the code also uses a DATA _NULL_ step, but here the DATA step loops through the source data as many times as there are observations in the source data, thus generating as many markers. Here are other notes about this section:

  • To append to the output HTML files, I use the mod option:
    file fout mod;
  • I use inline styling to modify the default width of the Google map information window. Similarly, you may apply other CSS styles here or in an external CSS using class= or id= selectors.
    'var info' i "= '" '<div style="' 'width:150px;"><b>' oname "</b><br>" addr1 "<br>" addr2 "<br>Phone: " phone "</div>" "';" 
  • I use the following statement to generate the Javascript variable suffix corresponding to each observation in the source SAS data set:
     i = strip(_n_);

6. Wrap up the HTML file. Again, I use a single-iteration DATA _NULL_ step to wrap up the Javascript and HTML. The bottom portion of the code contains information about the styling of the final embedded Google map:

data _null_;
  file fout mod;
  put
  '}'
  'google.maps.event.addDomListener(window, "load", initialize);' /
  '</script>' /
  '</head><body>' /
  '<h3>Sample of Google map in SAS output with multiple points/markers</h3>' /
  '<div id="map-canvas" style="width:550px; height:350px; border: 2px solid #3872ac;"></div>' /
  '</body></html>'
  ;
run;

Using the final map

Running the above code sample produces the gmapoutput_mm.html file which, when opened in a web browser, produces the following Google map containing all three points of interest represented by markers shown in Figure 3.

Figure 3. Final Google map showing  three location markers and an information block generated by data in a SAS data set.
Figure 3. Final Google map showing three location markers and an information window.

Click for an interactive version of the map.

This map is interactive: you can move it around, zoom in and zoom out, and you can click on markers to display detail information about that location in a popped information window.

The code that produced this map is completely data-driven in the sense that all the information comes from a data table. I'm hoping that, by now, you can see how relatively easy it is to incorporate Google maps into SAS-generated output and that you will start using this technique for your benefit.

Handpicked Related Content: The power of SAS-generated InfoWindows in Google maps

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 >>>

25 Comments

  1. Michael Cuenco on

    Hi Leonid,

    In your step 5. Add Multiple Markers, can you label the marker with a letter and color the marker where the letter and the color are read from the data source?

    Thanks,
    Michael Cuenco

    • Leonid Batkhan

      Hi Michael,
      I am not aware of the feasibility to place "text" on the markers. However, you can create a set of different markers with different letters and different colors, and then you can have your data drive the logic of which image to display for a particular marker. You can find an example of this implementation in my blog post SAS to the rescue: claiming your location on Google map...
      Please let me know if this answers your question.
      Best regards,
      Leonid

  2. SANDESH REGMI on

    Hi Leonid,
    I tried to implement your code and generate the map with location but failed to show the location. When I run the html file I can just see the map but not the location. Any thoughts?

    • Leonid Batkhan

      Sandesh,
      That is because in your generated code you are referencing custom marker images, but you do not supply those images. You should either have those image files in the specified location, or use default markers.

  3. Pingback: Circling Google maps with SAS - SAS Users

  4. Christopher Gerdvil on

    Thank you for this code and the idea. I dabbled a bit with it and made a pretty useful tool (IMO). The tool is not a production tool, just a concept of what's possible with SAS code and Platform Scheduler. This is what it does, I use SAS code to find customers that meet a certain criteria, I group them by a common attribute (node), then plot the attribute on the map using a red circle with an "X". Another map shows the customers by their lat\long coordinates.
    Now all I need to do is link the 2 maps. I want to be able to click on the red x (which shows how many customers met that criteria on that node) and have the customer detail map open up zoomed in to show the customers off of the clicked node.
    Again, thank you for the code and the idea!

  5. Pingback: The power of SAS-generated InfoWindows in Google maps - SAS Users

  6. Pingback: Drawing overlays on SAS-generated Google maps - SAS Users

  7. One more thing. I have been using the andriod app, Latitude & Longitude on my Samsung Galaxy Note 3 and can get up to 7 digits after the decimal point and an accuracy of about 11m. Is that what people use to get the lat/long values or is there a better way to do this?

  8. Leonid, great and useful stuff! I was curious if the infowindow could be set up to display an image?

    For example, lets say I have sites of office locations and when I click on the icon instead of showing text only, can I display the office manager?

    Another example is on a much smaller scale but same principle. Our home owners association has 220 homes and 8 members of the board. It would be nice to display the location of the board members along with their picture and some info about them such as name, title, address, email address and phone number.

    I have looked at how this can be done and hoped to translate it into SAS code but could not find anything after a fairly extensive amount of time. Any chance you could create an example similar to this? I think it would make for a great SAS / google maps blog post...

    • Leonid Batkhan
      Leonid Batkhan on

      Tom, thank you for your feedback and questions.
      The short answer is yes, info window can display text and images. In fact, in info window you can use any HTML syntax. For displaying an image, you would need to construct your var info as in the following example:

      var info = '<div><img src="image1.jpg"><b>Organization A</b><br>111 Rockville Pike, Suite 1000,<br>Rockville, MD 20850<br> Phone: (301) 838-7030</div>';

      Those image file names can be part of your source data.

      I will try to compile a more comprehensive code example and present it in one of my future posts.

      • I love the program but i like to use image names. but script is for one record.

        var info = 'Organization A111 Rockville Pike, Suite 1000,Rockville, MD 20850 Phone: (301) 838-7030';
        I have in my source dataset the link to the image.

        Do you have maybe the javascript for var info included the image
        'var info' i "= '" '' oname "" addr1 "" addr2 "Phone: " phone "" "';" /

        • Leonid Batkhan
          Leonid Batkhan on

          Hans, if you want to use custom markers, you need to add icon option to the marker definition, e.g.
          'var marker' i '= new google.maps.Marker({' /
          'position: point' i ',' /
          'map: map,' /
          'icon: ' brand ',' /
          'title: "Click here for details"' /
          '});' /
          where variable brand holds URLs to your marker images. Does this work for you?

  9. This is very helpful. I especially like the flexibility of the data preparation step. Thanks for expanding your original post.

    I've just started working with Javascript so maybe you can answer a question. Is there a way to turn all of the information windows on and off with a single click?

    • Leonid Batkhan
      Leonid Batkhan on

      Thank you for your comment!

      Yes, you can turn on all the information windows with one click, but I would not recommend doing that as the information windows may overlap thus cluttering the view.

      • With dozens of markers in my application that I want to compare at the same time, it's a necessary trade-off. Can you point me to where I can find the code to do this?

        • Leonid Batkhan
          Leonid Batkhan on

          Gary, you can look up more information on Google map information windows here: https://developers.google.com/maps/documentation/javascript/infowindows. However, here is an excerpt from that link:

          Best practices: For the best user experience, only one info window should be open on the map at any one time. Multiple info windows make the map appear cluttered. If you only need one info window at a time, you can create just one InfoWindow object and open it at different locations or markers upon map events, such as user clicks. If you do need more than one info window, you can display multiple InfoWindow objects at the same time.

          I believe that in your situation with "dozens of markers", if you open all information windows at once, they will overlap so you won't be able to read all of them.

          An alternative solution may be to display information on multiple locations in a single information window that is opened by clicking on either location.

Leave A Reply

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

Back to Top