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);
Evas_Object * elm_map_add(Evas_Object *parent)
Widget is broken due to on-line service API breaks.
Definition: elm_map.c:250
box = elm_box_add(win);
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);
#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:297
#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:298
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539
void elm_box_horizontal_set(Elm_Box *obj, Eina_Bool horizontal)
Set the horizontal orientation.
Definition: elm_box_eo.legacy.c:27
Evas_Object * elm_box_add(Evas_Object *parent)
Add a new box to the parent.
Definition: elm_box.c:363
void elm_box_pack_end(Elm_Box *obj, Efl_Canvas_Object *subobj)
Add an object at the end of the pack list.
Definition: elm_box_eo.legacy.c:57
Evas_Object * elm_button_add(Evas_Object *parent)
Add a new button to the parent's canvas.
Definition: efl_ui_button.c:459
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:8997
EVAS_API void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1814
EVAS_API 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_API 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
EVAS_API 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

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;
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition: Evas_Common.h:185
Definition: elm_widget_map.h:324
Definition: elm_widget_map.h:253
Definition: elm_widget_map.h:278

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);
void elm_map_region_show(Elm_Map *obj, double lon, double lat)
Widget is broken due to on-line service API breaks.
Definition: elm_map_eo.legacy.c:135

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);
}
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition: eina_types.h:339
Elm_Map_Route * elm_map_route_add(Elm_Map *obj, Elm_Map_Route_Type type, Elm_Map_Route_Method method, double flon, double flat, double tlon, double tlat, Elm_Map_Route_Cb route_cb, void *data)
Widget is broken due to on-line service API breaks.
Definition: elm_map_eo.legacy.c:81
void elm_map_name_region_get(const Elm_Map_Name *name, double *lon, double *lat)
Widget is broken due to on-line service API breaks.
Definition: elm_map.c:423
void elm_map_route_del(Elm_Map_Route *route)
Widget is broken due to on-line service API breaks.
Definition: elm_map.c:391
@ ELM_MAP_ROUTE_TYPE_FOOT
Route should consider user will be walking.
Definition: elm_map_eo.h:44
@ ELM_MAP_ROUTE_METHOD_SHORTEST
Route should prioritize distance.
Definition: elm_map_eo.h:59

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);
}
void elm_map_overlay_color_set(Elm_Map_Overlay *overlay, int r, int g, int b, int a)
Widget is broken due to on-line service API breaks.
Definition: elm_map.c:523
Elm_Map_Overlay * elm_map_overlay_route_add(Elm_Map *obj, const Elm_Map_Route *route)
Widget is broken due to on-line service API breaks.
Definition: elm_map_eo.legacy.c:171

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: