2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "here_route.h"
19 HERE_PLUGIN_BEGIN_NAMESPACE
21 HereRoute::HereRoute(void *pCbFunc, void *pUserData, int nReqId)
26 m_pUserData = pUserData;
29 m_eDistanceUnit = MAPS_DISTANCE_UNIT_M;
32 HereRoute::~HereRoute()
40 here_error_e HereRoute::PrepareQuery()
43 return HERE_ERROR_PERMISSION_DENIED;
45 GeoCoordinates origCoord, destCoord;
46 m_pQuery = new (std::nothrow) GeoRouteQuery(origCoord, destCoord);
49 return HERE_ERROR_OUT_OF_MEMORY;
51 return HERE_ERROR_NONE;
54 here_error_e HereRoute::PrepareWaypoint(maps_coordinates_h hOrigin, maps_coordinates_h hDestination)
57 return HERE_ERROR_OUT_OF_MEMORY;
59 if (!hOrigin || !hDestination)
60 return HERE_ERROR_INVALID_PARAMETER;
63 const int nWaypointNum = 2;
64 maps_coordinates_h hWaypointList[nWaypointNum];
65 hWaypointList[0] = hOrigin;
66 hWaypointList[1] = hDestination;
68 return PrepareWaypoint(hWaypointList, nWaypointNum);
71 here_error_e HereRoute::PrepareWaypoint(const maps_coordinates_h* hWaypointList, int nWaypointNum)
74 return HERE_ERROR_OUT_OF_MEMORY;
76 if (!hWaypointList || nWaypointNum <= 0)
77 return HERE_ERROR_INVALID_PARAMETER;
79 GeoCoordinateList hereCoordList;
80 GeoCoordinates hereCoord;
81 double dLatitude, dLongitude;
83 for (int index = 0; index < nWaypointNum; index++) {
84 if (hWaypointList[index] != NULL) {
85 maps_coordinates_get_latitude(hWaypointList[index], &dLatitude);
86 maps_coordinates_get_longitude(hWaypointList[index], &dLongitude);
88 //MAPS_LOGD("Waypoint --> Lat : %f, Long : %f", dLatitude, dLongitude);
90 hereCoord = GeoCoordinates(dLatitude, dLongitude);
92 if (!HereUtils::IsValid(hereCoord))
93 return HERE_ERROR_INVALID_PARAMETER;
95 hereCoordList.push_back(hereCoord);
99 m_pQuery->SetWaypoints(hereCoordList);
101 return HERE_ERROR_NONE;
104 here_error_e HereRoute::PreparePreference(maps_preference_h hPref)
107 return HERE_ERROR_OUT_OF_MEMORY;
110 return HERE_ERROR_NONE;
113 SegmentDetail aSegmentDetail;
114 ManeuverDetail aMneuverDetail;
115 m_pQuery->SetSegmentDetail(aSegmentDetail);
116 m_pQuery->SetManeuverDetail(aMneuverDetail);
120 maps_route_transport_mode_e eTransMode;
121 if (maps_preference_get_route_transport_mode(hPref, &eTransMode) == MAPS_ERROR_NONE) {
122 m_pQuery->SetTravelModes(HereUtils::Convert(eTransMode));
126 maps_route_feature_e eFeature;
127 maps_route_feature_weight_e eFeatureWeight;
128 if (maps_preference_get_route_feature(hPref, &eFeature) == MAPS_ERROR_NONE &&
129 maps_preference_get_route_feature_weight(hPref, &eFeatureWeight) == MAPS_ERROR_NONE) {
130 m_pQuery->SetFeatureWeight(HereUtils::Convert(eFeature),
131 HereUtils::Convert(eFeatureWeight));
136 if (maps_preference_get(hPref, MAPS_ROUTE_RECT_AREA_TO_AVOID, &szAreaToAvoid) == MAPS_ERROR_NONE) {
137 GeoBoundingBox gbBox;
138 GeoBoundingBoxList gbBoxList;
139 gbBoxList.push_back(HereUtils::Convert(szAreaToAvoid, gbBox));
140 m_pQuery->SetExcludeAreas(gbBoxList);
141 g_free(szAreaToAvoid);
145 GeoRouteQuery::RouteOptimization hereOpt;
146 maps_route_optimization_e mapsOpt;
147 if (maps_preference_get_route_optimization(hPref, &mapsOpt) == MAPS_ERROR_NONE) {
149 case MAPS_ROUTE_TYPE_FASTEST: hereOpt = GeoRouteQuery::RO_FastestRoute; break;
150 case MAPS_ROUTE_TYPE_SHORTEST: hereOpt = GeoRouteQuery::RO_ShortestRoute; break;
151 default: hereOpt = GeoRouteQuery::RO_FastestRoute; break;
153 m_pQuery->SetRouteOptimization(hereOpt);
157 GeoRouteQuery::MetricSystem eMetric;
158 maps_distance_unit_e eUnit;
159 if (maps_preference_get_distance_unit(hPref, &eUnit) == MAPS_ERROR_NONE) {
161 case MAPS_DISTANCE_UNIT_M: eMetric = GeoRouteQuery::DIST_metric; break;
162 case MAPS_DISTANCE_UNIT_KM: eMetric = GeoRouteQuery::DIST_metric; break;
163 default: eMetric = GeoRouteQuery::DIST_imperial; break;
165 m_eDistanceUnit = eUnit;
166 m_pQuery->SetMetricSystem(eMetric);
170 if (maps_preference_get(hPref, MAPS_ROUTE_GEOMETRY_BOUNDING_BOX, &szViewBounds) == MAPS_ERROR_NONE) {
171 GeoBoundingBox gbBox;
172 HereUtils::Convert(szViewBounds, gbBox);
173 m_pQuery->SetViewBounds(gbBox);
174 g_free(szViewBounds);
177 bool is_alternatives_enabled = false;
178 if (maps_preference_get_route_alternatives_enabled(hPref, &is_alternatives_enabled) == MAPS_ERROR_NONE) {
179 if (is_alternatives_enabled)
180 m_pQuery->SetAlternatives(2);
183 char *szRealtimeTraffic;
184 if (maps_preference_get(hPref, MAPS_ROUTE_REALTIME_TRAFFIC, &szRealtimeTraffic) == MAPS_ERROR_NONE)
186 if (!strcmp(szRealtimeTraffic, "true") || !strcmp(szRealtimeTraffic, "enabled")) {
187 m_pQuery->SetRealtimeTraffic(1);
188 } else if (!strcmp(szRealtimeTraffic, "false") || !strcmp(szRealtimeTraffic, "disabled")) {
189 m_pQuery->SetRealtimeTraffic(2);
191 m_pQuery->SetRealtimeTraffic(0);
193 g_free(szRealtimeTraffic);
196 return HERE_ERROR_NONE;
199 here_error_e HereRoute::StartRoute(void)
202 return HERE_ERROR_OUT_OF_MEMORY;
204 m_nRestReqId = m_pQuery->Execute(*this, NULL);
206 return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
209 void HereRoute::OnRouteReply(const GeoRouteReply& Reply)
211 if (m_bCanceled || !m_pCbFunc || !m_pQuery) { // ignore call back if it was cancelled.
216 maps_route_h mapsRoute;
218 GeoRouteList hereRouteList = Reply.GetRoutes();
219 int nReplyIdx = 0, nReplyNum = hereRouteList.size();
220 GeoRouteList::iterator hereRoute;
222 if (nReplyNum == 0) {
223 ((maps_service_search_route_cb)m_pCbFunc)(MAPS_ERROR_NOT_FOUND, m_nReqId,
224 0, 0, NULL, m_pUserData);
229 for (hereRoute = hereRouteList.begin() ; hereRoute != hereRouteList.end() ; hereRoute++) {
230 error = (maps_error_e)maps_route_create(&mapsRoute);
232 if (error == MAPS_ERROR_NONE) {
234 if (!hereRoute->GetRouteId().empty())
235 maps_route_set_route_id(mapsRoute, (char*)hereRoute->GetRouteId().c_str());
238 maps_route_set_total_distance(mapsRoute,
239 HereUtils::ConvertDistance(hereRoute->GetDistance(), m_eDistanceUnit));
242 maps_route_set_distance_unit(mapsRoute, m_eDistanceUnit);
245 if (m_pQuery->GetRealtimeTraffic() == 1)
246 maps_route_set_total_duration(mapsRoute, hereRoute->GetTrafficTime());
248 maps_route_set_total_duration(mapsRoute, hereRoute->GetTravelTime());
252 maps_route_transport_mode_e eTransportMode;
253 eTransportMode = HereUtils::Convert(hereRoute->GetTravelMode());
254 maps_route_set_transport_mode(mapsRoute, eTransportMode);
257 GeoCoordinateList herePathList = hereRoute->GetPath();
258 maps_item_list_h mapsPathList;
259 maps_coordinates_h mapsPath;
261 if (maps_item_list_create(&mapsPathList) == MAPS_ERROR_NONE) {
262 GeoCoordinateList::iterator herePath;
263 for (herePath = herePathList.begin(); herePath != herePathList.end(); herePath++) {
264 double dLat = herePath->GetLatitude();
265 double dLng = herePath->GetLongitude();
267 if(maps_coordinates_create(dLat, dLng, &mapsPath) == MAPS_ERROR_NONE) {
268 if (herePath == herePathList.begin())
269 maps_route_set_origin(mapsRoute, mapsPath);
270 else if (herePath == herePathList.end()-1)
271 maps_route_set_destination(mapsRoute, mapsPath);
273 maps_item_list_append(mapsPathList, mapsPath, maps_coordinates_clone);
275 maps_coordinates_destroy(mapsPath);
279 if (maps_item_list_items(mapsPathList)) {
280 maps_route_set_path(mapsRoute, mapsPathList);
281 maps_item_list_remove_all(mapsPathList, maps_coordinates_destroy);
283 maps_item_list_destroy(mapsPathList);
287 maps_area_h hMapsArea = NULL;
288 HereUtils::Convert(hereRoute->GetBounds(), hMapsArea);
290 maps_route_set_bounding_box(mapsRoute, hMapsArea);
291 maps_area_destroy(hMapsArea);
295 ProcessSegments(mapsRoute, hereRoute->GetRouteSegmentList());
299 maps_route_destroy(mapsRoute);
302 if (((maps_service_search_route_cb)m_pCbFunc)(error, m_nReqId,
303 nReplyIdx++, nReplyNum, mapsRoute, m_pUserData) == FALSE) {
307 //maps_route_destroy(mapsRoute);
311 if(nReplyIdx >= nReplyNum)
315 void HereRoute::OnRouteFailure(const GeoRouteReply& Reply)
317 if (!m_bCanceled && m_pCbFunc)
318 ((maps_service_search_route_cb)m_pCbFunc)((maps_error_e)GetErrorCode(Reply), m_nReqId, 0, 0, NULL, m_pUserData);
322 maps_error_e HereRoute::ProcessSegments(maps_route_h mapsRoute, const RouteSegmentList& hereSegmList)
324 maps_item_list_h mapsSegmList;
325 maps_route_segment_h mapsSegm;
328 if (hereSegmList.empty()) return MAPS_ERROR_NOT_FOUND;
330 if ((error = (maps_error_e)maps_item_list_create(&mapsSegmList)) != MAPS_ERROR_NONE)
333 RouteSegmentList::const_iterator hereSegm;
334 for (hereSegm = hereSegmList.begin() ; hereSegm != hereSegmList.end() ; hereSegm++)
336 if (maps_route_segment_create(&mapsSegm) != MAPS_ERROR_NONE) continue;
339 maps_route_segment_set_distance(mapsSegm,
340 HereUtils::ConvertDistance(hereSegm->GetDistance(), m_eDistanceUnit));
343 maps_route_segment_set_duration(mapsSegm, hereSegm->GetTravelTime());
345 /* origin, destination */
346 GeoCoordinateList herePathList = hereSegm->GetPath();
347 int here_path_list_size = herePathList.size();
349 if (here_path_list_size > 0) {
350 GeoCoordinates hereOrig = herePathList.at(0);
351 GeoCoordinates hereDest = herePathList.at(here_path_list_size-1);
353 maps_coordinates_h mapsOrig, mapsDest;
354 maps_coordinates_create(hereOrig.GetLatitude(),
355 hereOrig.GetLongitude(), &mapsOrig);
356 maps_coordinates_create(hereDest.GetLatitude(),
357 hereDest.GetLongitude(), &mapsDest);
358 maps_route_segment_set_origin(mapsSegm, mapsOrig);
359 maps_route_segment_set_destination(mapsSegm, mapsDest);
360 maps_coordinates_destroy(mapsOrig);
361 maps_coordinates_destroy(mapsDest);
365 ProcessManeuver(mapsSegm, hereSegm->GetManeuverList());
367 maps_item_list_append(mapsSegmList, mapsSegm, maps_route_segment_clone);
368 maps_route_segment_destroy(mapsSegm);
371 if (maps_item_list_items(mapsSegmList)) {
372 maps_route_set_segments(mapsRoute, mapsSegmList);
373 maps_item_list_remove_all(mapsSegmList, maps_route_segment_destroy);
375 maps_item_list_destroy(mapsSegmList);
377 return MAPS_ERROR_NONE;
380 maps_error_e HereRoute::ProcessManeuver(maps_route_segment_h mapsSegm, const ManeuverList& hereManeList)
382 maps_item_list_h mapsManeList;
383 maps_route_maneuver_h mapsManeuver;
384 maps_coordinates_h mapsCoord;
387 if (hereManeList.empty()) return MAPS_ERROR_NOT_FOUND;
389 if ((error = (maps_error_e)maps_item_list_create(&mapsManeList)) != MAPS_ERROR_NONE)
392 ManeuverList::const_iterator hereMane;
393 for (hereMane = hereManeList.begin() ; hereMane != hereManeList.end() ; hereMane++) {
394 if (maps_route_maneuver_create(&mapsManeuver) != MAPS_ERROR_NONE) continue;
397 if (maps_coordinates_create(hereMane->GetPosition().GetLatitude(),
398 hereMane->GetPosition().GetLongitude(), &mapsCoord) == MAPS_ERROR_NONE) {
399 maps_route_maneuver_set_position(mapsManeuver, mapsCoord);
400 maps_coordinates_destroy(mapsCoord);
404 if (!hereMane->GetInstructionText().empty())
405 maps_route_maneuver_set_instruction_text(mapsManeuver,
406 (char*)hereMane->GetInstructionText().c_str());
409 maps_route_maneuver_set_distance_to_next_instruction(mapsManeuver,
410 HereUtils::ConvertDistance(hereMane->GetDistanceToNextInstruction(), m_eDistanceUnit));
413 maps_route_maneuver_set_time_to_next_instruction(mapsManeuver,
414 hereMane->GetTimeToNextInstruction());
416 /* direction -> turn type */
417 maps_route_maneuver_set_turn_type(mapsManeuver,
418 HereUtils::Convert(hereMane->GetDirection()));
420 maps_item_list_append(mapsManeList, mapsManeuver, maps_route_maneuver_clone);
421 maps_route_maneuver_destroy(mapsManeuver);
424 if (maps_item_list_items(mapsManeList)) {
425 maps_route_segment_set_maneuvers(mapsSegm, mapsManeList);
426 maps_item_list_remove_all(mapsManeList, maps_route_maneuver_destroy);
428 maps_item_list_destroy(mapsManeList);
430 return MAPS_ERROR_NONE;
433 HERE_PLUGIN_END_NAMESPACE