Map Example - Route and Name Usage

This code places an Elementary map widget on a window, to exemplify part of the widget's API, related routes and names.

In this example, we will suppose we need to set a route for the user from his current point (a gps could provide us this information) to somewhere else. So we would have coordinates of this start point, and would like that he enters the address of his destination in a entry, and we'll trace a route on the map.

We'll start this example in the same way Map Example 1. Adding a map with buttons to control zoom, so if you didn't read it yet, just do it now. Actually there is a change, that we're aligning buttons to the top, since we want a vertical control box this time.

map = elm_map_add(win);
box = elm_box_add(win);
elm_box_horizontal_set(box, EINA_TRUE);
bt = elm_button_add(win);
elm_object_text_set(bt, "+");
elm_box_pack_end(box, bt);
evas_object_smart_callback_add(bt, "clicked", _bt_zoom_in, map);
bt = elm_button_add(win);
elm_object_text_set(bt, "-");
elm_box_pack_end(box, bt);
evas_object_smart_callback_add(bt, "clicked", _bt_zoom_out, map);
bt = elm_button_add(win);
elm_object_text_set(bt, "X");
elm_box_pack_end(box, bt);
evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fit, map);
bt = elm_button_add(win);
elm_object_text_set(bt, "#");
elm_box_pack_end(box, bt);
evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fill, map);

Next we set the box to be vertical and change it's size, weight and alignment, so it will occupy the top of the window, from left to right:

We'll add an entry with a preliminary address, that I know will find a coordinate, to exemplify how names work. But you can try lots of addresses. From city or country names to pubs, or whatever you want. To try is enough to run the example, type the address and press "Route" button. This button will call a function that will get the typed address and find the route.

The button pass an structure instance we make for this example, with all the fields we'll need.

typedef struct _Example_Data
{
Evas_Object *map, *entry;
Elm_Map_Route *route;
double start_lon, start_lat, dest_lon, dest_lat;
Elm_Map_Name *name;
Elm_Map_Overlay *route_ovl;
} Example_Data;
static Example_Data example_data;

Let's initialize it's fields:

example_data.map = map;
example_data.entry = entry;
example_data.route = NULL;
example_data.start_lon = -43.175;
example_data.start_lat = -22.97;

map and entry are our elementary objects, route is set to NULL, since we don't have one yet, and the coordinates of the start point is set (longitude and latitude).

Also, let's show this start point at the center of the map, and set a zoom nice enough to close it:

elm_map_region_show(map, example_data.start_lon, example_data.start_lat);

These lines were already explained on Map Example 2.

Now we'll see the "Route" button callback function:

static void
_name_loaded(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
{
Example_Data *exam_data = data;
Evas_Object *map = obj;
if (exam_data->route)
elm_map_route_del(exam_data->route);
elm_map_name_region_get(exam_data->name, &(exam_data->dest_lon),
&(exam_data->dest_lat));
exam_data->route = elm_map_route_add(map, ELM_MAP_ROUTE_TYPE_FOOT,
exam_data->start_lon, exam_data->start_lat,
exam_data->dest_lon, exam_data->dest_lat,
NULL, NULL);
}

First we get the address string from our entry. Then we use name conversion util functions, so we could get coordinates for this address. These functions return an Elm_Map_Name handle for us. Function elm_map_name_geo_request() will do this job for us, but it's an asynchronous function, since it requires this information from the server.

That's the reason we need to wait for "name,loaded" signal. We add a callback function for this:

static void
_route_loaded(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
{
Example_Data *exam_data = data;
exam_data->route_ovl = elm_map_overlay_route_add(obj, exam_data->route);
elm_map_overlay_color_set(exam_data->route_ovl, 0, 255, 0, 255);
}

This function will check if a previous route was traced, and if it was, it will remove it. Next we'll get destination coordinates from our name, and use them to add a new route.

To trace a route we need to know how the user will go through the path. Let's suppose he'll be walking, but doesn't like to walk, so we need to choose the shortest path instead of the route that would made him spend less time. Coordinates of the point from where he will start and of the destination point need to be passed as well.

Finally we'll set a color different from solid red (default), to show our route. We set it green.

See map_example_03.c for full source, whose window should look like this picture:

_Elm_Map_Name
Definition: elm_widget_map.h:324
elm_map_name_region_get
void elm_map_name_region_get(const Elm_Map_Name *name, double *lon, double *lat)
Get the current coordinates of the name.
Definition: elm_map.c:4815
elm_box_add
EAPI Evas_Object * elm_box_add(Evas_Object *parent)
Add a new box to the parent.
Definition: elm_box.c:363
_Elm_Map_Route
Definition: elm_widget_map.h:278
EINA_UNUSED
#define EINA_UNUSED
Definition: eina_types.h:339
elm_map_route_del
void elm_map_route_del(Elm_Map_Route *route)
Remove a route from the map.
Definition: elm_map.c:4712
_Elm_Map_Overlay
Definition: elm_widget_map.h:253
elm_button_add
EAPI Evas_Object * elm_button_add(Evas_Object *parent)
Add a new button to the parent's canvas.
Definition: efl_ui_button.c:477
EVAS_HINT_EXPAND
#define EVAS_HINT_EXPAND
Use with evas_object_size_hint_weight_set(), evas_object_size_hint_weight_get(), evas_object_size_hin...
Definition: Evas_Common.h:292
evas_object_smart_callback_add
void evas_object_smart_callback_add(Evas_Object *eo_obj, const char *event, Evas_Smart_Cb func, const void *data)
Add (register) a callback function to the smart event specified by event on the smart object obj.
Definition: evas_object_smart.c:1040
Evas_Object
Efl_Canvas_Object Evas_Object
Definition: Evas_Common.h:180
evas_object_size_hint_weight_set
void evas_object_size_hint_weight_set(Evas_Object *obj, double x, double y)
Sets the hints for an object's weight.
Definition: evas_object_main.c:2638
evas_object_size_hint_align_set
void evas_object_size_hint_align_set(Evas_Object *obj, double x, double y)
Sets the hints for an object's alignment.
Definition: evas_object_main.c:2650
elm_map_overlay_color_set
void elm_map_overlay_color_set(Elm_Map_Overlay *overlay, int r, int g, int b, int a)
Set the object color of the overlay.
Definition: elm_map.c:5220
elm_map_add
Evas_Object * elm_map_add(Evas_Object *parent)
Add a new map widget to the given parent Elementary (container) object.
Definition: elm_map.c:4299
ELM_MAP_ROUTE_TYPE_FOOT
@ ELM_MAP_ROUTE_TYPE_FOOT
Route should consider user will be walking.
Definition: elm_map_eo.h:44
evas_object_show
void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1814
EVAS_HINT_FILL
#define EVAS_HINT_FILL
Use with evas_object_size_hint_align_set(), evas_object_size_hint_align_get(), evas_object_size_hint_...
Definition: Evas_Common.h:293
EINA_TRUE
#define EINA_TRUE
Definition: eina_types.h:539
elm_win_resize_object_add
void elm_win_resize_object_add(Eo *obj, Evas_Object *subobj)
Add subobj as a resize object of window obj.
Definition: efl_ui_win.c:8992
ELM_MAP_ROUTE_METHOD_SHORTEST
@ ELM_MAP_ROUTE_METHOD_SHORTEST
Route should prioritize distance.
Definition: elm_map_eo.h:59