+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: ROUTE RESPONSE returned=%s", response);
+
+ rapidjson::Document document;
+ document.Parse(std::string(response, size).c_str());
+ rapidjson::Value::MemberIterator trip = document.FindMember("trip");
+ if (trip == document.MemberEnd()) {
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip object not found in response");
+ return;
+ }
+
+ // Process status
+ rapidjson::Value::ConstMemberIterator trip_status = trip->value.FindMember("status");
+ if (trip_status != trip->value.MemberEnd()) {
+ *status = trip_status->value.GetInt();
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip_status=%d", *status);
+ }
+ if (*status != 0) {
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: invalid status in response");
+ return;
+ }
+
+ // Create route response object and initialize lists to NULL
+ *routeResp = (mapzen_route_resp_s *) g_malloc(sizeof(mapzen_route_resp_s));
+ if (!(*routeResp))
+ return;
+ (*routeResp)->segments = NULL;
+ (*routeResp)->shapePoints = NULL;
+
+ // Get trip locations
+ rapidjson::SizeType location_index = 0;
+ rapidjson::Value& locations = trip->value["locations"];
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: locations.Size(): %d", locations.Size());
+
+ // Set trip origin
+ rapidjson::Value& mapzen_origin = locations[0];
+ (*routeResp)->origin.latitude = mapzen_origin["lat"].GetDouble();
+ (*routeResp)->origin.longitude = mapzen_origin["lon"].GetDouble();
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip origin: %f,%f", (*routeResp)->origin.latitude, (*routeResp)->origin.longitude);
+
+ // Set trip destination
+ rapidjson::Value& mapzen_destination = locations[locations.Size()-1];
+ (*routeResp)->destination.latitude = mapzen_destination["lat"].GetDouble();
+ (*routeResp)->destination.longitude = mapzen_destination["lon"].GetDouble();
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip destination: %f,%f", (*routeResp)->destination.latitude, (*routeResp)->destination.longitude);
+
+ // Set language
+ __get_string(trip->value, "language", &(*routeResp)->language);
+
+ // Set distance units
+ // TODO just read response units and set value
+ (*routeResp)->distance_unit = __route_unit;
+
+ // Set trip distance and time
+ rapidjson::Value::ConstMemberIterator trip_summary = trip->value.FindMember("summary");
+ if (trip_summary != trip->value.MemberEnd()) {
+ rapidjson::Value::ConstMemberIterator trip_distance = trip_summary->value.FindMember("length");
+ if (trip_distance != trip_summary->value.MemberEnd()) {
+ (*routeResp)->distance = trip_distance->value.GetDouble();
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip length : %f", (*routeResp)->distance);
+ }
+ rapidjson::Value::ConstMemberIterator trip_time = trip_summary->value.FindMember("time");
+ if (trip_time != trip_summary->value.MemberEnd()) {
+ (*routeResp)->time = trip_time->value.GetInt();
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip time: %d", trip_time->value.GetInt());
+ }
+ }
+
+ // Type
+ // TODO - set from input
+ (*routeResp)->type = COSTING_AUTO;
+
+ // Trip bounding box points
+ std::vector<coords_s> trip_bounding_box_candidates;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Process segments (legs)
+ rapidjson::Value::MemberIterator legs = trip->value.FindMember("legs");
+ if (legs == trip->value.MemberEnd() || !legs->value.IsArray()) {
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: invalid legs in response");
+ return;
+ }
+ for (rapidjson::Value::ConstValueIterator leg = legs->value.Begin(); leg != legs->value.End(); ++leg) {
+ // Create segment response
+ mapzen_route_segment *segment_resp = (mapzen_route_segment *)g_malloc(sizeof(mapzen_route_segment));
+ segment_resp->maneuvers = NULL;
+ segment_resp->shapePoints = NULL;
+
+ // Determine segment origin and destination
+ coords_s segment_origin;
+ coords_s segment_destination;
+ if (!__determine_segment_origin_destination(locations, location_index, segment_origin, segment_destination)) {
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: invalid segment origin and destination");
+ return;
+ }
+
+ // Set segment origin
+ segment_resp->origin = segment_origin;
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: segment_origin: %f,%f", segment_origin.latitude, segment_origin.longitude);
+
+ // Set segment destination
+ segment_resp->destination = segment_destination;
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: segment_destination: %f,%f", segment_destination.latitude, segment_destination.longitude);
+
+ // Set segment distance & time
+ rapidjson::Value::ConstMemberIterator leg_summary = leg->FindMember("summary");
+ if (leg_summary != leg->MemberEnd()) {
+ rapidjson::Value::ConstMemberIterator leg_distance = leg_summary->value.FindMember("length");
+ if (leg_distance != leg_summary->value.MemberEnd()) {
+ segment_resp->distance = leg_distance->value.GetDouble();
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: leg length=%f", segment_resp->distance);
+ }
+ rapidjson::Value::ConstMemberIterator leg_time = leg_summary->value.FindMember("time");
+ if (leg_time != leg_summary->value.MemberEnd()) {
+ segment_resp->time = leg_time->value.GetInt();
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: leg time=%d", segment_resp->time);
+ }
+ }
+
+ // Get segment encoded shape and decode
+ auto encoded_shape = leg->FindMember("shape");
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: ENCODED SHAPE=%s", encoded_shape->value.GetString());
+ std::vector<coords_s> decoded_shape;
+ decode_shape(encoded_shape->value.GetString(), decoded_shape);
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: Segment shape point count=%d", decoded_shape.size());
+
+ // Append shape for route trip and segment
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: PRE __process_shape");
+ __process_shape(decoded_shape, (*routeResp)->shapePoints);
+ __process_shape(decoded_shape, segment_resp->shapePoints);
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: POST __process_shape");
+
+ // Set segment bounding box
+ rectangle_s segment_bounding_box;
+ __create_bounding_box(decoded_shape, segment_bounding_box);
+ segment_resp->bounding_box = segment_bounding_box;
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: segment_bounding_box.top_left =%f,%f", segment_resp->bounding_box.top_left.latitude, segment_resp->bounding_box.top_left.longitude);
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: segment_bounding_box.bottom_right =%f,%f", segment_resp->bounding_box.bottom_right.latitude, segment_resp->bounding_box.bottom_right.longitude);
+
+ // Add segment bounding box points to the trip bounding box candidates
+ trip_bounding_box_candidates.push_back(segment_bounding_box.top_left);
+ trip_bounding_box_candidates.push_back(segment_bounding_box.bottom_right);
+
+ rapidjson::Value::ConstMemberIterator maneuvers = leg->FindMember("maneuvers");
+ if (maneuvers == leg->MemberEnd() || !maneuvers->value.IsArray())
+ return;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Process each maneuver
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: PRE __parse_maneuvers");
+ __parse_maneuvers(maneuvers, segment_resp, decoded_shape);
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: POST __parse_maneuvers");
+ ///////////////////////////////////////////////////////////////////////
+
+ // Add segment to segment list
+ if ((*routeResp)->segments == NULL) {
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: (*routeResp)->maneuvers == NULL) - append");
+ (*routeResp)->segments = g_list_append((*routeResp)->segments, (gpointer)segment_resp);
+ } else {
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: (*routeResp)->maneuvers != NULL) - insert before");
+ (*routeResp)->segments = g_list_insert_before((*routeResp)->segments, NULL, (gpointer)segment_resp);
+ }
+ } // end process each leg
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Trip Bounding box
+ rectangle_s trip_bounding_box;
+ __create_bounding_box(trip_bounding_box_candidates, trip_bounding_box);
+ (*routeResp)->bounding_box = trip_bounding_box;
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip_bounding_box.top_left =%f,%f", (*routeResp)->bounding_box.top_left.latitude, (*routeResp)->bounding_box.top_left.longitude);
+ MAP_DEBUG(">>>>> PROCESS __parse_route_response: trip_bounding_box.bottom_right =%f,%f", (*routeResp)->bounding_box.bottom_right.latitude, (*routeResp)->bounding_box.bottom_right.longitude);
+
+ MAP_DEBUG(">>>>> END __parse_route_response");