Skip to Content
*Update Oct, 13th 2006:* Google Maps are now also avaliable for Enterprise use (http://www.google.com/enterprise/maps/index.html). *Update:* Have also a look at {code:html}Geocoding – the next step: Routing with Map24 AJAX API{code} Inspired by Eddy De Clercq’s (Eddy%20De%20Clercq’s) SDN World Map (http://sdn.idizaai.be/sdn_world/sdn_world.html) and the German Podcast Pimp My Brain (http://tellerrand.typepad.com/tellerrand/pimp_my_brain/index.html) where they introduced me into Google Maps (http://www.google.com/apis/maps/) I’ve tried out to combine this with our SAP CRM People Centric User Interface (PC-UI). The result is this little BSP application which uses ABAP Object Persistence Service (http://help.sap.com/saphelp_nw04/helpdata/en/f5/a36828bc6911d4b2e80050dadfb92b/frameset.htm) and Simple Transformations (Fifth ABAP Online Meet-up: Simple Transformations). During my research about geocoding in a SAP environment I found Geocoding for BW (http://help.sap.com/saphelp_erp2004/helpdata/en/3b/7c93ec1bed374ee0000800091c1b0e/frameset.htm) and Geocoding for Business Partners (http://help.sap.com/saphelp_erp2004/helpdata/en/19/0353f6e7689b43a43615e25655eeb4/frameset.htm). You find more information about this topic in the SPRO customizing transaction at SAP NetWeaver -> General Settings -> Set Geocoding. Unfortunately I’ve found no documentation how to implement this standard interface and I implemented my own. External Geocoding solutions can be found in the Partner Directory Solution Search (http://www.sap.com/partners/directories/SearchSolution.epx). SAP Notes regarding Geocoding can be found in the OSS Application Area BC-SRV-GEO. There is also an SDN Article “[Using Geo Services with Web Dynpro | https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/webdynpro/using%20geo%20services%20with%20web%20dynpro.pdf]” which uses the standard interface which calls external providers using the IGS. But now let’s start to build our solution which will result in: image h3. Preparation h4. Sign up to the Google Maps API To use Google Maps (http://www.google.com/apis/maps/) you have to Sign up for the Google Maps API (http://www.google.com/apis/maps/signup.html). You have to provide the web site URL which must exactly match your WebAS URL including the Port. I. e. http://webas.test.com:8000/. After the sign up you get a sample HTML Source which you can save locally and play around using the API Documentation (http://www.google.com/apis/maps/documentation/).

h4. Create Database Table for Geocoding Data I’ve put all development objects together in the Package ZBPGOOGLEMAP: image Here I’ve created also the DB Table ZBPGEOCODE which will contain the Geocode information for a Business Partner (BP). To detect changes on the BP I also save Street, Street No., Postal Code and City in this table. image h4. Create Persistent class for Geocoding Data A long time ago I’ve read Thomas Jung (/people/thomas.jung/blog)’s Weblog on “[ABAP Persistent Classes: Coding without SQL | ABAP Persistent Classes: Coding without SQL]” but never tried it on my own. But here I’ve done it and created the Class ZCL_BPGEOCODE which is from Class Type “Persistent class”. All the rest is described in detail in the mentioned Blog. Be aware that you have to use the DB Table ZBPGEOCODE.

h4. Transform Google KML to ABAP I did not attend the ABAP Online Meet-up on Simple Transformations (Fifth ABAP Online Meet-up: Simple Transformations) but it inspired me to use this to transform the return of the Geocoding HTTP Request (http://www.google.com/apis/maps/documentation/#Geocoding_HTTP_Request) into an ABAP Structure. To test the Transformation I first downloaded the result of this request to my local drive: http://maps.google.com/maps/geo?q=Neurottstr.+15a,+Walldorf,+DE&output=xml&key=… h3. Implement the BSP * event handler for checking and processing user input and * for defining navigation DATA: ls_addressdata TYPE bapibus1006_address. IF NOT bp IS INITIAL. * Get leading zeros for BP Number CALL FUNCTION ‘BAPI_BUPA_GET_NUMBERS’ EXPORTING businesspartner = bp IMPORTING businesspartnerout = bp. * Get BP’s default address CALL FUNCTION ‘BAPI_BUPA_ADDRESS_GETDETAIL’ EXPORTING businesspartner = bp IMPORTING addressdata = ls_addressdata. * Prepare the address to display in marker CONCATENATE ls_addressdata-street ls_addressdata-house_no ‘ ‘ ls_addressdata-postl_cod1 ls_addressdata-city INTO address SEPARATED BY space. * Prepare the address as a Google Maps destination CONCATENATE ls_addressdata-street ls_addressdata-house_no ‘,’ ls_addressdata-postl_cod1 ls_addressdata-city INTO mapadd SEPARATED BY ‘%20’. * Get Users Address as the from address data: USER_ADDRESS type ADDR3_VAL. CALL FUNCTION ‘SUSR_USER_ADDRESS_READ’ EXPORTING user_name = sy-uname IMPORTING USER_ADDRESS = USER_ADDRESS. CONCATENATE USER_ADDRESS-street USER_ADDRESS-house_num1 ‘,’ USER_ADDRESS-post_code1 USER_ADDRESS-city1 INTO fromadd SEPARATED BY ‘%20’. * Check if Geocoding for address already exists DATA: geocode TYPE zbpgeocode. DATA: connection TYPE REF TO zcl_bpgeocode, agent TYPE REF TO zca_bpgeocode. DATA: exc TYPE REF TO cx_root, getgeocode TYPE flag, updategeocode TYPE flag. agent = zca_bpgeocode=>agent. TRY. * Get Persistence Object by Key connection = agent->get_persistent( i_partner = bp ). * Has the Address been changed? IF ls_addressdata-street = connection->get_street( ) AND ls_addressdata-house_no = connection->get_house_no( ) AND ls_addressdata-postl_cod1 = connection->get_postl_cod1( ) AND ls_addressdata-city = connection->get_city( ). geocode-lon = connection->get_lon( ). geocode-lat = connection->get_lat( ). geocode-alt = connection->get_alt( ). ELSE. * Address was changed and needs to be updated getgeocode = ‘X’. updategeocode = ‘X’. ENDIF. * Object does not exist. So we have to get the geocode CATCH cx_root INTO exc. getgeocode = ‘X’. ENDTRY. IF getgeocode = ‘X’. * HTTP Client according to * BSP: Create a weather magnet using xml feed from weather.com DATA: client TYPE REF TO if_http_client, url TYPE string, c_xml TYPE string. * Build URL to call Googe Maps Geocoding url = ‘http://maps.google.com/maps/geo?q=‘. IF NOT ls_addressdata-house_no IS INITIAL. CONCATENATE url ls_addressdata-house_no ‘+’ INTO url. ENDIF. CONCATENATE url ls_addressdata-street ‘,’ INTO url. CONCATENATE url ls_addressdata-postl_cod1 ‘,’ ls_addressdata-city ‘,’ ls_addressdata-countryiso ‘&output=xml’ ‘&key=…’ INTO url. ****Create the HTTP client CALL METHOD cl_http_client=>create_by_url EXPORTING url = url IMPORTING client = client EXCEPTIONS OTHERS = 1. client->send( ). client->receive( ). ****Get the response content in Character format c_xml = client->response->get_cdata( ). ****Transform XML to ABAP Values CALL TRANSFORMATION zgoogle_geocode_to_abap SOURCE XML c_xml RESULT geocode = geocode. IF NOT geocode IS INITIAL. MOVE-CORRESPONDING ls_addressdata TO geocode. geocode-partner = bp. geocode-erzet = sy-uzeit. geocode-erdat = sy-datum. IF updategeocode = ‘X’. * Update Persistent Object connection->set_erzet( geocode-erzet ). connection->set_erdat( geocode-erdat ). connection->set_lon( geocode-lon ). connection->set_lat( geocode-lat ). connection->set_alt( geocode-alt ). connection->set_street( geocode-street ). connection->set_house_no( geocode-house_no ). connection->set_postl_cod1( geocode-postl_cod1 ). connection->set_city( geocode-city ). COMMIT WORK. ELSE. * Create Persistent Object TRY. connection = agent->create_persistent( i_partner = geocode-partner i_erdat = geocode-erdat i_erzet = geocode-erzet i_lon = geocode-lon i_lat = geocode-lat i_alt = geocode-alt i_street = geocode-street i_house_no = geocode-house_no i_postl_cod1 = geocode-postl_cod1 i_city = geocode-city ). COMMIT WORK. ENDTRY. ENDIF. ENDIF. ENDIF. ENDIF. * Only fill Mapcenter if geocode is valid IF NOT geocode IS INITIAL. DATA: lat type string, lon type string. * Prepere Latitude for Javascript IF geocode-lat < 0. geocode-lat = geocode-lat * -1. lat = geocode-lat. CONCATENATE ‘-‘ lat INTO lat. ELSE. lat = geocode-lat. ENDIF. * Prepere Longitude for Javascript IF geocode-lon < 0. geocode-lon = geocode-lon * -1. lon = geocode-lon. CONCATENATE ‘-‘ lon INTO lon. ELSE. lon = geocode-lon. ENDIF. CONCATENATE lat ‘,’ lon INTO mapcenter. ENDIF. Also here insert your own key to the generated URL. The result is this little BSP Application which provides a Map with a marker where our Business Partner is located.: image After the extension suggested by Ranjan Kumar (https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.sdn.businesscard.sdnbusinesscard?u=rm2di2raa5snpbq80kwe1g%3d%3d) the layout is now: image When you click on the “Directions” Link you see what Google suggests me to drive home. image

To report this post you need to login first.

17 Comments

You must be Logged on to comment or reply to a post.

    1. Alvaro Tejada Galindo
      Hi Gregor:

      What can I say…You always surprise me! -:D
      Your blog is really great…On my of implementation projects…A company tried to do something like that for the IS-U system…But they didn’t get even close to you…At first I tought that they work was great…After watching what can be done by mixing Google Maps and SAP…I just don’t want to see those guys again..hehehe….Thanx for open my eyes to such a great application!

      Greetings,

      Blag.

      (0) 
      1. Gregor Wolf Post author
        Hi Blag,

        thanks for that amazing comment. Perhaps when they tried to do it the Google Maps API was not avaliable?

        Regards
        Gregor

        (0) 
        1. Valery Silaev
          [cite]Perhaps when they tried to do it the Google Maps API was not avaliable?[/cite]

          GMaps API is here for quite long time, however GMaps _Geocoding_ API was released less then week ago.

          Hence Eddy and me stick with Yahoo Maps for “SDN World” (that includes geocoding from the very first day).

          VS

          (0) 
          1. Gregor Wolf Post author
            Hi VS,

            will try to do the same with Yahoo Maps the next weekend. I like their interface because of the support of the mouse weel.

            Regards
            Gregor

            (0) 
  1. Marilyn Pratt
    My young son will be so jealous.  He thought he could copyright this idea of IGS and enterprise software and offer it for sale…and you’ve gone and implemented his “IP”.  Great blog, incredible use of lots of the elements found here on SDN in shared learning sessions and contents.

    Bravo!

    (0) 
  2. Anonymous
    Hi Gregor,

    you’re like an “innovation machine” throwing out great ideas. Meanwhile I’m having troubles implementing all your solutions. Pls slow down 😉

    Regards
    Wolfgang

    (0) 
  3. Anton Wenzelhuemer
    Hi Gregor,
    thx for sharing this veeeery nice example.

    I immediately had a look at it myself and observed the following which is worth mentioning: Your detailed example addresses suggest a quality of address data which isn’t met in general.

    E.g, in Austria, you can’t search for street names. Moreover, if you enter “Karlsplatz, Wien” or “Karlsplatz, Vienna” (which is the most central point in Vienna, Austria)it doesn’t even give you some general geocodes for Vienna, Austria but it returns you NULL (that is 602 in the http request).

    Now, the quality doesn’t seem to be the same even for a city like, say, barcelona as in your example. what works for one street doesn’t necessarily work for another street.

    Well, that’s definitely not your fault, but I think one has to be aware of that and maybe adopt your examples for the very likely probability, that a given BP adress returns NULL from the geocoding part.

    regards,
    anton

    (0) 
    1. Gregor Wolf Post author
      Hi Anton,

      I’ve noticed this problem during my test. The best results I’ve got for Germany and the US. I will try Yahoo Maps and perhaps Map24 if they give better results.

      Regards
      Gregor

      (0) 
  4. Ranjan Kumar

    Hi Gregor,<br/><br/>          I have enhanced the functionality a little bit by adding Driving Directions to this application. I have added the following lines to the BSP Page:<br/><br/>GEvent.addListener(marker, “click”, function() {<br/>                marker.openInfoWindowHtml(“<%= address %> <br/> [Directions | http://maps.google.com/maps?saddr=<%= fromadd%>&daddr=<%= mapadd%>]”);<br/>              });<br/>                marker.openInfoWindowHtml(“<%= address %> <br/> [Directions | http://maps.google.com/maps?saddr=<%= fromadd%>&daddr=<%= mapadd%>]”);<br/>            }<br/><br/>I had to add 2 additional Attributes (fromadd, mapadd) to the BSP Page as well.<br/><br/>Basically what this does is provide a Directions hyperlink in the Google Maps Balloon….<br/><br/>Thanks,<br/><br/>Ranjan

    (0) 
    1. Gregor Wolf Post author
      Hello Ranjan,

      I’ve updated my Blog with your suggestion. I read the fromadd from the actual Users Company address. For more info have a look in the OnInputProcessing Event Handler.

      Regards
      Gregor

      (0) 
  5. sandro cuzzolin
    Hi Gregor,
    I implemented your blog and I got some strange results: I hope you can help me!
    when I launch the application I get the first html page, where I enter BP number. Afterwards I get another html page, in which I can see just BP form.
    But if I look at the html code, I’ve got all the informations I need from google maps.
    In addition, I can tell you I’m calling my (your) BSP application from a private website of a company. But if I copy the same html page in a local page and I call it with a browser, gmaps is called correctly and the map is correctly shown!
    But the page is exactly the same!!! Could it be that google blocks map visualization if I call it from inside a private company website?
    Otherwise it can be a matter of checking events in BSP… but I’m quite sure I followed your blog properly.
    Thank you in advance,
    Sandro Cuzzolin
    (0) 
    1. Gregor Wolf Post author
      Hello Sandro,

      have you registered your Server with the full qualified hostname and do you use this hostname also in the application? Perhaps you have to the the Parameter icm/host_name_full as described in OSS Note 434918. Also Check that URL which is created in the Model Access Class uses the FQDN.

      Regards
      Gregor

      (0) 
  6. Prashanth KR
    Hi Gregor Wolf,

    your Blogs are really amazing.

    I tried to implement the same but ended up with some issues. I followed the same procedure as mentioned in your blog but when i ran the BSP Application the map appeared to be greyed out (not able to view the map). I debugged the program and found the values for business partner being fetched properly and everything was fine in it, but i don’t know why it does’nt work.

    Suggestion on this from your side would be greatly appreciated if there are any Basic Customizing to be done or any steps missing which I should have done.

    Keep your great work going. expecting some wonderful blogs like this in future too.

    Thanks,
    Prashanth

    (0) 

Leave a Reply