Purpose
Using the Google MAPS API to retrieve and process address data via asynchronous JavaScript calls

The Google Maps API is one of several web services that you can call via the JavaScript interface. However, as in this example, the results are often returned asynchronously (by a so-called callback function). Therefore, there is a special aspect to be considered when using automatic processing in an InputScript.

Hint: Many Google API services are still free, but now require a valid key. To do so, you need to register as a developer at Google and unlock the corresponding API.

Example: Define and check areas on a map

In this example we want to check if an address given by the user is within a certain area. This area, which could be a delivery area or area of responsibility, for example, is defined by a list of geocoordinates.

First step: Define areas

For example, you can easily draw polygons on the map with Google Earth and then export these areas. However, you will receive an XML file from which you have to extract the coordinates for the JavaScript array. In any case, the Google API needs a list of geocoordinates that encloses an area (polygon).

var areaCoords = 
[ new google.maps.LatLng(25.77014212500977, -80.19589526516582),
  new google.maps.LatLng(25.76086015600341, -80.19554919789735),
  new google.maps.LatLng(25.75979057914396, -80.1889029950932),
  new google.maps.LatLng(25.76438887383056, -80.18824982266264),
  new google.maps.LatLng(25.76915080643688, -80.18781360716652),
  new google.maps.LatLng(25.76963030449667, -80.1885820330303),
  new google.maps.LatLng(25.76999660752534, -80.19272885625307),
  new google.maps.LatLng(25.77014212500977, -80.19589526516582)
];

 

Second step: The GuiXT Scripts

WebView   (0,0)   (15,76) _

  "google_geometry.html"   _
  name="google_webview" -closeOnHide
InputField     (16,4) "Check Address"     (16,24) _
  size=40 name="google_address" default="Brickell Plaza, Miami, Florida, USA"
 
Pushbutton (16,65)  "GO" "?" process="check_google_address.txt"
  using AD = [google_address]
 
InputField (17,4) "Result" (17,24) size=40 name="google_contains_text" -readOnly
 
 
 
// InputScript: "check_google_address.txt":
 
Parameter AD 
 
clear V[google_completed]
clear V[google_contains]
 
CallJS codeAddress "&U[AD]"
 
Set V[count] 1 
 
label wait
Screen *
  
  if not V[google_completed]
    Enter "?" wait=1000
    statusmessage  addString="Google is working... (&V[count] Sec.)"
    
    set V[count] "&V[count]" + 1
    
    if V[count<30]
      goto wait
    endif   
    
    Message "E: Google failed" -statusline
  endif 
  
  statusmessage  -remove
  
  if V[google_contains=1]
    Set V[google_contains_text] "Address is within zone"
  endif
  
  if V[google_contains=-1]
    Set V[google_contains_text] "Address is NOT within zone"
  endif
  
  Enter "?"

The idea here is that the InputScript loops for a while so the Google API can execute the request, which is sometimes faster and sometimes slower, depending, for example, on the Internet connection, server load and so on.

In this case, however, the process is interrupted after 30 seconds at the latest.  

Third step: Extend the JavaScript library

In this case we do not want to embed an HTML page as a control, but execute all functions as pure JavaScript code. We insert the code into a file that is specified in the GuiXT profile and is loaded by the SAP GUI at startup.

Hint: You can cause a reload of the library without restarting the SAP GUI by calling a transaction in the new mode /O.

We extend the library with a general part that loads the Google Maps library on startup and a function that is called later by the user.

 

// load additional JavaScript framework
function loadJS(url) {

    var script = document.createElement(
        "script");
    script.type = "text/javascript";
    script.src = url;
    document.getElementsByTagName(
        "head")[0].appendChild(
        script);
};

// load google maps API
loadJS(
    "https://maps.googleapis.com/maps/api/js?KEY&libraries=geometry"
);

function codeAddress(address) {

    var geocoder;
    geocoder = new google.maps.Geocoder();

    var testCoords = [
        new google.maps.LatLng(
            25.77014212500977, -
            80.19589526516582),
        new google.maps.LatLng(
            25.76086015600341, -
            80.19554919789735),
        new google.maps.LatLng(
            25.75979057914396, -
            80.1889029950932),
        new google.maps.LatLng(
            25.76438887383056, -
            80.18824982266264),
        new google.maps.LatLng(
            25.76915080643688, -
            80.18781360716652),
        new google.maps.LatLng(
            25.76963030449667, -
            80.1885820330303),
        new google.maps.LatLng(
            25.76999660752534, -
            80.19272885625307),
        new google.maps.LatLng(
            25.77014212500977, -
            80.19589526516582)
    ];

    var testPolygon = new google.maps
        .Polygon({
            paths: testCoords
        });
    geocoder.geocode({
        'address': address
    }, function(results,
        status) {
        if (status == google
            .maps.GeocoderStatus
            .OK) {

            //alert(results[0].geometry.location);
            var contains =
                google.maps
                .geometry.poly
                .containsLocation(
                    results[0]
                    .geometry
                    .location,
                    testPolygon
                );
            if (contains) {
                guixt.set(
                    "google_contains",
                    1);
                guixt.set(
                    "google_completed",
                    1);
            } else {
                guixt.set(
                    "google_contains",
                    -1);
                guixt.set(
                    "google_completed",
                    1);
            }

        } else {

            // Error occured
            guixt.set(
                "google_completed",
                1);
            alert('Geocode was not successful: ' +
                status);

        }
    });
}

 

Conclusion

The use of external libraries and web services can enhance SAP screens with various functions. However, communication with the corresponding services is somewhat tricky due to the HTTP protocol and the often asynchronous processing.

It is recommended to test the functions in an HTML page first. In this case you can use the file google_geometry.html, for example, to visualize an area and test the Google API.

Download google_geometry.html

 

Components
InputAssistant + Controls