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()
41 here_error_e HereRoute::PrepareQuery()
44 return HERE_ERROR_PERMISSION_DENIED;
46 GeoCoordinates origCoord, destCoord;
47 m_pQuery = new (std::nothrow) GeoRouteQuery(origCoord, destCoord);
50 return HERE_ERROR_OUT_OF_MEMORY;
52 return HERE_ERROR_NONE;
55 here_error_e HereRoute::PrepareWaypoint(maps_coordinates_h hOrigin, maps_coordinates_h hDestination)
58 return HERE_ERROR_OUT_OF_MEMORY;
60 if (!hOrigin || !hDestination)
61 return HERE_ERROR_INVALID_PARAMETER;
64 const int nWaypointNum = 2;
65 maps_coordinates_h hWaypointList[nWaypointNum];
66 hWaypointList[0] = hOrigin;
67 hWaypointList[1] = hDestination;
69 return PrepareWaypoint(hWaypointList, nWaypointNum);
72 here_error_e HereRoute::PrepareWaypoint(const maps_coordinates_h* hWaypointList, int nWaypointNum)
75 return HERE_ERROR_OUT_OF_MEMORY;
77 if (!hWaypointList || nWaypointNum <= 0)
78 return HERE_ERROR_INVALID_PARAMETER;
80 GeoCoordinateList hereCoordList;
81 GeoCoordinates hereCoord;
82 double dLatitude, dLongitude;
84 for (int index = 0; index < nWaypointNum; index++)
86 if (hWaypointList[index] != NULL) {
87 maps_coordinates_get_latitude(hWaypointList[index], &dLatitude);
88 maps_coordinates_get_longitude(hWaypointList[index], &dLongitude);
90 //MAPS_LOGD("Waypoint --> Lat : %f, Long : %f", dLatitude, dLongitude);
92 hereCoord = GeoCoordinates(dLatitude, dLongitude);
94 if (!HereUtils::IsValid(hereCoord))
95 return HERE_ERROR_INVALID_PARAMETER;
97 hereCoordList.push_back(hereCoord);
101 m_pQuery->SetWaypoints(hereCoordList);
103 return HERE_ERROR_NONE;
106 here_error_e HereRoute::PreparePreference(maps_preference_h hPref)
109 return HERE_ERROR_OUT_OF_MEMORY;
112 return HERE_ERROR_NONE;
115 SegmentDetail aSegmentDetail;
116 ManeuverDetail aMneuverDetail;
117 m_pQuery->SetSegmentDetail(aSegmentDetail);
118 m_pQuery->SetManeuverDetail(aMneuverDetail);
122 maps_route_transport_mode_e eTransMode;
123 if (maps_preference_get_route_transport_mode(hPref, &eTransMode) == MAPS_ERROR_NONE)
125 m_pQuery->SetTravelModes(HereUtils::Convert(eTransMode));
129 maps_route_feature_e eFeature;
130 maps_route_feature_weight_e eFeatureWeight;
131 if (maps_preference_get_route_feature(hPref, &eFeature) == MAPS_ERROR_NONE &&
132 maps_preference_get_route_feature_weight(hPref, &eFeatureWeight) == MAPS_ERROR_NONE)
134 m_pQuery->SetFeatureWeight(HereUtils::Convert(eFeature),
135 HereUtils::Convert(eFeatureWeight));
140 if (maps_preference_get(hPref, MAPS_ROUTE_RECT_AREA_TO_AVOID, &szAreaToAvoid) == MAPS_ERROR_NONE)
142 GeoBoundingBox gbBox;
143 GeoBoundingBoxList gbBoxList;
144 gbBoxList.push_back(HereUtils::Convert(szAreaToAvoid, gbBox));
145 m_pQuery->SetExcludeAreas(gbBoxList);
146 g_free(szAreaToAvoid);
150 GeoRouteQuery::RouteOptimization hereOpt;
151 maps_route_optimization_e mapsOpt;
152 if (maps_preference_get_route_optimization(hPref, &mapsOpt) == MAPS_ERROR_NONE)
156 case MAPS_ROUTE_TYPE_FASTEST: hereOpt = GeoRouteQuery::RO_FastestRoute; break;
157 case MAPS_ROUTE_TYPE_SHORTEST: hereOpt = GeoRouteQuery::RO_ShortestRoute; break;
158 default: hereOpt = GeoRouteQuery::RO_FastestRoute; break;
160 m_pQuery->SetRouteOptimization(hereOpt);
164 GeoRouteQuery::MetricSystem eMetric;
165 maps_distance_unit_e eUnit;
166 if (maps_preference_get_distance_unit(hPref, &eUnit) == MAPS_ERROR_NONE)
170 case MAPS_DISTANCE_UNIT_M: eMetric = GeoRouteQuery::DIST_metric; break;
171 case MAPS_DISTANCE_UNIT_KM: eMetric = GeoRouteQuery::DIST_metric; break;
172 default: eMetric = GeoRouteQuery::DIST_imperial; break;
174 m_eDistanceUnit = eUnit;
175 m_pQuery->SetMetricSystem(eMetric);
179 if (maps_preference_get(hPref, MAPS_ROUTE_GEOMETRY_BOUNDING_BOX, &szViewBounds) == MAPS_ERROR_NONE)
181 GeoBoundingBox gbBox;
182 HereUtils::Convert(szViewBounds, gbBox);
183 m_pQuery->SetViewBounds(gbBox);
184 g_free(szViewBounds);
187 bool is_alternatives_enabled = false;
188 if (maps_preference_get_route_alternatives_enabled(hPref, &is_alternatives_enabled) == MAPS_ERROR_NONE)
190 if (is_alternatives_enabled)
192 m_pQuery->SetAlternatives(2);
196 char *szRealtimeTraffic;
197 if (maps_preference_get(hPref, MAPS_ROUTE_REALTIME_TRAFFIC, &szRealtimeTraffic) == MAPS_ERROR_NONE)
199 if (!strcmp(szRealtimeTraffic, "true") || !strcmp(szRealtimeTraffic, "enabled"))
201 m_pQuery->SetRealtimeTraffic(1);
203 else if (!strcmp(szRealtimeTraffic, "false") || !strcmp(szRealtimeTraffic, "disabled"))
205 m_pQuery->SetRealtimeTraffic(2);
209 m_pQuery->SetRealtimeTraffic(0);
211 g_free(szRealtimeTraffic);
214 return HERE_ERROR_NONE;
217 here_error_e HereRoute::StartRoute(void)
220 return HERE_ERROR_OUT_OF_MEMORY;
222 m_nRestReqId = m_pQuery->Execute(*this, NULL);
224 return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
227 void HereRoute::OnRouteReply(const GeoRouteReply& Reply)
229 if (m_bCanceled || !m_pCbFunc || !m_pQuery) // ignore call back if it was cancelled.
235 maps_route_h mapsRoute;
237 GeoRouteList hereRouteList = Reply.GetRoutes();
238 int nReplyIdx = 0, nReplyNum = hereRouteList.size();
239 GeoRouteList::iterator hereRoute;
243 ((maps_service_search_route_cb)m_pCbFunc)(MAPS_ERROR_NOT_FOUND, m_nReqId,
244 0, 0, NULL, m_pUserData);
249 for (hereRoute = hereRouteList.begin() ; hereRoute != hereRouteList.end() ; hereRoute++)
251 error = (maps_error_e)maps_route_create(&mapsRoute);
253 if (error == MAPS_ERROR_NONE)
256 if (!hereRoute->GetRouteId().empty())
257 maps_route_set_route_id(mapsRoute, (char*)hereRoute->GetRouteId().c_str());
260 maps_route_set_total_distance(mapsRoute,
261 HereUtils::ConvertDistance(hereRoute->GetDistance(), m_eDistanceUnit));
264 maps_route_set_distance_unit(mapsRoute, m_eDistanceUnit);
267 if (m_pQuery->GetRealtimeTraffic() == 1)
268 maps_route_set_total_duration(mapsRoute, hereRoute->GetTrafficTime());
270 maps_route_set_total_duration(mapsRoute, hereRoute->GetTravelTime());
274 maps_route_transport_mode_e eTransportMode;
275 eTransportMode = HereUtils::Convert(hereRoute->GetTravelMode());
276 maps_route_set_transport_mode(mapsRoute, eTransportMode);
279 GeoCoordinateList herePathList = hereRoute->GetPath();
280 maps_item_list_h mapsPathList;
281 maps_coordinates_h mapsPath;
283 if (maps_item_list_create(&mapsPathList) == MAPS_ERROR_NONE)
285 GeoCoordinateList::iterator herePath;
286 for (herePath = herePathList.begin(); herePath != herePathList.end(); herePath++)
288 double dLat = herePath->GetLatitude();
289 double dLng = herePath->GetLongitude();
291 if(maps_coordinates_create(dLat, dLng, &mapsPath) == MAPS_ERROR_NONE)
293 if (herePath == herePathList.begin())
294 maps_route_set_origin(mapsRoute, mapsPath);
295 else if (herePath == herePathList.end()-1)
296 maps_route_set_destination(mapsRoute, mapsPath);
298 maps_item_list_append(mapsPathList, mapsPath, maps_coordinates_clone);
300 maps_coordinates_destroy(mapsPath);
304 if (maps_item_list_items(mapsPathList))
306 maps_route_set_path(mapsRoute, mapsPathList);
307 maps_item_list_remove_all(mapsPathList, maps_coordinates_destroy);
309 maps_item_list_destroy(mapsPathList);
313 maps_area_h hMapsArea = NULL;
314 HereUtils::Convert(hereRoute->GetBounds(), hMapsArea);
317 maps_route_set_bounding_box(mapsRoute, hMapsArea);
318 maps_area_destroy(hMapsArea);
322 ProcessSegments(mapsRoute, hereRoute->GetRouteSegmentList());
327 maps_route_destroy(mapsRoute);
332 if (((maps_service_search_route_cb)m_pCbFunc)(error, m_nReqId,
333 nReplyIdx++, nReplyNum, mapsRoute, m_pUserData) == FALSE)
338 //maps_route_destroy(mapsRoute);
342 if(nReplyIdx >= nReplyNum)
346 void HereRoute::OnRouteFailure(const GeoRouteReply& Reply)
348 if (!m_bCanceled && m_pCbFunc)
349 ((maps_service_search_route_cb)m_pCbFunc)((maps_error_e)GetErrorCode(Reply), m_nReqId, 0, 0, NULL, m_pUserData);
353 maps_error_e HereRoute::ProcessSegments(maps_route_h mapsRoute, const RouteSegmentList& hereSegmList)
355 maps_item_list_h mapsSegmList;
356 maps_route_segment_h mapsSegm;
359 if (hereSegmList.empty()) return MAPS_ERROR_NOT_FOUND;
361 if ((error = (maps_error_e)maps_item_list_create(&mapsSegmList)) != MAPS_ERROR_NONE)
364 RouteSegmentList::const_iterator hereSegm;
365 for (hereSegm = hereSegmList.begin() ; hereSegm != hereSegmList.end() ; hereSegm++)
367 if (maps_route_segment_create(&mapsSegm) != MAPS_ERROR_NONE) continue;
370 maps_route_segment_set_distance(mapsSegm,
371 HereUtils::ConvertDistance(hereSegm->GetDistance(), m_eDistanceUnit));
374 maps_route_segment_set_duration(mapsSegm, hereSegm->GetTravelTime());
376 /* origin, destination */
377 GeoCoordinateList herePathList = hereSegm->GetPath();
378 int here_path_list_size = herePathList.size();
380 if (here_path_list_size > 0)
382 GeoCoordinates hereOrig = herePathList.at(0);
383 GeoCoordinates hereDest = herePathList.at(here_path_list_size-1);
385 maps_coordinates_h mapsOrig, mapsDest;
386 maps_coordinates_create(hereOrig.GetLatitude(),
387 hereOrig.GetLongitude(), &mapsOrig);
388 maps_coordinates_create(hereDest.GetLatitude(),
389 hereDest.GetLongitude(), &mapsDest);
390 maps_route_segment_set_origin(mapsSegm, mapsOrig);
391 maps_route_segment_set_destination(mapsSegm, mapsDest);
392 maps_coordinates_destroy(mapsOrig);
393 maps_coordinates_destroy(mapsDest);
397 ProcessManeuver(mapsSegm, hereSegm->GetManeuverList());
399 maps_item_list_append(mapsSegmList, mapsSegm, maps_route_segment_clone);
400 maps_route_segment_destroy(mapsSegm);
403 if (maps_item_list_items(mapsSegmList))
405 maps_route_set_segments(mapsRoute, mapsSegmList);
406 maps_item_list_remove_all(mapsSegmList, maps_route_segment_destroy);
408 maps_item_list_destroy(mapsSegmList);
410 return MAPS_ERROR_NONE;
413 maps_error_e HereRoute::ProcessManeuver(maps_route_segment_h mapsSegm, const ManeuverList& hereManeList)
415 maps_item_list_h mapsManeList;
416 maps_route_maneuver_h mapsManeuver;
417 maps_coordinates_h mapsCoord;
420 if (hereManeList.empty()) return MAPS_ERROR_NOT_FOUND;
422 if ((error = (maps_error_e)maps_item_list_create(&mapsManeList)) != MAPS_ERROR_NONE)
425 ManeuverList::const_iterator hereMane;
426 for (hereMane = hereManeList.begin() ; hereMane != hereManeList.end() ; hereMane++)
428 if (maps_route_maneuver_create(&mapsManeuver) != MAPS_ERROR_NONE) continue;
431 if (maps_coordinates_create(hereMane->GetPosition().GetLatitude(),
432 hereMane->GetPosition().GetLongitude(), &mapsCoord) == MAPS_ERROR_NONE)
434 maps_route_maneuver_set_position(mapsManeuver, mapsCoord);
435 maps_coordinates_destroy(mapsCoord);
439 if (!hereMane->GetInstructionText().empty())
440 maps_route_maneuver_set_instruction_text(mapsManeuver,
441 (char*)hereMane->GetInstructionText().c_str());
444 maps_route_maneuver_set_distance_to_next_instruction(mapsManeuver,
445 HereUtils::ConvertDistance(hereMane->GetDistanceToNextInstruction(), m_eDistanceUnit));
448 maps_route_maneuver_set_time_to_next_instruction(mapsManeuver,
449 hereMane->GetTimeToNextInstruction());
451 /* direction -> turn type */
452 maps_route_maneuver_set_turn_type(mapsManeuver,
453 HereUtils::Convert(hereMane->GetDirection()));
455 maps_item_list_append(mapsManeList, mapsManeuver, maps_route_maneuver_clone);
456 maps_route_maneuver_destroy(mapsManeuver);
459 if (maps_item_list_items(mapsManeList))
461 maps_route_segment_set_maneuvers(mapsSegm, mapsManeList);
462 maps_item_list_remove_all(mapsManeList, maps_route_maneuver_destroy);
464 maps_item_list_destroy(mapsManeList);
466 return MAPS_ERROR_NONE;
469 HERE_PLUGIN_END_NAMESPACE