Page Example

Maps Sample Overview

Mobile native

The Maps application demonstrates how to use map services, such as geocoding, place search, and routing, using the Maps Service API.

The following figure illustrates the main view of the Maps application.

Figure: Maps main view

Maps main view

In the main view, you can perform various location-based operations, such as searching for locations and having them displayed on the map.

Prerequisites

To ensure proper application execution, the following privileges must be set:

  • http://tizen.org/privilege/mapservice
  • http://tizen.org/privilege/internet
  • http://tizen.org/privilege/network.get

Implementation

Application Main View

To create the application main view:

  1. Create the application layout with the create_base_gui() function:

    static void
    create_base_gui(appdata_s *ad)
    {
       // Window
       ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
       elm_win_conformant_set(ad->win, EINA_TRUE);
       elm_win_autodel_set(ad->win, EINA_TRUE);
    
       if (elm_win_wm_rotation_supported_get(ad->win)) 
       {
          int rots[4] = {0, 90, 180, 270};
          elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
       }
    
       evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
    
       // Conformant
       ad->conform = elm_conformant_add(ad->win);
       elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
       elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
       evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
       elm_win_resize_object_add(ad->win, ad->conform);
       evas_object_show(ad->conform);
    
       // Layout
       ad->layout = elm_layout_add(ad->conform);
       evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
       elm_layout_theme_set(ad->layout, "layout", "application", "default");
       elm_object_content_set(ad->conform, ad->layout);
       evas_object_show(ad->layout);
    
       ad->nf = elm_naviframe_add(ad->layout);
       elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
       eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
       evas_object_show(ad->nf);
    
       create_map_view(ad->nf);
    
       // Show the window after the base GUI is set up
       evas_object_show(ad->win);
    }
    
  2. Create a searchbar and a map view panel with the create_map_view() function:

    Evas_Object*
    create_map_view(Evas_Object *parent)
    {
       init();
    
       Evas_Object *view_layout = elm_layout_add(parent);
    
       MapLocationView(view_layout);
    
       Elm_Object_Item *navi_item = elm_naviframe_item_push(parent, "Maps Service Sample", 
                                                            NULL, NULL, view_layout, NULL);
       elm_naviframe_item_pop_cb_set(navi_item, __map_view_delete_request_cb, (void *)NULL);
    
       m_parent_evas_obj = parent;
       m_map_view_layout = view_layout;
    
       return view_layout;
    }
    
    static void
    MapLocationView(Evas_Object *view_layout)
    {
       char edj_path[PATH_MAX] = {0,};
    
       app_get_resource(MAP_VIEW_EDJ_FILE, edj_path, (int)PATH_MAX);
    
       dlog_print(DLOG_ERROR, LOG_TAG, "edj_path: %s", edj_path);
    
       elm_layout_file_set(view_layout, edj_path, "map-view");
       evas_object_size_hint_weight_set(view_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
       evas_object_size_hint_align_set(view_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
       evas_object_show(view_layout);
    
       if (!m_map_obj_layout) 
       {
          m_map_obj_layout = __create_map_object(view_layout);
          if (m_map_obj_layout == NULL) 
          {
             dlog_print(DLOG_ERROR, LOG_TAG, "failed to create map object");
    
             return;
          }
       }
    
       elm_object_part_content_set(view_layout, "map", m_map_obj_layout);
    
       if (!m_searchbar_obj)
          m_searchbar_obj = __create_map_searchbar(view_layout);
    
       if (m_searchbar_obj) 
       {
          elm_genlist_realized_items_update(m_searchbar_obj);
          elm_object_part_content_set(view_layout, "searchbar", m_searchbar_obj);
       }
    
       elm_object_focus_set(m_map_obj_layout, EINA_TRUE);
    
       elm_object_focus_custom_chain_append(view_layout, m_map_obj_layout, NULL);
       elm_object_focus_custom_chain_append(view_layout, m_searchbar_obj, NULL);
    }
    
  3. Create callbacks for scroll, longpress, and click events on the map with the __create_map_object() function:

    static Evas_Object*
    __create_map_object(Evas_Object *layout)
    {
       char edj_path[PATH_MAX] = {0,};
    
       if (m_map_evas_object != NULL) 
       {
          // WERROR("m_map_evas_object is created already");
    
          return m_map_evas_object;
       }
    
       m_map_evas_object = elm_map_add(layout);
       if (m_map_evas_object == NULL) 
       {
          dlog_print(DLOG_ERROR, LOG_TAG, "m_map_evas_object is NULL");
    
          return NULL;
       }
    
       elm_map_zoom_min_set(m_map_evas_object, 2);
       elm_map_user_agent_set(m_map_evas_object, UA_TIZEN_WEB);
       evas_object_show(m_map_evas_object);
    
       Evas_Object *map_obj_layout = elm_layout_add(layout);
    
       app_get_resource(MAP_VIEW_EDJ_FILE, edj_path, (int)PATH_MAX);
       elm_layout_file_set(map_obj_layout, edj_path, "map_object");
       evas_object_size_hint_weight_set(map_obj_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
       evas_object_size_hint_align_set(map_obj_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
       evas_object_show(map_obj_layout);
       elm_layout_content_set(map_obj_layout, "content", m_map_evas_object);
    
       evas_object_smart_callback_add(m_map_evas_object, "scroll", __maps_scroll_cb, (void *)NULL);
       evas_object_smart_callback_add(m_map_evas_object, "longpressed", __maps_longpress_cb, (void *)NULL);
       evas_object_smart_callback_add(m_map_evas_object, "clicked", __maps_clicked_cb, (void *)NULL);
    
       elm_map_zoom_set(m_map_evas_object, 15);
       elm_map_region_bring_in(m_map_evas_object, DEFAULT_LON, DEFAULT_LAT);
    
       return map_obj_layout;
    }
    
  4. Use the __create_map_searchbar() function to create a searchbar to be placed on top of the map view:

    static Evas_Object*
    __create_map_searchbar(Evas_Object *parent)
    {
       Evas_Object *searchbar_obj = elm_genlist_add(parent);
       if (searchbar_obj == NULL)
          dlog_print(DLOG_ERROR, LOG_TAG, "searchbar is NULL");
       evas_object_size_hint_weight_set(searchbar_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
       evas_object_size_hint_align_set(searchbar_obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
       elm_genlist_mode_set(searchbar_obj, ELM_LIST_COMPRESS);
       evas_object_show(searchbar_obj);
       evas_object_smart_callback_add(searchbar_obj, "realized", __searchbar_gl_realized_cb, NULL);
    
       Elm_Genlist_Item_Class *search_itc = elm_genlist_item_class_new();
       search_itc->item_style = "entry.icon";
       search_itc->func.text_get = NULL;
       search_itc->func.content_get = __searchbar_gl_content_cb;
       search_itc->func.del = NULL;
    
       elm_genlist_item_append(searchbar_obj, search_itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
       elm_genlist_item_class_free(search_itc);
       elm_object_focus_custom_chain_append(parent, searchbar_obj, NULL);
    
       return searchbar_obj;
    }
    
  5. Define the place search view:

    1. Create a searchbar and a place category view with the create_search_view() function:
      Evas_Object *
      create_search_view(Evas_Object *parent)
      {
         __poi_result_obtained = false;
      
         char edj_path[PATH_MAX] = {0,};
      
         app_get_resource(SEARCH_VIEW_EDJ_FILE, edj_path, (int)PATH_MAX);
      
         dlog_print(DLOG_DEBUG, LOG_TAG, "edj_path: %s", edj_path);
      
         m_search_view_layout = elm_layout_add(parent);
         elm_layout_file_set(m_search_view_layout, edj_path, "result-view");
         evas_object_size_hint_weight_set(m_search_view_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(m_search_view_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
      
         Evas_Object *searchbar_obj = __create_searchbar(m_search_view_layout);
         if (searchbar_obj == NULL)
            dlog_print(DLOG_ERROR, LOG_TAG, "searchbar_obj is NULL");
         elm_object_part_content_set(m_search_view_layout, "searchbar", searchbar_obj);
      
         Evas_Object *scroller = elm_scroller_add(m_search_view_layout);
         elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
      
         m_search_content_layout = __create_search_category_genlist(scroller);
         elm_object_part_content_set(m_search_view_layout, "list", m_search_content_layout);
      
         Elm_Object_Item *navi_item = elm_naviframe_item_push(parent, "Search", NULL, NULL, 
                                                              m_search_view_layout, NULL);
         elm_naviframe_item_title_enabled_set(navi_item, EINA_FALSE, EINA_FALSE);
      
         elm_naviframe_item_pop_cb_set(navi_item, __search_view_delete_request_cb, (void *)NULL);
      
         m_search_parent_obj = parent;
      
         __poi_result_obtained = false;
      
         return m_search_view_layout;
      }
      
    2. Define the place search searchbar with the __create_searchbar() function:

      static Evas_Object*
      __create_searchbar(Evas_Object *parent)
      {
         Evas_Object *searchbar_obj = elm_layout_add(parent);
         evas_object_size_hint_weight_set(searchbar_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(searchbar_obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
         evas_object_show(searchbar_obj);
         elm_layout_theme_set(searchbar_obj, "layout", "searchbar", "default");
      
         // Entry
         Evas_Object *editfield = create_editfield(searchbar_obj);
         eext_entry_selection_back_event_allow_set(editfield, EINA_TRUE);
         evas_object_size_hint_weight_set(editfield, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(editfield, EVAS_HINT_FILL, EVAS_HINT_FILL);
         Evas_Object *entry = elm_object_part_content_get(editfield, "elm.swallow.content");
         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
         elm_entry_single_line_set(entry, EINA_TRUE);
         elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_PLAINTEXT);
         elm_entry_autocapital_type_set(entry, ELM_AUTOCAPITAL_TYPE_NONE);
         elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
         elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH);
         eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
         elm_object_part_text_set(entry, "elm.guide", "Search");
         elm_entry_prediction_allow_set(entry, EINA_FALSE);
      
         evas_object_show(entry);
      
         elm_object_part_content_set(searchbar_obj, "elm.swallow.content", entry);
      
         return searchbar_obj;
      }
      
    3. Use the __create_search_category_genlist() function to create some predefined search categories for the place search below the searchbar:

      static Evas_Object*
      __create_search_category_genlist(Evas_Object *parent)
      {
         Evas_Object *search_category_genlist = elm_genlist_add(parent);
         elm_list_mode_set(search_category_genlist, ELM_LIST_COMPRESS);
         evas_object_show(search_category_genlist);
      
         // Category
         Elm_Genlist_Item_Class *category_itc = elm_genlist_item_class_new();
         category_itc->item_style = "type1";
         category_itc->func.content_get = NULL; // __search_category_gl_content_get_cb;
         category_itc->func.text_get = __search_category_gl_text_get_cb;
      
         for (int i = 0; i < NUM_OF_CATEGORY; i++) 
         {
            elm_genlist_item_append(search_category_genlist, category_itc, (void *)i, NULL,
                                    ELM_GENLIST_ITEM_NONE, __search_category_gl_select_cb, (void *)i);
         }
      
         elm_genlist_item_class_free(category_itc);
      
         return search_category_genlist;
      }
      
      const char* 
      category_list_text[] = 
      {
         "Food and Drink",
         "Transport",
         "Hotels",
         "Shopping",
         "Leisure"
      };
      
      static char*
      __search_category_gl_text_get_cb(void *data, Evas_Object *obj, const char *part)
      {
         int index = (int)data;
         if (!strcmp(part, "elm.text"))
            return strdup(category_list_text[index]);
      
         return NULL;
      }
      
  6. Define the route search view:

    1. Create 2 searchbars for the starting point and destination with the create_route_view() function:

      void
      create_route_view(Evas_Object *parent)
      {
         __route_result_obtained = false;
         __route_result = NULL;
      
         char edj_path[PATH_MAX] = {0,};
         app_get_resource(ROUTE_VIEW_EDJ_FILE, edj_path, (int)PATH_MAX);
      
         Evas_Object *m_view_layout = elm_layout_add(parent);
         elm_layout_file_set(m_view_layout, edj_path, "route-view");
         evas_object_size_hint_weight_set(m_view_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(m_view_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
         evas_object_show(m_view_layout);
      
         m_route_searchbox_layout = __create_route_searchbox(m_view_layout);
         if (m_route_searchbox_layout != NULL)
            elm_object_part_content_set(m_view_layout, "searchbar-box", m_route_searchbox_layout);
      
         m_route_view_layout = m_view_layout;
      
         Elm_Object_Item *navi_item = elm_naviframe_item_push(parent, "Search", NULL, NULL, 
                                                              m_route_view_layout, NULL);
         elm_naviframe_item_title_enabled_set(navi_item, EINA_FALSE, EINA_FALSE);
      
         m_route_parent_obj = parent;
      
         elm_naviframe_item_pop_cb_set(navi_item, __route_view_delete_request_cb, (void *)NULL);
      
         find_route();
      }
      
    2. Create 2 editfields for the starting point and destination with the __create_route_searchbox() function:

      static Evas_Object*
      __create_route_searchbox(Evas_Object *parent)
      {
         char edj_path[PATH_MAX] = {0,};
         app_get_resource(ROUTE_VIEW_EDJ_FILE, edj_path, (int)PATH_MAX);
      
         Evas_Object *searchbox_layout = elm_layout_add(parent);
         elm_layout_file_set(searchbox_layout, edj_path, "searchbox-layout");
         evas_object_size_hint_weight_set(searchbox_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(searchbox_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
         evas_object_show(searchbox_layout);
      
         // Set icon
         Evas_Object *icon_layout = elm_layout_add(searchbox_layout);
         elm_layout_file_set(icon_layout, edj_path, "searchbox-icon-layout");
         evas_object_size_hint_weight_set(icon_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(icon_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
         evas_object_show(icon_layout);
      
         // Set the searchbox entry
         Evas_Object *entry_layout = elm_layout_add(searchbox_layout);
         elm_layout_file_set(entry_layout, edj_path, "searchbox-entry-layout");
         evas_object_size_hint_weight_set(entry_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(entry_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
         evas_object_show(entry_layout);
         elm_object_part_content_set(searchbox_layout, "searchbox-entry", entry_layout);
      
         // Set starting point
         Evas_Object *searchbar_from_obj = __create_searchbar_from(entry_layout);
         elm_object_part_content_set(entry_layout, "entry-from", searchbar_from_obj);
      
         // Set destination
         Evas_Object *searchbar_to_obj = __create_searchbar_to(entry_layout);
         elm_object_part_content_set(entry_layout, "entry-to", searchbar_to_obj);
      
         elm_object_part_content_set(parent, "searchbar-box", searchbox_layout);
      
         return searchbox_layout;
      }
      
    3. Use the __create_searchbar_from() function to create an editfield for displaying the starting point:

      static Evas_Object*
      __create_searchbar_from(Evas_Object *layout)
      {
         Evas_Object *editfield = create_editfield(layout);
         eext_entry_selection_back_event_allow_set(editfield, EINA_TRUE);
         evas_object_size_hint_weight_set(editfield, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(editfield, EVAS_HINT_FILL, EVAS_HINT_FILL);
         Evas_Object *entry = elm_object_part_content_get(editfield, "elm.swallow.content");
         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
         eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
         elm_object_focus_allow_set(entry, EINA_FALSE);
      
         elm_entry_entry_set(entry, "Map Center Location");
      
         return entry;
      }
      
    4. Use the __create_searchbar_to() function to create an editfield for displaying the destination:

      static Evas_Object*
      __create_searchbar_to(Evas_Object *layout)
      {
         Evas_Object *editfield = create_editfield(layout);
         eext_entry_selection_back_event_allow_set(editfield, EINA_TRUE);
         evas_object_size_hint_weight_set(editfield, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(editfield, EVAS_HINT_FILL, EVAS_HINT_FILL);
         Evas_Object *entry = elm_object_part_content_get(editfield, "elm.swallow.content");
         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
         eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
         elm_object_focus_allow_set(entry, EINA_FALSE);
      
         double tLat = 0.0;
         double tLng = 0.0;
         char *name = NULL;
      
         map_get_selected_poi_lat_lng(&tLat, &tLng, &name);
      
         elm_entry_entry_set(entry, name);
      
         return entry;
      }
      

Application Operation

To use the map service:

  1. Create a maps service handle:

    void
    create_maps_service_handle()
    {
       int error = maps_service_create(MAPS_PROVIDER, &__maps_service_handler);
       bool supported = false;
    
       // Set the provider key to access the services from provider
       maps_service_set_provider_key(__maps_service_handler, PROVIDER_TEST_KEY);
    
       // Check which services are available
       error = maps_service_provider_is_service_supported(__maps_service_handler,
             MAPS_SERVICE_SEARCH_ROUTE, &supported);
       __is_routing_supported = (error == MAPS_ERROR_NONE) ? supported : false;
    
       error = maps_service_provider_is_service_supported(__maps_service_handler,
             MAPS_SERVICE_SEARCH_PLACE, &supported);
       __is_place_search_supported = (error == MAPS_ERROR_NONE) ? supported : false;
    
       error = maps_service_provider_is_service_supported(__maps_service_handler,
             MAPS_SERVICE_REVERSE_GEOCODE, &supported);
       __is_revgeocode_supported = (error == MAPS_ERROR_NONE) ? supported : false;
    }
    
  2. Destroy the maps service handle:

    void
    destroy_maps_service_handle()
    {
       if (__maps_service_handler) 
       {
          int error = maps_service_destroy(__maps_service_handler);
          if (error != MAPS_ERROR_NONE)
             dlog_print(DLOG_ERROR, LOG_TAG, "Failed to destroy maps service [%d]", error);
    
          __maps_service_handler = NULL;
       }
    }
    
  3. Get the reverse geocode:
    1. Perform a longpress gesture on a particular location on the map and request the reverse geocode:

      int
      request_revgeocode(maps_service_h maps, double latitude, double longitude)
      {
         int request_id = -1;
      
         maps_preference_h preference = NULL;
         maps_preference_create(&preference);
      
         int error = maps_service_reverse_geocode(maps, // Maps service handle
                                                  latitude, // Center location
                                                  longitude, // Search radius from center location
                                                  preference, // Reverse geocode preference
                                                  __maps_service_reverse_geocode_cb, // Callback
                                                  (void *)NULL, // User data
                                                  &request_id); // Request ID
      
         if (error != MAPS_ERROR_NONE)
            __request_id = GEO_REQ_ID_IDLE;
         else
            __request_id = request_id;
      
         maps_preference_destroy(preference);
      
         return error;
      }
      
    2. Get the reverse geocode result:

      void
      __maps_service_reverse_geocode_cb(maps_error_e result, int request_id, int index, int total, maps_address_h address, void *user_data)
      {
         __request_id = GEO_REQ_ID_IDLE;
      
         if (result != MAPS_ERROR_NONE) 
         {
            // Invalid result
            dlog_print(DLOG_ERROR, LOG_TAG, "Invalid Reverse Geocode Result");
            handle_addr_notification(NULL);
      
            return;
         }
      
         char resultText[1024] = {0,};
         strcpy(resultText, "");
      
         char *street = NULL;
         maps_address_get_street(address, &street);
         if (street != NULL) 
         {
            strcat(resultText, street);
            free(street);
            street = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "Street is NULL");
         }
      
         char *district = NULL;
         maps_address_get_district(address, &district);
         if (district != NULL) 
         {
            if (strlen(resultText) > 0)
               strcat(resultText, ", ");
            strcat(resultText, district);
            free(district);
            district = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "District is NULL");
         }
      
         char *city = NULL;
         maps_address_get_city(address, &city);
         if (city != NULL) 
         {
            if (strlen(resultText) > 0)
               strcat(resultText, ", ");
            strcat(resultText, city);
            free(city);
            city = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "City is NULL");
         }
      
         char *state = NULL;
         maps_address_get_state(address, &state);
         if (state != NULL) 
         {
            if (strlen(resultText) > 0)
               strcat(resultText, ", ");
            strcat(resultText, state);
            free(state);
            state = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "State is NULL");
         }
      
         char *country = NULL;
         maps_address_get_country(address, &country);
         if (country != NULL) 
         {
            if (strlen(resultText) > 0)
               strcat(resultText, ", ");
            strcat(resultText, country);
            free(country);
            country = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "Country is NULL");
         }
      
         char *country_code = NULL;
         maps_address_get_country_code(address, &country_code);
         if (country_code != NULL) 
         {
            if (strlen(resultText) > 0)
               strcat(resultText, ", ");
            strcat(resultText, country_code);
            free(country_code);
            country_code = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "Country Code is NULL");
         }
      
         char *county = NULL;
         maps_address_get_county(address, &county);
         if (county != NULL) 
         {
            if (strlen(resultText) > 0)
               strcat(resultText, ", ");
            strcat(resultText, county);
            free(county);
            county = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "County is NULL");
         }
      
         char *postal_code = NULL;
         maps_address_get_postal_code(address, &postal_code);
         if (postal_code != NULL) 
         {
            if (strlen(resultText) > 0)
               strcat(resultText, ", ");
            strcat(resultText, postal_code);
            free(postal_code);
            postal_code = NULL;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "Postal Code is NULL");
         }
      
         if (strlen(resultText) > 0) 
         {
            revgeocode_result = (revgeocode_s *)malloc(sizeof(revgeocode_s));
      
            if (!revgeocode_result) 
            {
               handle_addr_notification(NULL);
      
               return;
            }
      
            char *top = strdup(resultText);
            strtok(top, ", ");
            if (top == NULL || !strcmp(top, resultText)) 
            {
               if (top) free(top);
               strcpy(top, "Selected location");
            }
            dlog_print(DLOG_ERROR, LOG_TAG, "addr %s, set name as %s", resultText, top);
            strcpy(revgeocode_result->name, top);
            if (strlen(resultText) > 0)
               strcpy(revgeocode_result->address, &resultText[strlen(top) + 2]);
            else
               strcpy(revgeocode_result->address, (char *)"Not found");
         } 
         else
            revgeocode_result = NULL;
      
         handle_addr_notification(revgeocode_result);
      
         maps_address_destroy(address);
      }
      
  4. Perform a place search:
    1. Perform a place search by clicking the searchbar in the main application view and selecting any of the predefined search categories:

      int
      request_place(maps_service_h maps, double lat, double lon, char *search_keyword, place_type category_type, 
                    int distance, int max_results, place_s **place_res)
      {
         int ret = 0;
         int request_id = 0;
      
         maps_place_filter_h filter = NULL;
         maps_preference_h preference = NULL;
         maps_place_category_h category = NULL;
         maps_coordinates_h coords = NULL;
      
         if (distance < 1)
            distance = POI_SERVICE_CATEGORY_SEARCH_RADIUS;
      
         maps_preference_create(&preference); // Create maps preference
         maps_place_filter_create(&filter); // Create maps place filter
      
         if (category_type != none_category) 
         {
            // Category search
            maps_place_category_create(&category); // Create place_category
      
            maps_place_category_set_name(category, __get_category_name(category_type)); // Set category name for place search
      
            ret = maps_place_filter_set_category(filter, category); // Set place_category to filter
      
            if (ret != MAPS_ERROR_NONE) 
            {
               dlog_print(DLOG_ERROR, LOG_TAG, "maps_place_filter_set error [%d]", ret);
               goto EXIT;
            }
         } 
         else 
         {
            // Keyword search
            dlog_print(DLOG_DEBUG, LOG_TAG, "poi search keyword: %s", search_keyword);
      
            ret = maps_place_filter_set_place_name(filter, search_keyword); // Keyword search. No POI category search
            if (ret != MAPS_ERROR_NONE) 
            {
               dlog_print(DLOG_ERROR, LOG_TAG, "maps_place_filter_set error [%d]", ret);
               goto EXIT;
            }
         }
      
         maps_preference_set_max_results(preference, max_results);	// Set max results preference
      
         maps_coordinates_create(lat, lon, &coords); // Create maps coordinates for radius search
         if (coords == NULL) 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "coords is NULL");
            goto EXIT;
         }
      
         // Place search
         ret = maps_service_search_place(maps, coords, distance, filter, preference,
                                         __maps_service_search_place_cb, (void *) place_res, &request_id);
      
         if (ret != MAPS_ERROR_NONE) 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "failed to poi_service_search.");
            __request_id = POI_REQ_ID_IDLE;
            goto EXIT;
         } 
         else 
         {
            __request_id = request_id;
            dlog_print(DLOG_ERROR, LOG_TAG, "request_id: %d", __request_id);
         }
      
         EXIT:
            if (coords)
               maps_coordinates_destroy(coords);
            if (category)
               maps_place_category_destroy(category);
            if (filter)
               maps_place_filter_destroy(filter);
            maps_preference_destroy(preference);
      
            return ret;
      }
      
    2. Get the place search result:

      static bool
      __maps_service_search_place_cb(maps_error_e error, int request_id, int index, 
                                     int length, maps_place_h place, void *user_data)
      {
         dlog_print(DLOG_DEBUG, LOG_TAG, "Place result >> index [%d]/ length [%d]", index, length);
      
         place_s** place_result = (void *) user_data;
      
         maps_coordinates_h coordinates;
         static double cur_lat, cur_lon;
         double distance = 0.0;
      
         if (error != MAPS_ERROR_NONE) 
         {
            __request_id = POI_REQ_ID_IDLE;
            on_poi_result(length);
      
            return false;
         }
      
         char *name = NULL;
         double latitude = 0.0, longitude = 0.0;
      
         if (index == 0)
            map_get_poi_lat_lng(&cur_lat, &cur_lon);
      
         place_result[index] = (place_s *) malloc(sizeof(place_s));
      
         // Place name
         maps_place_get_name(place, &name);
         strcpy(place_result[index]->__place_name, name);
      
         // Place location
         maps_place_get_location(place, &coordinates);
         maps_coordinates_get_latitude(coordinates, &latitude);
         maps_coordinates_get_longitude(coordinates, &longitude);
         place_result[index]->__lat = latitude;
         place_result[index]->__lon = longitude;
         maps_coordinates_destroy(coordinates);
      
         // Distance calculation
         location_manager_get_distance(cur_lat, cur_lon, latitude, longitude, &distance);
         distance = distance * 0.001;
         place_result[index]->__distance = distance;
      
         if (index == (length-1))
            on_poi_result(length);
      
         __request_id = POI_REQ_ID_IDLE;
      
         // Release the place result
         maps_place_destroy(place);
      
         return true;
      }
      
  5. Perform a route search:
    1. Perform a route search from the map center location to a selected place result by clicking the direction icon in the searchbar in the main application view:

      int
      request_route(maps_service_h maps, double src_lat, double src_lon, 
                    double dest_lat, double dest_lon, route_s **res)
      {
         if (maps == NULL) 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "maps service handle is NULL");
      
            return false;
         }
      
         int request_id;
      
         maps_coordinates_h origin = NULL;
         maps_coordinates_h destination = NULL;
      
         // Origin coordinates
         maps_coordinates_create(src_lat, src_lon, &origin);
         // Destination coordinates
         maps_coordinates_create(dest_lat, dest_lon, &destination);
      
         // Maps preference
         maps_preference_h preference = NULL;
         maps_preference_create(&preference);
      
         // Set route transport mode preference to car
         maps_preference_set_route_transport_mode(preference, MAPS_ROUTE_TRANSPORT_MODE_CAR);
      
         // Route search
         int error = maps_service_search_route(maps, origin, destination, preference,
                                               _maps_service_search_route_cb, (void *) res, &request_id);
      
         if (error == MAPS_ERROR_NONE) 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "request_id: %d", request_id);
            __route_request_id = request_id;
         } 
         else 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "Route Service Request Failed: [%d]", error);
            __route_request_id = ROUTE_REQ_ID_IDLE;
         }
      
         maps_coordinates_destroy(origin);
         maps_coordinates_destroy(destination);
      
         maps_preference_destroy(preference);
      
         return error;
      }
      
    2. Get the route search result:

      bool
      __maps_route_segment_maneuver_cb(int index, int total, 
                                       maps_route_maneuver_h maneuver, void *user_data)
      {
         route_s **route_result = (route_s **) user_data;
      
         double _distance = 0.0;
         maps_route_maneuver_get_distance_to_next_instruction(maneuver, &_distance);
      
         // Route segment maneuver instruction text
         char *instruction = NULL;
         maps_route_maneuver_get_instruction_text(maneuver, &instruction);
      
         if (instruction) 
         {
            strcpy(((*route_result)->__maneuver[__maneuver_count]).__instruction, instruction);
            free(instruction);
            instruction = NULL;
         } 
         else
            strcpy(((*route_result)->__maneuver[__maneuver_count]).__instruction, "");
      
         // Route segment maneuver road name
         char *road_name = NULL;
         maps_route_maneuver_get_road_name(maneuver, &road_name);
      
         if (road_name) 
         {
            strcpy(((*route_result)->__maneuver[__maneuver_count]).__street_name, road_name);
            free(road_name);
            road_name = NULL;
         } 
         else
            strcpy(((*route_result)->__maneuver[__maneuver_count]).__street_name, "");
      
         ((*route_result)->__maneuver[__maneuver_count]).__origin_lat = segment_origin.latitude;
         ((*route_result)->__maneuver[__maneuver_count]).__origin_lon = segment_origin.longitude;
         ((*route_result)->__maneuver[__maneuver_count]).__dest_lat = segment_destination.latitude;
         ((*route_result)->__maneuver[__maneuver_count]).__dest_lon = segment_destination.longitude;
      
         // Route segment maneuver turn type
         maps_route_turn_type_e turn_type = MAPS_ROUTE_TURN_TYPE_NONE;
         maps_route_maneuver_get_turn_type(maneuver, &turn_type);
      
         strcpy(((*route_result)->__maneuver[__maneuver_count]).__turn_string, 
                turn_id_string[turn_type]);
      
         __maneuver_count++;
      
         maps_route_maneuver_destroy(maneuver);
      
         return true;
      }
      
      bool
      __maps_route_segment_cb(int index, int total, maps_route_segment_h segment, void *user_data)
      {
         if (!segment) 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "critical error: FAILED");
      
            return false;
         }
      
         maps_coordinates_h origin = NULL, destination = NULL;
      
         // Segment origin coordinates
         maps_route_segment_get_origin(segment, &origin);
         maps_coordinates_get_latitude(origin, &(segment_origin.latitude));
         maps_coordinates_get_longitude(origin, &(segment_origin.longitude));
         maps_coordinates_destroy(origin);
      
         dlog_print(DLOG_DEBUG, LOG_TAG, "Segment Origin Lat: %f, Lon: %f", 
                    segment_origin.latitude, segment_origin.longitude);
      
         // Segment destination coordinates
         maps_route_segment_get_destination(segment, &destination);
         maps_coordinates_get_latitude(destination, &(segment_destination.latitude));
         maps_coordinates_get_longitude(destination, &(segment_destination.longitude));
         maps_coordinates_destroy(destination);
      
         dlog_print(DLOG_DEBUG, LOG_TAG, "Segment Destination Lat: %f, Lon: %f", 
                    segment_destination.latitude, segment_destination.longitude);
      
         // Segment maneuvers information
         maps_route_segment_foreach_maneuver(segment, __maps_route_segment_maneuver_cb, user_data);
      
         maps_route_segment_destroy(segment);
      
         return true;
      }
      
      bool
      __parse_route_data(maps_route_h route, int index, int total, void *user_data)
      {
         route_s **route_result = (route_s **) user_data;
      
         maps_distance_unit_e dist_unit;
         double distance = 0;
         long duration = 0;
         int ret = 0;
      
         // Clone the route
         if (ret != MAPS_ERROR_NONE || !route) 
         {
            dlog_print(DLOG_ERROR, LOG_TAG, "Route Response error [%d]", ret);
      
            return false;
         }
      
         // Get the total distance
         maps_route_get_total_distance(route, &distance);
         // Get the distance unit
         maps_route_get_distance_unit(route, &dist_unit);
      
         // Change everything to KM (by default)
         if (dist_unit == MAPS_DISTANCE_UNIT_M) 
         {
            dlog_print(DLOG_DEBUG, LOG_TAG, "distance: %.5f m", distance);
            distance = distance / 1000; // Convert the distance into KM
         } 
         else if (dist_unit == MAPS_DISTANCE_UNIT_KM) 
         {
            dlog_print(DLOG_DEBUG, LOG_TAG, "distance: %.5f km", distance);
         }
      
         // Get the total duration
         maps_route_get_total_duration(route, &duration);
         dlog_print(DLOG_DEBUG, LOG_TAG, "duration: %ld sec", duration);
         duration = (duration + 30) / 60; // Convert the duration to minutes
      
         (*route_result) = (route_s *)malloc(sizeof(route_s));
      
         (*route_result)->__distance = distance;
         (*route_result)->__duration = duration;
      
         __maneuver_count = 0;
      
         // Check whether maneuver path data is supported
         bool supported = false;
         int error = maps_service_provider_is_data_supported(get_maps_service_handle(), 
                                                             MAPS_ROUTE_SEGMENTS_PATH, &supported);
         const bool is_route_segment_path_supported = (error == MAPS_ERROR_NONE) ? supported : false;
      
         // Check whether maneuver segment data is supported 
         error = maps_service_provider_is_data_supported(get_maps_service_handle(), 
                                                         MAPS_ROUTE_SEGMENTS_MANEUVERS, &supported);
         const bool is_route_segment_maneuvers_supported = (error == MAPS_ERROR_NONE) ? supported : false;
      
         if ((is_route_segment_path_supported) && (is_route_segment_maneuvers_supported)) 
         {
            // Allow segment maneuvers and path usage
            maps_route_foreach_segment(route, __maps_route_segment_cb, (void *)route_result);
         }
      
         (*route_result)->__maneuver_count = __maneuver_count;
      
         return true;
      }
      
      bool
      __maps_service_search_route_cb(maps_error_e error, int request_id, int index, 
                                     int total, maps_route_h route, void *user_data)
      {
         route_s **route_result = (route_s **) user_data;
      
         __parse_route_data(route, index, total, (void *) user_data);
      
         dlog_print(DLOG_DEBUG, LOG_TAG, "distance: %f", (*route_result)->__distance);
      
         on_route_result();
      
         maps_route_destroy(route);
      
         return true;
      }