SAP surprises us every day. Even after working for more than a decade, a new project or client will have some requirements which are unique and you need out of the box thinking and solution. The below post is a similar requirement where a client wanted to know the Geo Coordinates of any given place. He thought Google Map is free and readily available, so why not use it in SAP with ease.
Check below, if the user enters any address, he should get the latitude and longitude of that place.
Isn’t it a cool requirement?
How can we achieve this?
Simple, connect to Google Map Service (read API), scan through its content string and find your data. It needs some reading through the string, but this is really effective and easy solution.
Check this steps (detailed code is available at the end of the article below)
Concatenate your input address with the Google Maps API web address to get the client data.
Request the data. Check your cases (lower/upper) of the methods (they might be case sensitive).
Send the request.
Receive the response from Google API.
Now, you have the string content. Just look through the string at the right place and get the latitude/longitude information.
<location> </location> are the opening and closing tag. We need to find the latitudes and longitudes in between these two tags.
Similarly <lat> </lat> and <lng> </lng> are the opening and closing tags for Latitude and Longitude respectively.
This is one example of the content file received from Google API. Looking at the data, it is very clear, where we can find the coordinates.
Also, he would show, how to open the two addresses in Google Map and show the distance in the browser. Please stay tuned.
And our code not only works for India address, it works for any address in the world. Let’s check an address in USA.
You can validate the coordinates in Google Map manually.
Here is the code snippet used for this post.
*-----------------------------------------------------------------------
* Author : For www.sapspot.com
* Title : Get Latitude and Longitude of a place from Google API
*-----------------------------------------------------------------------
* Change History :
* Author DATE REQUEST# DESCRIPTION
*--------------- ---------- ----------- -------------------------------
* SAPSPOT 05/22/2016 Intial Development
*-----------------------------------------------------------------------
REPORT zsapspot_google_api NO STANDARD PAGE HEADING
LINE-COUNT 132.
*&---------------------------------------------------------------------*
*& TYPE-POOLS
*&---------------------------------------------------------------------*
TYPE-POOLS: truxs, slis.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
PARAMETERS : p_add_f TYPE c LENGTH 50.
*&---------------------------------------------------------------------*
*& Types and Data
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_dest,
place_f TYPE c LENGTH 50,
lat_f TYPE c LENGTH 20,
lng_f TYPE c LENGTH 20,
END OF ty_dest.
DATA: gt_dest TYPE STANDARD TABLE OF ty_dest.
*&---------------------------------------------------------------------*
*& Start of Selection
*&---------------------------------------------------------------------*
START-OF-SELECTION .
* Get longitude and latitude
PERFORM get_long_lat.
*&---------------------------------------------------------------------*
*& End of Selection
*&---------------------------------------------------------------------*
END-OF-SELECTION .
* Show Latitute and Longitude
PERFORM display_lat_longitude.
*&---------------------------------------------------------------------*
*& Sub Routines
*&---------------------------------------------------------------------*
FORM get_long_lat .
DATA:
lv_http_client TYPE REF TO if_http_client,
lv_content TYPE string.
* Creation of new IF_HTTP_Client object
PERFORM create_http_client CHANGING lv_http_client.
* Request and Get
PERFORM http_client_request_get_method USING lv_http_client.
* Send the request
PERFORM http_client_send USING lv_http_client.
* Retrieve the result
PERFORM http_client_receive USING lv_http_client CHANGING lv_content.
* Get the actual coordinate using the content string
PERFORM get_coordinates USING lv_content.
ENDFORM. " get_long_lat
*&---------------------------------------------------------------------*
*& Form CREATE_HTTP_CLIENT
*&---------------------------------------------------------------------*
* Create HTTP Client
*----------------------------------------------------------------------*
FORM create_http_client CHANGING p_http_client TYPE REF TO if_http_client.
DATA: lv_http_url TYPE string.
* Prepare the url of the address
CONCATENATE
'http://maps.google.com/maps/api/geocode/xml?address='
p_add_f
INTO lv_http_url .
* Get client from url
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = lv_http_url
IMPORTING
client = p_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form HTTP_CLIENT_REQUEST_GET_METHOD
*&---------------------------------------------------------------------*
* Request and Get Method
*----------------------------------------------------------------------*
FORM http_client_request_get_method USING p_http_client TYPE REF TO if_http_client..
* Request and Get
p_http_client->request->set_header_field( name = '~request_method' value = 'GET' ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form HTTP_CLIENT_SEND
*&---------------------------------------------------------------------*
* Send request
*----------------------------------------------------------------------*
FORM http_client_send USING p_http_client TYPE REF TO if_http_client.
* Send the request
p_http_client->send( ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form HTTP_CLIENT_RECEIVE
*&---------------------------------------------------------------------*
* Get the string content
*----------------------------------------------------------------------*
FORM http_client_receive USING p_http_client TYPE REF TO if_http_client
CHANGING p_p_content TYPE string.
* Reterive the result
CALL METHOD p_http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4.
p_p_content = p_http_client->response->get_cdata( ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_COORDINATES
*&---------------------------------------------------------------------*
* Get Latitute Longitude Coordinate
*----------------------------------------------------------------------*
FORM get_coordinates USING p_p_content TYPE string.
* Local data declaration
DATA: lv_url TYPE c LENGTH 255,
ls_dest TYPE ty_dest,
moff TYPE syst-tabix,
moff1 TYPE syst-tabix,
lv_len TYPE syst-tabix,
lv_lat TYPE c LENGTH 20,
lv_lng TYPE c LENGTH 20.
*&---------------------------------------------------------------------*
*& Processing string
*&---------------------------------------------------------------------*
DO .
* Find <location> text in the content string
FIND '<location>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff .
IF sy-subrc = 0 .
* <location> is a 10 character string, hence adding 10
moff = moff + 10 .
* Find closing tag </location> text in the content string
FIND '</location>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff1 .
* Find the length of string between tag <location> and </location>
lv_len = moff1 - moff .
* We have seen the API string contet, so we know <lat> </lat> <lng> </lng> are there between
* <location> and </location>
*--------------------------------------------------------------------*
* ---------------Find latitude
*--------------------------------------------------------------------*
* Find string <lat>
FIND '<lat>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff .
IF sy-subrc = 0 .
* <lat> is a 5 character string, hence adding 5
moff = moff + 5 .
* Find closing tag </lat> text in the content string
FIND '</lat>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff1 .
* Find the length of string between tag <lat> and </lat>
lv_len = moff1 - moff .
* Characters between <lat> </lat> will have the latitude coorniate
lv_lat = p_p_content+moff(lv_len) .
* From place address
ls_dest-place_f = p_add_f .
* Keep latitude in structure
ls_dest-lat_f = lv_lat.
ENDIF.
*--------------------------------------------------------------------*
* ---------------Find longitude
*--------------------------------------------------------------------*
* Find string <lng>
FIND '<lng>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff .
IF sy-subrc = 0 .
* <lng> is a 5 character string, hence adding 5
moff = moff + 5 .
* Find closing tag </lng> text in the content string
FIND '</lng>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff1 .
* Find the length of string between tag <lng> and </lng>
lv_len = moff1 - moff .
* Characters between <lng> </lng> will have the latitude coorniate
lv_lng = p_p_content+moff(lv_len) .
* Keep longitude in structure
ls_dest-lng_f = lv_lng.
ENDIF.
ELSE.
EXIT.
ENDIF.
ENDDO .
* Put in internal table to display later
APPEND ls_dest TO gt_dest.
CLEAR:ls_dest .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form DISPLAY_LAT_LONGITUDE
*&---------------------------------------------------------------------*
* Display Latitude and Longitude
*----------------------------------------------------------------------*
FORM display_lat_longitude .
DATA:
lr_alv TYPE REF TO cl_salv_table,
lr_columns TYPE REF TO cl_salv_columns_table,
lr_column TYPE REF TO cl_salv_column,
lr_functions TYPE REF TO cl_salv_functions_list,
lr_display TYPE REF TO cl_salv_display_settings,
lr_layout TYPE REF TO cl_salv_layout,
ls_key TYPE salv_s_layout_key,
lr_sorts TYPE REF TO cl_salv_sorts.
" Check to make sure the internal table has data.
IF lines( gt_dest ) > 0.
TRY.
* Create ALV instance
* Use CALL METHOD since this is a static method
CALL METHOD cl_salv_table=>factory
IMPORTING
r_salv_table = lr_alv
CHANGING
t_table = gt_dest.
* Get functions object and then set all the functions to be allowed
lr_functions = lr_alv->get_functions( ).
lr_functions->set_all( ).
lr_columns = lr_alv->get_columns( ).
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'PLACE_F'
RECEIVING
value = lr_column.
CALL METHOD lr_column->set_short_text
EXPORTING
value = ''.
CALL METHOD lr_column->set_medium_text
EXPORTING
value = ''.
CALL METHOD lr_column->set_long_text
EXPORTING
value = 'Place Name'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'LAT_F'
RECEIVING
value = lr_column.
CALL METHOD lr_column->set_short_text
EXPORTING
value = ''.
CALL METHOD lr_column->set_medium_text
EXPORTING
value = ''.
CALL METHOD lr_column->set_long_text
EXPORTING
value = 'Latitude'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'LNG_F'
RECEIVING
value = lr_column.
CALL METHOD lr_column->set_short_text
EXPORTING
value = ''.
CALL METHOD lr_column->set_medium_text
EXPORTING
value = ''.
CALL METHOD lr_column->set_long_text
EXPORTING
value = 'Longitude'.
lr_columns->set_optimize( ).
* Set sort column
lr_sorts = lr_alv->get_sorts( ).
lr_sorts->clear( ).
* This code is to get the layout, save the layout and display the layout
lr_layout = lr_alv->get_layout( ).
ls_key-report = sy-repid.
lr_layout->set_key( ls_key ).
lr_layout->set_default( ' ' ).
lr_layout->set_save_restriction( cl_salv_layout=>restrict_none ).
lr_display = lr_alv->get_display_settings( ).
lr_display->set_striped_pattern( cl_salv_display_settings=>true ).
* Now display the report as an ALV grid
lr_alv->display( ).
CATCH cx_salv_msg.
WRITE: 'Error displaying grid CX_SALV_MSG!'(001).
CATCH cx_salv_not_found.
WRITE: 'Error displaying grid CX_SALV_NOT_FOUND!'(002).
CATCH cx_salv_data_error.
WRITE: 'Error displaying grid CX_SALV_DATA_ERROR!'(003).
CATCH cx_salv_existing.
WRITE: 'Error displaying grid CX_SALV_EXISTING!'(004).
ENDTRY.
ELSE.
MESSAGE 'No data to display' TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDIF.
ENDFORM.