Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
gregorw
Active Contributor
0 Kudos
Last week I've started with Geocode Business Partner with Google Maps (Geocode Business Partner with Google Maps). As promised in the Blog Comments I will extend this approach using the Map24 AJAX API (http://devnet.map24.com/). They provide an easy interface for routing. The result is integrated into the PC-UI Application COMM_BUPAR which comes with SAP ERP 2004: When you click on "Calculate Route" you see the Way Map24 suggests to me to drive to work: h3. Sign up to the Map24 AJAX API Like Google Maps (http://www.google.com/apis/maps/) you have to Sign up for the Map24 AJAX API (http://devnet.map24.com/index2.php?c=ajax_free_register). You have to provide the web site URL which must exactly match your WebAS URL including the Port and also the Path to your application. Unfortunately the plain path like /sap/bc/bsp/sap/zbpmap/ does not work. I've used http://webas.test.com:8000/sap(bD1kZSZjPTgwMCZkPW1pbg==)/bc/bsp/sap/zbpmap/. Be aware that the key is also bound to a Map. Currently Europe, North- and South America, Middle East, Australia and New Zeeland are available. After the sign up you get a sample HTML Source which you can save locally and play around using the Tutorials (http://devnet.map24.com/manuals/doku.php?id=ajax:1.0:tutorials:tutorials).

h3. Implement the BSP Unfortunately Map24 uses another type of Geographic Coordinates (http://devnet.map24.com/manuals/doku.php?id=glossary:geographiccoordinates). So I had to convert the Google Maps Coordinates. I've created the Page map24.htm in the BSP Application ZBPMAP. In addition to the Attributes we've used for the Google Maps implementation I've added the Attribute addressroute to fill the field "Destination Address" dynamically. You also can fill the "Start Address" dynamically i.e. from the Users Address data. But that's another story. So I've set a default Start Address to Siteco Beleuchtungstechnik GmbH (http://www.siteco.com/). var map = null; function goMap24() { map = Map24.Webservices.getMap24Application({ AppKey: "", MapArea: document.getElementById( "maparea" ), MapWidth: 900, MapHeight: 460 }); var mrcContainer = new Map24.Webservices.Request.MapletRemoteControl( map ); mrcContainer.push( new Map24.Webservices.MRC.SetMapView({Coordinates} ) }) ); map.Webservices.sendRequest( mrcContainer ); } function calculateRouteAddr( start, destination ){ if( typeof start == 'undefined' || start == '' ){ Map24.dump( "No start address defined!" ); return; } if( typeof destination == 'undefined' || destination == '' ){ Map24.dump( "No destination address defined!" ); return; } geocodeStartAndDestination( start, destination ); return; } function geocodeStartAndDestination( start, destination ){ //1. Geocode the start address geocode( start, onGeocodeStart ) //2. When start address has been geocoded, then geocode destination address function onGeocodeStart( geoRes ){ startGeocoded = geoRes.firstResult; geocode( destination, onGeocodeDest ) } //3. When both start and dest address have been geocoded, then start route calculation function onGeocodeDest( geoRes ){ destinationGeocoded = geoRes.firstResult; calculateRouteCoord( startGeocoded, destinationGeocoded ); } } //Calculate a route between two addresses function calculateRouteCoord( startGeocoded, destinationGeocoded ){ if( startGeocoded == 'NULL' || typeof startGeocoded == 'undefined' ) return; if( destinationGeocoded == 'NULL' || typeof destinationGeocoded == 'undefined' ) return; var routeRequest = new Map24.Webservices.Request.CalculateRoute( map ); routeRequest.Start = new Map24.Webservices.Request.CalculateRoute.CoordinateAndAddress(); routeRequest.Start.Coordinate = new Map24.Coordinate( startGeocoded.Coordinate.Longitude, startGeocoded.Coordinate.Latitude ); routeRequest.Destination = new Map24.Webservices.Request.CalculateRoute.CoordinateAndAddress(); /* routeRequest.Destination.Coordinate = new Map24.Coordinate( destinationGeocoded.Coordinate.Longitude, destinationGeocoded.Coordinate.Latitude ); */ routeRequest.Destination.Coordinate = new Map24.Coordinate( Please note that you have to insert your Key. In this application I use the Event Handler OnRequest because the Business Partner Number is provided by the PC-UI. I still use Google Maps to Geocode the Address because the Map24 Web Services (http://devnet.map24.com/index2.php?c=downloads#webservices) are not free. Also the WSDL File (http://maptp11.map24.com/map24/webservices1.5?soap=Map24Geocoder) they provide results in an error "Proxy generation terminated: Message must have exactly one part" when you try to create the Proxy Object. * The handler is called whenever a request is made for a particular page * it is used to restore the internal data structures from the request 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 for route calculation CONCATENATE ls_addressdata-street ls_addressdata-house_no ', ' ls_addressdata-postl_cod1 ls_addressdata-city INTO addressroute SEPARATED BY space. * 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, lattrunc TYPE i, lontrunc TYPE i, latfrac type DEC31_14, lonfrac type DEC31_14, latsign(1) type c, lonsign(1) type c. * Prepere Latitude for Javascript IF geocode-lat < 0. geocode-lat = geocode-lat * -1. lat = geocode-lat. latsign = '-'. ELSE. lat = geocode-lat. ENDIF. * Prepere Longitude for Javascript IF geocode-lon < 0. geocode-lon = geocode-lon * -1. lon = geocode-lon. lonsign = '-'. ELSE. lon = geocode-lon. ENDIF. * Calculate for Map24 lattrunc = TRUNC( geocode-lat ) * 60. lontrunc = TRUNC( geocode-lon ) * 60. latfrac = frac( geocode-lat ) * 60. lonfrac = frac( geocode-lon ) * 60. lat = lattrunc + latfrac. lon = lontrunc + lonfrac. CONCATENATE lonsign lon ',' latsign lat 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: h3. Include BSP into PC-UI Application First we have to create a Structure which I've called: ZCRMT_BSP_ACC_ROUTING h4. Model Access Class Create Class ZCL_ROUTING which implements Interface IF_CRM_BSP_MODEL_ACCESS_IL:
1 Comment