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 wan't a vertical control box this time.

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

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 preliminar address, that I know will find a coordinate, to examplify 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)
{
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)
{
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:

map_example_03.png