We saw how we can get the latitude and longitude of any address using Google Map API. Adding to that learning, in this post, we would learn how to get the distance between two addresses. We would also see how we can derive turn by turn directions between two given addresses. To add more to the fun, we would also open a browser from SAP and display the route between two points on the map.
Do you think, this is interesting?
In short, this tool would act like a GPS in SAP, which would help you get the Coordinates (Latitudes/Longitudes), Route and Map with complete direction.
Before we check, how it can be done, let us first see, what we are talking about.
I. First radio button: Coordinates & Distance
We get the Coordinates of two addresses and also the distance between them.
II. Second Radio button: Turn by turn route
The tool would provide you the complete break-up of the route from the source to the destination address. It would also provide you with multiple routes if available.
II. Let’s check the third radio button which says ‘Display Map‘.
As requested, this GPS Tool would display the map along with the routes in a Web Browser. Check this out.
Did you like it?
You can use the code snippet provided at the end of this article and try it yourself. The code provided here would work as it is. The concept was already explained in our earlier post ‘Get Latitude and Longitude of any place using Google Map API in SAP’.
For the three output options, we need to call three APIs. As explained in the earlier article, we concatenate the strings with source and destination address, Latitudes and Longitudes etc to complete the API URL and get the XML data. Reading through the XML data and pinpointing the needed information is the trick which we have already learned.
a) GeoCode API String for Coordinates:
* Prepare the url of the GeoCode API
CONCATENATE
'http://maps.google.com/maps/api/geocode/xml?address='
lv_address
INTO lv_http_url .
b) Distance Matrix API String for retrieving the distance between Coordinates:
* Prepare the url for the DistanceMatrix API using From Address Coordinates and To Address Coordinates
CONCATENATE
'http://maps.googleapis.com/maps/api/distancematrix/xml?origins='
<fs_dest>-place_f '|' <fs_dest>-lat_f ',' <fs_dest>-lng_f ','
'&destinations=' <fs_dest>-place_t '|' <fs_dest>-lat_t ',' <fs_dest>-lng_t
'&alternatives=' 'true'
INTO lv_http_url .
c) Directions API String to trace the route on the Map:
* Prepare the url for Directions API for the From Address Coordinates and To Address Coordinates
CONCATENATE
'http://maps.googleapis.com/maps/api/directions/xml?origin='
<fs_dest>-place_f '|' <fs_dest>-lat_f ',' <fs_dest>-lng_f
'&destination=' <fs_dest>-place_t '|' <fs_dest>-lat_t ',' <fs_dest>-lng_t
'&alternatives=' 'true'
INTO lv_http_url .
where:
lv_address = From/To address
<fs_dest>-place_f = From address
<fs_dest>-lat_f = From address latitude
<fs_dest>-lng_f = From address longitude
<fs_dest>-place_t = To address
<fs_dest>-lat_t = To address latitude
<fs_dest>-lng_t = To address longitude
Once you have the correct API URL, use this cl_http_client class and create_by_url method to get the detailed information.
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.
Please go through the detailed code to check how it works. There might be better ways to read these APIs and XML data but we just wanted to show the possibilities. You can explore more and figure out the best way for you.
If you find any difficulty in understanding the code or concept, please do write to us or leave your question in the comment section. We would surely respond.
If you have doubt whether this tool would work for Non-India address. Be rest assured, it works for any address. Check the output for the address in the USA.
*-----------------------------------------------------------------------
* Author : SAPSPOT (www.sapspot.com)
* Title : Get Latitude and Longitude of a place from Google API
* Get distance between two addresses
* Show the turn by turn route of two addresses
* Show route in map in a browser
*-----------------------------------------------------------------------
* Change History :
* Author DATE REQUEST# DESCRIPTION
*--------------- ---------- ----------- -------------------------------
* SAPSPOT 05/27/2016 Intial Development
*-----------------------------------------------------------------------
REPORT zsapspot_gps_google_api NO STANDARD PAGE HEADING
LINE-COUNT 132.
*&---------------------------------------------------------------------*
*& TYPE-POOLS
*&---------------------------------------------------------------------*
TYPE-POOLS: truxs, slis.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-t01.
PARAMETERS : p_add_f TYPE c LENGTH 50,
p_add_t TYPE c LENGTH 50.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-t02.
PARAMETERS:
p_alv RADIOBUTTON GROUP spot,
p_route RADIOBUTTON GROUP spot,
p_map RADIOBUTTON GROUP spot.
SELECTION-SCREEN END OF BLOCK b2.
*&---------------------------------------------------------------------*
*& Types and Data
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_dest,
place_f TYPE c LENGTH 50, " From Place
place_t TYPE c LENGTH 50, " To Place
lat_f TYPE c LENGTH 20, " From Latitude
lng_f TYPE c LENGTH 20, " From Longitude
lat_t TYPE c LENGTH 20, " To Latitude
lng_t TYPE c LENGTH 20, " To Longitude
dis TYPE c LENGTH 30, " Distance
END OF ty_dest,
BEGIN OF ty_route,
route_n TYPE c LENGTH 255, " Start of New Route
summary TYPE c LENGTH 120, " Route Summary
step TYPE syst_tabix, " Turn step
ins TYPE c LENGTH 255, " Instruction
dis TYPE c LENGTH 20, " Distance
END OF ty_route.
TYPES: t_ty_route TYPE TABLE OF ty_route.
DATA:
gt_dest TYPE STANDARD TABLE OF ty_dest,
gt_route TYPE STANDARD TABLE OF ty_route.
FIELD-SYMBOLS:
<fs_dest> TYPE ty_dest.
*&---------------------------------------------------------------------*
*& Start of Selection
*&---------------------------------------------------------------------*
START-OF-SELECTION .
* Get longitude and latitude of From Address
PERFORM get_long_lat USING p_add_f.
* Get longitude and latitude of To Address
PERFORM get_long_lat USING p_add_t.
*&---------------------------------------------------------------------*
*& End of Selection
*&---------------------------------------------------------------------*
END-OF-SELECTION .
* Get distance between two address
PERFORM measure_distance.
* Get detailed turn by turn address
PERFORM turn_by_turn_route.
* Show the output
PERFORM show_output.
************************************************************************
*&---------------------------------------------------------------------*
*& Sub Routines
*&---------------------------------------------------------------------*
************************************************************************
FORM get_long_lat USING lv_address TYPE char50.
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 USING lv_address
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 lv_address.
ENDFORM. " get_long_lat
*&---------------------------------------------------------------------*
*& Form CREATE_HTTP_CLIENT
*&---------------------------------------------------------------------*
* Create HTTP Client
*----------------------------------------------------------------------*
FORM create_http_client USING lv_address TYPE char50
CHANGING p_http_client TYPE REF TO if_http_client.
DATA: lv_http_url TYPE string.
* Prepare the url of the GeoCode API
CONCATENATE
'http://maps.google.com/maps/api/geocode/xml?address='
lv_address
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.
* CALL METHOD p_http_client->response->get_cdata(
* RECEIVING
* data = p_p_content " Character data
* EXCEPTIONS
* OTHERS = 1 ).
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
lv_address TYPE char50.
* 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.
* Field symbol
FIELD-SYMBOLS:
<lfs_dest> TYPE ty_dest.
*&---------------------------------------------------------------------*
*& 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 = lv_address .
* 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 .
IF gt_dest[] IS INITIAL.
* This part would trigger for From Latitude and Longitude
* Put in internal table to display later
APPEND ls_dest TO gt_dest.
CLEAR:ls_dest .
ELSE.
* This part would trigger for To Latitude and Longitude
READ TABLE gt_dest ASSIGNING <lfs_dest> INDEX 1.
IF sy-subrc EQ 0.
<lfs_dest>-place_t = lv_address.
<lfs_dest>-lat_t = ls_dest-lat_f.
<lfs_dest>-lng_t = ls_dest-lng_f.
ENDIF.
ENDIF.
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 = 'From 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 = 'From 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 = 'From Longitude'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'PLACE_T'
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 = 'To Place Name'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'LAT_T'
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 = 'To Latitude'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'LNG_T'
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 = 'To Longitude'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'DIS'
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 = 'Distance between From & To Address'.
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.
*&---------------------------------------------------------------------*
*& Form MEASURE_DISTANCE
*&---------------------------------------------------------------------*
* Get distance between the from and to address
*----------------------------------------------------------------------*
FORM measure_distance .
DATA:
lv_http_client TYPE REF TO if_http_client,
lv_content TYPE string.
LOOP AT gt_dest ASSIGNING <fs_dest>.
* Creation of new IF_HTTP_Client object
PERFORM create_http_client_dist 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_dist USING lv_content.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_HTTP_CLIENT_DIST
*&---------------------------------------------------------------------*
* * Create HTTP Client
*----------------------------------------------------------------------*
FORM create_http_client_dist CHANGING p_http_client TYPE REF TO if_http_client.
DATA: lv_http_url TYPE string.
* Prepare the url for the DistanceMatrix API From Address Coordinates and To Address Coordinates
CONCATENATE
'http://maps.googleapis.com/maps/api/distancematrix/xml?origins='
<fs_dest>-place_f '|' <fs_dest>-lat_f ',' <fs_dest>-lng_f ','
'&destinations=' <fs_dest>-place_t '|' <fs_dest>-lat_t ',' <fs_dest>-lng_t
'&alternatives=' 'true'
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 GET_COORDINATES_DIST
*&---------------------------------------------------------------------*
* Get Latitute Longitude Coordinate
*----------------------------------------------------------------------*
FORM get_coordinates_dist 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.
* Field symbol
FIELD-SYMBOLS:
<lfs_dest> TYPE ty_dest.
*&---------------------------------------------------------------------*
*& Processing string
*&---------------------------------------------------------------------*
DO .
* Find <distance> text in the content string
FIND '<distance>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff .
IF sy-subrc = 0 .
* <distance> is a 10 character string, hence adding 10
moff = moff + 10 .
* Find closing tag </distance> text in the content string
FIND '</distance>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff1 .
** Find the length of string between tag <distance> and </distance>
* lv_len = moff1 - moff .
* We have seen the API string contet, so we know <text> </text> are there between
* <distance> and </distance>
FIND '<text>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff .
IF sy-subrc = 0 .
* <text> is a 6 character string, hence adding 6
moff = moff + 6 .
* Find closing tag </text> text in the content string
FIND '</text>' IN SECTION OFFSET moff OF p_p_content IGNORING CASE MATCH OFFSET moff1 .
* Find the length of string between tag <text> and </text>
lv_len = moff1 - moff .
* Characters between <text> </text> will have the distance
<fs_dest>-dis = p_p_content+moff(lv_len).
* Get one distance and exit
EXIT.
ENDIF.
ELSE.
EXIT.
ENDIF.
ENDDO .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SHOW_OUTPUT
*&---------------------------------------------------------------------*
* Show output
*----------------------------------------------------------------------*
FORM show_output .
IF p_alv IS NOT INITIAL.
* Show Latitute, Longitude and Distance
PERFORM display_lat_longitude.
ELSEIF p_route IS NOT INITIAL.
* Show the complete break down of driving route
PERFORM display_turn_by_turn_route.
ELSEIF p_map IS NOT INITIAL.
* Show direction in map
PERFORM show_map.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form TURN_BY_TURN_ROUTE
*&---------------------------------------------------------------------*
* Get turn by turn ROUTE
*----------------------------------------------------------------------*
FORM turn_by_turn_route .
DATA:
lv_http_client TYPE REF TO if_http_client,
lv_content TYPE string,
lv_xstring TYPE xstring,
li_xml_table TYPE TABLE OF smum_xmltb.
IF p_route IS NOT INITIAL.
LOOP AT gt_dest ASSIGNING <fs_dest>.
* Creation of new IF_HTTP_Client object
PERFORM create_http_client_direction 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_dist USING lv_content.
* Convert String to XString
PERFORM convert_string_to_xstring USING lv_content CHANGING lv_xstring.
* Parse XML document into a table structure
PERFORM parse_xml_to_table USING lv_xstring CHANGING li_xml_table.
* Clean XML file
PERFORM clean_xml_data USING li_xml_table.
ENDLOOP.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CONVERT_STRING_TO_XSTRING
*&---------------------------------------------------------------------*
* Convert sting to xstring
*----------------------------------------------------------------------*
FORM convert_string_to_xstring USING p_p_content TYPE string
CHANGING p_p_xstring TYPE xstring.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = p_p_content
IMPORTING
buffer = p_p_xstring
EXCEPTIONS
failed = 1
OTHERS = 2.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form PARSE_XML_TO_TABLE
*&---------------------------------------------------------------------*
* Parse XML docment into a table structure
*----------------------------------------------------------------------*
FORM parse_xml_to_table USING p_p_xstring TYPE xstring
CHANGING p_li_xml_table TYPE hrpayfr_t_smum_xmltb.
DATA:
li_return TYPE TABLE OF bapiret2.
CALL FUNCTION 'SMUM_XML_PARSE'
EXPORTING
xml_input = p_p_xstring
TABLES
xml_table = p_li_xml_table
return = li_return.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_HTTP_CLIENT_DIRECTION
*&---------------------------------------------------------------------*
* Get Direction API
*----------------------------------------------------------------------*
FORM create_http_client_direction CHANGING p_http_client TYPE REF TO if_http_client.
DATA: lv_http_url TYPE string.
* Prepare the url for Directions API for the From Address Coordinates and To Address Coordinates
CONCATENATE
'http://maps.googleapis.com/maps/api/directions/xml?origin='
<fs_dest>-place_f '|' <fs_dest>-lat_f ',' <fs_dest>-lng_f
'&destination=' <fs_dest>-place_t '|' <fs_dest>-lat_t ',' <fs_dest>-lng_t
'&alternatives=' 'true'
INTO lv_http_url .
CONDENSE 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 CLEAN_XML_DATA
*&---------------------------------------------------------------------*
* Clean XML data to cleaner format
*----------------------------------------------------------------------*
FORM clean_xml_data USING p_li_xml_table TYPE hrpayfr_t_smum_xmltb.
DATA:
ls_xml TYPE smum_xmltb,
ls_path TYPE ty_route.
* Deleting time mentioned in the XML. If you want time, you need to
* keep this and manipulate later
DELETE p_li_xml_table WHERE cvalue CS 'min'.
* Remove sub total for partial route. If you want time, you need to
* keep this and manipulate later
DELETE p_li_xml_table WHERE
hier = '5' AND
type = 'V' AND
cname = 'text'.
* Reading the XML data
LOOP AT p_li_xml_table INTO ls_xml.
AT FIRST.
* First step is new route by default
ls_path-route_n = abap_true.
ENDAT.
* Remove the XML format tag codes
REPLACE ALL OCCURRENCES OF '<b>' IN ls_xml-cvalue WITH space.
REPLACE ALL OCCURRENCES OF '</b>' IN ls_xml-cvalue WITH space.
* Remove the XML format tag codes
REPLACE ALL OCCURRENCES OF '<div style="font-size:0.9em">' IN ls_xml-cvalue WITH '.'.
REPLACE ALL OCCURRENCES OF '</div>' IN ls_xml-cvalue WITH space.
* Check the name
CASE ls_xml-cname.
* Get the summary of the route
WHEN 'summary'.
ls_path-summary = ls_xml-cvalue.
* Driving instruction
WHEN 'html_instructions'.
ls_path-ins = ls_xml-cvalue.
* Text would have the distance and unit
WHEN 'text'.
ls_path-dis = ls_xml-cvalue.
* Copyrights means, start of new path
WHEN 'copyrights'.
ls_path-route_n = 'X'.
CLEAR ls_path-step.
WHEN OTHERS.
* do nothing
ENDCASE.
* If there is some data, populate the route table
IF ls_path-ins IS NOT INITIAL
AND ls_path-dis IS NOT INITIAL.
ls_path-step = ls_path-step + 1.
* This will have the route details
APPEND ls_path TO gt_route.
CLEAR: ls_path-ins, ls_path-dis, ls_path-route_n, ls_path-summary.
ENDIF.
CLEAR: ls_xml.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form DISPLAY_TURN_BY_TURN_ROUTE
*&---------------------------------------------------------------------*
* Display Turn by Turn route
*----------------------------------------------------------------------*
FORM display_turn_by_turn_route .
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_route ) > 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_route.
* 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 = 'ROUTE_N'
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 = 'New Route Indicator'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'SUMMARY'
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 = 'Via'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'STEP'
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 = 'Important Turns'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'INS'
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 = 'Instructions'.
CALL METHOD lr_columns->get_column
EXPORTING
columnname = 'DIS'
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 = 'Distance'.
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 route data to display' TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SHOW_MAP
*&---------------------------------------------------------------------*
* Show direction on the map
*----------------------------------------------------------------------*
FORM show_map .
DATA:
lv_http_client TYPE REF TO if_http_client,
lv_content TYPE string.
LOOP AT gt_dest ASSIGNING <fs_dest>.
* Call Browser
PERFORM call_browser.
EXIT.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CALL_BROWSER
*&---------------------------------------------------------------------*
* Route map
*----------------------------------------------------------------------*
FORM call_browser.
DATA: lv_url TYPE c LENGTH 255.
* Prepare the url for Directions API for the From Address Coordinates and To Address Coordinates
CONCATENATE
'https://www.google.co.in/maps/dir/'
<fs_dest>-lat_f ',' <fs_dest>-lng_f '/'
<fs_dest>-lat_t ',' <fs_dest>-lng_t
INTO lv_url .
* Condense the text
CONDENSE lv_url.
* Open the route in browser
CALL FUNCTION 'CALL_BROWSER'
EXPORTING
url = lv_url
EXCEPTIONS
frontend_not_supported = 1
frontend_error = 2
prog_not_found = 3
no_batch = 4
unspecified_error = 5
OTHERS = 6.
ENDFORM.