int editor_track_draw_current (RoadMapPen pen) { RoadMapPosition *from; RoadMapPosition *to; int first_shape = -1; int last_shape = -2; if (points_count < 2) return 0; if (pen == NULL) return 0; if (!cur_active_line) return 0; from = track_point_pos (0); to = track_point_pos (points_count-1); if (points_count > 2) { first_shape = 1; last_shape = points_count - 2; } roadmap_screen_draw_one_line (from, to, 0, from, first_shape, last_shape, editor_track_shape_position, &pen, 1, -1, 0, 0 ,0); return 1; }
static int create_new_line (int gps_first_point, int gps_last_point, int from_point, int to_point, int cfcc) { int p_from; int p_to; int line_id; if (editor_track_util_create_db (track_point_pos (gps_last_point)) == -1) { editor_log (ROADMAP_ERROR, "create_new_line: can't create db."); return -1; } if (from_point != -1) { p_from = from_point; } else { p_from = create_node (gps_first_point, &cur_node); if (p_from == -1) { return -1; } } if (to_point != -1) { p_to = to_point; } else { RoadMapPosition start_pos; editor_point_position (p_from, &start_pos); /* check if first and last point are the same */ if (!roadmap_math_compare_points (&start_pos, track_point_pos (gps_last_point))) { p_to = p_from; } else { p_to = editor_point_add (track_point_pos (gps_last_point), -1); if (p_to == -1) { return -1; } } } cur_node.id = p_to; cur_node.plugin_id = EditorPluginID; line_id = editor_track_util_create_line (gps_first_point, gps_last_point, p_from, p_to, cfcc, is_new_track); is_new_track = 0; return line_id; }
int editor_track_draw_current_new_direction_road(){ RoadMapPen layer_pens[LAYER_PROJ_AREAS]; NavigateSegment segment; RoadMapPosition intersection; int distance; int i; if (points_count < 1) return 0; roadmap_square_set_current(TrackConfirmedLine.line.square); if (!roadmap_line_route_is_low_weight (TrackConfirmedLine.line.line_id)) { return 0; } segment.square = TrackConfirmedLine.line.square; segment.line = TrackConfirmedLine.line.line_id; roadmap_line_from(TrackConfirmedLine.line.line_id, &segment.from_pos); roadmap_line_to(TrackConfirmedLine.line.line_id, &segment.to_pos); roadmap_line_shapes (TrackConfirmedLine.line.line_id, &segment.first_shape, &segment.last_shape); segment.shape_initial_pos = segment.from_pos; for (i = 0; i < LAYER_PROJ_AREAS; i++) { layer_pens[i] = roadmap_layer_get_pen (roadmap_line_cfcc(TrackConfirmedLine.line.line_id),1, i); } navigate_instr_fix_line_end(track_point_pos(points_count - 1), &segment, TrackConfirmedStreet.line_direction == ROUTE_DIRECTION_WITH_LINE ? LINE_END : LINE_START); if (!editor_override_exists(TrackConfirmedLine.line.line_id, TrackConfirmedLine.line.square)){ distance = roadmap_math_get_distance_from_segment (track_point_pos(points_count - 1), &segment.from_pos, &segment.to_pos, &intersection, NULL); if (TrackConfirmedStreet.line_direction == ROUTE_DIRECTION_WITH_LINE) distance = roadmap_math_distance (&intersection, &segment.from_pos); else distance = roadmap_math_distance (&intersection, &segment.to_pos); roadmap_ticker_set_last_event(road_munching_event); editor_points_display(distance); } roadmap_screen_draw_one_line (&segment.from_pos, &segment.to_pos, 0, &segment.shape_initial_pos, segment.first_shape, segment.last_shape, NULL, layer_pens, LAYER_PROJ_AREAS, -1, 0, 0, 0); return 0; }
static int point_distance_from_expected_position(int range_begin, int range_end, int point) { RoadMapPosition pos1; RoadMapPosition pos2; if (track_point_time (range_begin) + 1 >= track_point_time (range_end)) { pos1 = *track_point_pos (range_begin); pos2 = *track_point_pos (range_end); } else { double factor; factor = time_relative_part_factor_from_absolute_value( track_point_time (range_begin), track_point_time (range_end), track_point_time (point) - 0.5); pos1 = RoadMapPosition_from_relative_part_factor( track_point_pos (range_begin), track_point_pos (range_end), factor); factor = time_relative_part_factor_from_absolute_value( track_point_time (range_begin), track_point_time (range_end), track_point_time (point) + 0.5); pos2 = RoadMapPosition_from_relative_part_factor( track_point_pos (range_begin), track_point_pos (range_end), factor); } return roadmap_math_get_distance_from_segment (track_point_pos (point), &pos1, &pos2, NULL, NULL); }
/* Find if the current point matches a point on the current new line. * (Detect loops) */ static int match_distance_from_current (const RoadMapGpsPosition *gps_point, int last_point, RoadMapPosition *best_intersection, int *match_point) { int i; int distance; int smallest_distance; int azymuth = 0; RoadMapPosition intersection; smallest_distance = 0x7fffffff; for (i = 0; i < (last_point-1); i++) { distance = roadmap_math_get_distance_from_segment ((RoadMapPosition *)gps_point, track_point_pos (i), track_point_pos (i+1), &intersection, NULL); if (distance < smallest_distance) { smallest_distance = distance; *best_intersection = intersection; *match_point = i; azymuth = roadmap_math_azymuth (track_point_pos (i), track_point_pos (i+1)); } } return (smallest_distance < editor_track_point_distance ()) && (roadmap_math_delta_direction (azymuth, gps_point->steering) < 10); }
static int create_node(int point_id, NodeNeighbour *node) { int new_node; if (node && (node->id != -1)) { if (node->plugin_id == ROADMAP_PLUGIN_ID) { return editor_track_util_roadmap_node_to_editor (node); } return node->id; } new_node = editor_point_add (track_point_pos (point_id), -1); return new_node; }
int editor_track_known_locate_point (int point_id, const RoadMapGpsPosition *gps_position, RoadMapTracking *confirmed_street, RoadMapNeighbour *confirmed_line, RoadMapTracking *new_street, RoadMapNeighbour *new_line) { int found; int count; int current_fuzzy; RoadMapFuzzy best = roadmap_fuzzy_false (); RoadMapFuzzy second_best; const RoadMapPosition *position = track_point_pos (point_id); RoadMapFuzzy before; if (KnownCandidatesCount > 1) { if ((resolve_candidates (gps_position, point_id) == -1) || !KnownCandidatesCount) { KnownCandidatesCount = 0; editor_track_reset (); return 0; } if (KnownCandidatesCount > 1) { return 0; } } if (KnownCandidatesCount == 1) { KnownCandidateEntry *entry = KnownCandidates[0].entries; if (!--KnownCandidates[0].count) { KnownCandidatesCount = 0; } *new_line = entry->line; *new_street = entry->street; if (KnownCandidates[0].low_confidence) new_street->entry_fuzzyfied = roadmap_fuzzy_acceptable (); point_id = entry->point_id; memmove (entry, entry+1, KnownCandidates[0].count * sizeof(KnownCandidateEntry)); if (!point_id) { if (confirmed_street->valid && roadmap_plugin_same_line (&confirmed_line->line, &new_line->line)) { return 0; } *confirmed_street = *new_street; *confirmed_line = *new_line; confirmed_street->valid = 1; if (confirmed_street->valid) { /* This is probably a GPS jump or an error in resolve */ return -1; } } return point_id; } if (confirmed_street->valid) { /* We have an existing street match: check if it is still valid. */ before = confirmed_street->cur_fuzzyfied; if (!editor_track_util_get_distance (position, &confirmed_line->line, confirmed_line)) { current_fuzzy = 0; confirmed_line->distance = MAX_DISTANCE; } else { current_fuzzy = roadmap_navigate_fuzzify (new_street, confirmed_street, confirmed_line, confirmed_line, 0, gps_position->steering); } if (current_fuzzy && (new_street->line_direction == confirmed_street->line_direction) && ((current_fuzzy >= before) || roadmap_fuzzy_is_certain(current_fuzzy))) { confirmed_street->cur_fuzzyfied = current_fuzzy; return 0; /* We are on the same street. */ } } /* We must search again for the best street match. */ count = editor_track_util_find_street (gps_position, new_street, confirmed_street, confirmed_line, RoadMapNeighbourhood, ROADMAP_NEIGHBOURHOUD, &found, &best, &second_best); #if 0 if (count && (RoadMapNeighbourhood[found].distance < 30) && !roadmap_fuzzy_is_acceptable (best)) { /* if we are on a known street, we don't want to start a new road * if we are still close to it. In this case we ignore the fuzzy */ } else #endif if (!roadmap_fuzzy_is_good (best) && roadmap_fuzzy_is_acceptable (best) && confirmed_street->valid) { /* We're not sure that the new line is a real match. * Delay the decision if we're still close to the previous road. */ if (confirmed_line->distance < editor_track_point_distance ()) { RoadMapTracking candidate; if (roadmap_plugin_same_line (&RoadMapNeighbourhood[found].line, &confirmed_line->line)) { /* We don't have any candidates other than the current line */ return 0; } /* We have two candidates here */ /* current line */ KnownCandidates[0].entries[0].street = *confirmed_street; KnownCandidates[0].entries[0].line = *confirmed_line; KnownCandidates[0].entries[0].point_id = 0; KnownCandidates[0].count = 1; KnownCandidates[0].low_confidence = 0; /* new line */ candidate.entry_fuzzyfied = roadmap_navigate_fuzzify (&candidate, confirmed_street, confirmed_line, RoadMapNeighbourhood+found, 0, gps_position->steering); candidate.cur_fuzzyfied = candidate.entry_fuzzyfied; candidate.valid = 1; KnownCandidates[1].entries[0].street = candidate; KnownCandidates[1].entries[0].line = RoadMapNeighbourhood[found]; KnownCandidates[1].entries[0].point_id = point_id; KnownCandidates[1].count = 1; KnownCandidates[1].low_confidence = 0; KnownCandidatesCount = 2; return 0; } } if ((roadmap_fuzzy_is_good (best) && roadmap_fuzzy_is_good (second_best)) || (!roadmap_fuzzy_is_good (best) && roadmap_fuzzy_is_acceptable (second_best))) { /* We got too many options. Wait before deciding. */ int i; RoadMapFuzzy result; int use_acceptable = 0; if (!roadmap_fuzzy_is_good (best)) use_acceptable = 1; for (i = 0; i < count; ++i) { RoadMapTracking candidate; result = roadmap_navigate_fuzzify (&candidate, confirmed_street, confirmed_line, RoadMapNeighbourhood+i, 0, gps_position->steering); if (roadmap_fuzzy_is_good (result) || (use_acceptable && roadmap_fuzzy_is_acceptable (result))) { if (confirmed_street->valid && roadmap_plugin_same_line (&confirmed_line->line, &RoadMapNeighbourhood[i].line)) { if (result < best) { continue; } else { /* delay the decision as the current line is still good */ KnownCandidatesCount = 0; return 0; } } candidate.valid = 1; candidate.entry_fuzzyfied = candidate.cur_fuzzyfied = result; KnownCandidates[KnownCandidatesCount].entries[0].street = candidate; KnownCandidates[KnownCandidatesCount].entries[0].line = RoadMapNeighbourhood[i]; KnownCandidates[KnownCandidatesCount].entries[0].point_id = point_id; KnownCandidates[KnownCandidatesCount].count = 1; KnownCandidates[KnownCandidatesCount].low_confidence = 0; KnownCandidatesCount++; if (KnownCandidatesCount == MAX_PATHS) { roadmap_log (ROADMAP_ERROR, "ResolveCandidates - Reached max entries!"); break; } } } if (KnownCandidatesCount > 1) { return 0; } else { /* We only got one candidate so fall through to use it */ KnownCandidatesCount = 0; } } if (roadmap_fuzzy_is_acceptable (best)) { if (confirmed_street->valid && (!roadmap_plugin_same_line (&confirmed_line->line, &RoadMapNeighbourhood[found].line) || (confirmed_street->opposite_street_direction != new_street->opposite_street_direction) || (confirmed_street->line_direction != new_street->line_direction))) { *new_line = RoadMapNeighbourhood[found]; new_street->valid = 1; new_street->entry_fuzzyfied = new_street->cur_fuzzyfied = best; return point_id; } *confirmed_line = RoadMapNeighbourhood[found]; if (!confirmed_street->valid) confirmed_street->entry_fuzzyfied = best; new_street->entry_fuzzyfied = confirmed_street->entry_fuzzyfied; *confirmed_street = *new_street; confirmed_street->cur_fuzzyfied = best; confirmed_street->valid = 1; return 0; } else { new_street->valid = 0; return point_id; } }
int editor_track_known_end_segment (PluginLine *previous_line, int last_point_id, PluginLine *line, RoadMapTracking *street, int is_new_track) { //TODO: add stuff //Notice that previous_line may not be valid (only at first) // //check for low confidence & in static update, do not use a trkseg with low confidence! RoadMapPosition from; RoadMapPosition to; RoadMapPosition *current; int trkseg; int trkseg_line_id; int trkseg_plugin_id; int trkseg_square; int line_length; int segment_length; int percentage; int flags = 0; editor_log_push ("editor_track_end_known_segment"); assert (last_point_id != 0); if (!last_point_id) return 0; if (editor_db_activate (line->fips) == -1) { editor_db_create (line->fips); if (editor_db_activate (line->fips) == -1) { editor_log_pop (); return 0; } } roadmap_street_extend_line_ends (line, &from, &to, FLAG_EXTEND_BOTH, NULL, NULL); trkseg_plugin_id = roadmap_plugin_get_id (line); trkseg_line_id = roadmap_plugin_get_line_id (line); trkseg_square = roadmap_plugin_get_square (line); line_length = editor_track_util_get_line_length (line); segment_length = editor_track_util_length (0, last_point_id); editor_log (ROADMAP_INFO, "Ending line %d (plugin_id:%d). Line length:%d, Segment length:%d", trkseg_line_id, trkseg_plugin_id, line_length, segment_length); /* End current segment if we really passed through it * and not only touched a part of it. */ /*SRUL*: avoid this problem, see above comment assert (line_length > 0); if (line_length == 0) { editor_log (ROADMAP_ERROR, "line %d (plugin_id:%d) has length of zero.", trkseg_line_id, trkseg_plugin_id); editor_log_pop (); return 0; } */ if (line_length <= 0) line_length = 1; current = track_point_pos (last_point_id); if (roadmap_math_distance (current, &to) > roadmap_math_distance (current, &from)) { flags = ED_TRKSEG_OPPOSITE_DIR; #if DEBUG_TRACKS printf ("Closing trkseg from %d.%06d,%d.%06d to %d.%06d,%d.%06d", to.longitude / 1000000, to.longitude % 1000000, to.latitude / 1000000, to.latitude % 1000000, from.longitude / 1000000, from.longitude % 1000000, from.latitude / 1000000, from.latitude % 1000000); } else { printf ("Closing trkseg from %d.%06d,%d.%06d to %d.%06d,%d.%06d", from.longitude / 1000000, from.longitude % 1000000, from.latitude / 1000000, from.latitude % 1000000, to.longitude / 1000000, to.longitude % 1000000, to.latitude / 1000000, to.latitude % 1000000); #endif } #if DEBUG_TRACKS printf (" %d/%d", segment_length, line_length); #endif if (is_new_track) { flags |= ED_TRKSEG_NEW_TRACK; #if DEBUG_TRACKS printf (" NEW"); #endif } if (!editor_ignore_new_roads ()) { flags |= ED_TRKSEG_RECORDING_ON; } percentage = 100 * segment_length / line_length; if (percentage < 70) { editor_log (ROADMAP_INFO, "segment is too small to consider: %d%%", percentage); if (segment_length > (editor_track_point_distance ()*1.5)) { trkseg = editor_track_util_create_trkseg (trkseg_square, trkseg_line_id, trkseg_plugin_id, 0, last_point_id, flags|ED_TRKSEG_LOW_CONFID); editor_track_add_trkseg (line, trkseg, ROUTE_DIRECTION_NONE, ROUTE_CAR_ALLOWED); editor_log_pop (); #if DEBUG_TRACKS printf (" LOW (percentage)\n"); #endif return 1; } else { trkseg = editor_track_util_create_trkseg (trkseg_square, trkseg_line_id, trkseg_plugin_id, 0, last_point_id, flags|ED_TRKSEG_IGNORE); editor_track_add_trkseg (line, trkseg, ROUTE_DIRECTION_NONE, ROUTE_CAR_ALLOWED); editor_log_pop (); #if DEBUG_TRACKS printf (" IGNORE\n"); #endif return 0; } } #if 0 if (!roadmap_fuzzy_is_good (street->entry_fuzzyfied) || !roadmap_fuzzy_is_good (street->cur_fuzzyfied)) { flags |= ED_TRKSEG_LOW_CONFID; #if DEBUG_TRACKS printf (" LOW"); if (!roadmap_fuzzy_is_good (street->entry_fuzzyfied)) printf (" (entry)"); if (!roadmap_fuzzy_is_good (street->cur_fuzzyfied)) printf (" (cur)"); #endif } #endif if (trkseg_plugin_id != ROADMAP_PLUGIN_ID) flags |= ED_TRKSEG_LOW_CONFID; trkseg = editor_track_util_create_trkseg (trkseg_square, trkseg_line_id, trkseg_plugin_id, 0, last_point_id, flags); if (flags & ED_TRKSEG_OPPOSITE_DIR) { editor_log (ROADMAP_INFO, "Updating route direction: to -> from"); editor_track_add_trkseg (line, trkseg, ROUTE_DIRECTION_AGAINST_LINE, ROUTE_CAR_ALLOWED); } else { editor_log (ROADMAP_INFO, "Updating route direction: from -> to"); editor_track_add_trkseg (line, trkseg, ROUTE_DIRECTION_WITH_LINE, ROUTE_CAR_ALLOWED); } editor_log_pop (); #if DEBUG_TRACKS printf ("\n"); #endif return 1; }
static void end_unknown_segments (TrackNewSegment *new_segments, int count) { int i; int start_point = 0; NodeNeighbour end_node = NODE_NEIGHBOUR_NULL; editor_track_util_create_db (track_point_pos (start_point)); for (i=0; i<count; i++) { int type = new_segments[i].type; int end_point = new_segments[i].point_id; int end_node_id = -1; switch (type) { case TRACK_ROAD_TURN: if (editor_track_util_length (start_point, end_point) < (editor_track_point_distance () * 2)) { RoadMapPosition pos; RoadMapPosition *pos1; RoadMapPosition *pos2; pos1 = track_point_pos (start_point); pos2 = track_point_pos (end_point); pos.longitude = (pos1->longitude + pos2->longitude) / 2; pos.latitude = (pos1->latitude + pos2->latitude) / 2; if (cur_node.plugin_id == ROADMAP_PLUGIN_ID) { cur_node.id = editor_track_util_roadmap_node_to_editor (&cur_node); cur_node.plugin_id = EditorPluginID; } else { editor_point_set_pos (cur_node.id, &pos); } start_point = end_point; continue; } break; case TRACK_ROAD_ROUNDABOUT: if (cur_node.plugin_id == ROADMAP_PLUGIN_ID) { cur_node.id = editor_track_util_roadmap_node_to_editor (&cur_node); cur_node.plugin_id = EditorPluginID; } create_new_line (start_point, end_point, cur_node.id, cur_node.id, ROADMAP_ROAD_STREET); start_point = end_point; continue; break; } if ((i == (count - 1)) && (TrackConfirmedStreet.valid)) { /* we are connecting to a known road */ end_point = editor_track_util_new_road_end (&TrackConfirmedLine, track_point_pos (end_point), end_point, TrackConfirmedStreet.line_direction, &end_node); if (end_node.plugin_id == ROADMAP_PLUGIN_ID) { end_node.id = editor_track_util_roadmap_node_to_editor (&end_node); end_node.plugin_id = EditorPluginID; } end_node_id = end_node.id; } if ((i < (count -1)) || (start_point != (end_point -1))) { int line_id = create_new_line (start_point, end_point, -1, end_node_id, ROADMAP_ROAD_STREET); if ((line_id != -1) && ((type == TRACK_ROAD_CONNECTION) || !EditorAllowNewRoads)) { editor_line_set_flag (line_id, ED_LINE_CONNECTION); } } start_point = end_point; } track_reset_points (start_point); }
static int end_known_segment (int point_id, RoadMapTracking *new_street, RoadMapNeighbour *new_line) { int fips; int current_points_count = points_count; if (!TrackConfirmedStreet.valid) { TrackConfirmedLine = *new_line; TrackConfirmedStreet = *new_street; return point_id; } fips = roadmap_plugin_get_fips (&TrackConfirmedLine.line); if (editor_db_activate (fips) == -1) { editor_db_create (fips); if (editor_db_activate (fips) == -1) { roadmap_log (ROADMAP_ERROR, "Can't end known segment."); track_reset_points (-1); TrackConfirmedLine = *new_line; TrackConfirmedStreet = *new_street; return current_points_count - 1; } } if (new_street->valid) { int split_point; /* we have just switched from one known street to another */ if (TrackConfirmedStreet.valid && (TrackConfirmedLine.line.plugin_id == ROADMAP_PLUGIN_ID) && editor_screen_gray_scale()){ int low_weight; roadmap_square_set_current(TrackConfirmedLine.line.square); low_weight = roadmap_line_route_is_low_weight (TrackConfirmedLine.line.line_id); if (low_weight){ int length; RoadMapPosition line_from; RoadMapPosition line_to; int flags; if (editor_override_line_get_flags(TrackConfirmedLine.line.line_id, TrackConfirmedLine.line.square, &flags) == -1){ length = roadmap_line_length (TrackConfirmedLine.line.line_id); if (length > 0){ editor_points_add(length); roadmap_line_from (TrackConfirmedLine.line.line_id, &line_from); roadmap_line_to (TrackConfirmedLine.line.line_id, &line_to); roadmap_square_set_current (TrackConfirmedLine.line.square); editor_override_line_set_flag (TrackConfirmedLine.line.line_id, TrackConfirmedLine.line.square, ED_LINE_NEW_DIRECTION); } //roadmap_street_extend_line_ends (&TrackConfirmedLine.line, &line_from, &line_to, FLAG_EXTEND_BOTH, handle_new_direction, NULL); } } else{ editor_points_hide(); } } split_point = editor_track_util_connect_roads (&TrackConfirmedLine.line, &new_line->line, TrackConfirmedStreet.line_direction, new_street->line_direction, track_point_gps (point_id), point_id); if (split_point != -1) { if (editor_track_known_end_segment (&TrackPreviousLine.line, split_point, &TrackConfirmedLine.line, &TrackConfirmedStreet, is_new_track)) { is_new_track = 0; /*FIXME the whole previous line thing is not used and broken */ TrackPreviousLine = TrackConfirmedLine; } } else { /* We can't just connect the two roads. * We need to create a new road in between. */ #if 0 split_point = add_road_connection (point_id, new_street, new_line); #else split_point = -1; #endif if (split_point == -1) { TrackConfirmedLine = *new_line; TrackConfirmedStreet = *new_street; editor_track_util_create_trkseg (-1, -1, ROADMAP_PLUGIN_ID, 0, point_id, ED_TRKSEG_IGNORE); track_reset_points (point_id); //track_reset_points (-1); editor_track_known_reset_resolve (); return current_points_count - 1; } is_new_track = 0; TrackPreviousLine = TrackConfirmedLine; return split_point; } track_reset_points (split_point); TrackConfirmedLine = *new_line; TrackConfirmedStreet = *new_street; return split_point; } /* we are not on a known road */ if (TrackConfirmedStreet.valid) { int split_point; /* we just lost a known road, let's find the best point to start this new road from */ split_point = editor_track_util_new_road_start (&TrackConfirmedLine, track_point_pos (point_id), point_id, TrackConfirmedStreet.line_direction, &cur_node); if (split_point != -1) { if (editor_track_known_end_segment (&TrackPreviousLine.line, split_point, &TrackConfirmedLine.line, &TrackConfirmedStreet, is_new_track)) { is_new_track = 0; TrackPreviousLine = TrackConfirmedLine; } } track_reset_points (split_point); TrackConfirmedLine = *new_line; TrackConfirmedStreet = *new_street; return split_point; } assert(0); return point_id; }
static int add_road_connection (int point_id, RoadMapTracking *new_street, RoadMapNeighbour *new_line) { int from_point; int end_point; int line_id; NodeNeighbour end_node = NODE_NEIGHBOUR_NULL; int road_type = 0; editor_log_push ("add_road_connection"); from_point = editor_track_util_new_road_start (&TrackConfirmedLine, track_point_pos (point_id), point_id, TrackConfirmedStreet.line_direction, &cur_node); assert (from_point != -1); if (from_point == -1) { return -1; } if (editor_track_known_end_segment (&TrackPreviousLine.line, from_point, &TrackConfirmedLine.line, &TrackConfirmedStreet, is_new_track)) { is_new_track = 0; } track_reset_points (from_point); /*FIXME the whole previous line thing is not used and broken */ TrackPreviousLine = TrackConfirmedLine; TrackConfirmedLine = *new_line; TrackConfirmedStreet = *new_street; end_point = editor_track_util_new_road_end (&TrackConfirmedLine, track_point_pos (points_count - 1), points_count - 1, TrackConfirmedStreet.line_direction, &end_node); if ((cur_node.plugin_id == ROADMAP_PLUGIN_ID) && (end_node.plugin_id == ROADMAP_PLUGIN_ID)) { /* This a known connection road */ road_type = 0; } else { road_type = ED_LINE_CONNECTION; } if (!EditorAllowNewRoads) { road_type = ED_LINE_CONNECTION; } if (end_node.plugin_id == ROADMAP_PLUGIN_ID) { end_node.id = editor_track_util_roadmap_node_to_editor (&end_node); end_node.plugin_id = EditorPluginID; } line_id = create_new_line (0, end_point, -1, end_node.id, ROADMAP_ROAD_STREET); if (road_type == ED_LINE_CONNECTION) { if (line_id != -1) { editor_line_set_flag (line_id, ED_LINE_CONNECTION); } } track_reset_points (end_point); return from_point + end_point; }
static void editor_track_shape_position (int shape, RoadMapPosition *position) { assert (shape < points_count); *position = *track_point_pos (shape); }
static int detect_turn(int point_id, const RoadMapGpsPosition *gps_position, TrackNewSegment *new_segment, int max, int road_type) { static int last_straight_line_point = -1; static int last_straight_azymuth = 0; int middle1; int middle2; if (point_id == 0) return 0; if (point_id == 1) { last_straight_line_point = point_id; last_straight_azymuth = roadmap_math_azymuth (track_point_pos (point_id-1), track_point_pos (point_id)); return 0; } waze_assert (point_id > last_straight_line_point); /* trivial case */ if ((last_straight_line_point == (point_id-1)) && (roadmap_math_delta_direction (roadmap_math_azymuth (track_point_pos (point_id - 1), track_point_pos (point_id)), last_straight_azymuth) > 60)) { new_segment[0].type = road_type; new_segment[0].point_id = point_id - 1; last_straight_line_point = point_id; last_straight_azymuth = roadmap_math_azymuth (track_point_pos (point_id-1), track_point_pos (point_id)); return 1; } if (roadmap_math_delta_direction (roadmap_math_azymuth (track_point_pos (point_id - 1), (RoadMapPosition *)gps_position), roadmap_math_azymuth (track_point_pos (point_id - 3), track_point_pos (point_id - 2))) < 10) { int this_straight_azymuth; /* this is a straight line, save it */ this_straight_azymuth = roadmap_math_azymuth (track_point_pos (point_id - 3), track_point_pos (point_id)); if (last_straight_line_point == -1) { last_straight_line_point = point_id; last_straight_azymuth = this_straight_azymuth; return 0; } if (!find_line_break (last_straight_line_point, last_straight_azymuth, point_id-3, &middle1, &middle2)) { last_straight_line_point = point_id; last_straight_azymuth = this_straight_azymuth; return 0; } last_straight_line_point = point_id - middle2; last_straight_azymuth = this_straight_azymuth; waze_assert (middle1 > 0); if (middle1 > 0) { new_segment[0].type = road_type; new_segment[0].point_id = middle1; } if (middle1 != middle2) { /* make the curve a segment of its own */ new_segment[1].type = TRACK_ROAD_TURN; new_segment[1].point_id = middle2; return 2; } else { return 1; } } return 0; }
static int find_line_break (int last_point, int last_azymuth, int current_point, int *middle1, int *middle2) { #define MAX_TURN_POINTS 50 angle_pair pairs[MAX_TURN_POINTS]; int i; int j; int max_azymuth_diff = 0; int max_point_azymuth = 0; int max_azymuth_point = -1; int current_azymuth; if ((current_point - last_point + 1) > MAX_TURN_POINTS) return 0; j=0; for (i=last_point; i<=current_point; i++) { int diff; int prev_azymuth; current_azymuth = roadmap_math_azymuth (track_point_pos (i), track_point_pos (i+1)); diff = roadmap_math_delta_direction (last_azymuth, current_azymuth); if (diff > max_azymuth_diff) { max_azymuth_diff = diff; } if (i == last_point) { prev_azymuth = last_azymuth; } else { prev_azymuth = roadmap_math_azymuth (track_point_pos (i-1), track_point_pos (i)); } diff = roadmap_math_delta_direction (prev_azymuth, current_azymuth); pairs[j].index = i; pairs[j].angle = diff; j++; if (diff > max_point_azymuth) { max_point_azymuth = diff; max_azymuth_point = i; } } qsort (pairs, j, sizeof(angle_pair), angle_pair_cmp); if (max_azymuth_diff > 45) { int angle_sum = pairs[0].angle; int middle1_angle = pairs[0].angle; int middle2_angle = pairs[0].angle; *middle1 = pairs[0].index; *middle2 = pairs[0].index; j=1; while ((100 * angle_sum / max_azymuth_diff) < 70) { waze_assert (j<(current_point-last_point+1)); if (j>=(current_point-last_point+1)) break; angle_sum += pairs[j].angle; if (pairs[j].index < *middle1) { *middle1 = pairs[j].index; middle1_angle = pairs[j].angle; } else if (pairs[j].index > *middle2) { *middle2 = pairs[j].index; middle2_angle = pairs[j].angle; } j++; } return 1; } return 0; }