void QgsGrassEditAddVertex::mouseClick( QgsPoint & point, Qt::MouseButton button ) { double thresh = e->threshold(); switch ( button ) { case Qt::LeftButton: // Add vertex to previously selected line if ( e->mSelectedLine > 0 ) { e->eraseDynamic(); e->eraseElement( e->mSelectedLine ); // Move vertex int type = e->mProvider->readLine( e->mPoints, e->mCats, e->mSelectedLine ); if ( e->mAddVertexEnd && e->mSelectedPart == e->mEditPoints->n_points - 1 ) { e->snap( point ); Vect_append_point( e->mPoints, point.x(), point.y(), 0.0 ); } else { Vect_line_insert_point( e->mPoints, e->mSelectedPart, point.x(), point.y(), 0.0 ); } Vect_line_prune( e->mPoints ); e->mProvider->rewriteLine( e->mSelectedLine, type, e->mPoints, e->mCats ); e->updateSymb(); e->displayUpdated(); e->mSelectedLine = 0; Vect_reset_line( e->mEditPoints ); e->setCanvasPrompt( tr( "Select line segment" ), "", "" ); } else { // Select new line e->mSelectedLine = e->mProvider->findLine( point.x(), point.y(), GV_LINES, thresh ); if ( e->mSelectedLine ) // highlite { e->mProvider->readLine( e->mEditPoints, NULL, e->mSelectedLine ); e->displayElement( e->mSelectedLine, e->mSymb[QgsGrassEdit::SYMB_HIGHLIGHT], e->mSize ); double xl, yl; // nearest point on the line // Note first segment is 1! e->mSelectedPart = Vect_line_distance( e->mEditPoints, point.x(), point.y(), 0.0, 0, &xl, &yl, NULL, NULL, NULL, NULL ); double dist1 = Vect_points_distance( xl, yl, 0.0, e->mEditPoints->x[e->mSelectedPart-1], e->mEditPoints->y[e->mSelectedPart-1], 0.0, 0 ); double dist2 = Vect_points_distance( xl, yl, 0.0, e->mEditPoints->x[e->mSelectedPart], e->mEditPoints->y[e->mSelectedPart], 0.0, 0 ); double maxdist = ( dist1 + dist2 ) / 4; if ( e->mSelectedPart == 1 && dist1 < maxdist ) { e->mSelectedPart = 0; e->mAddVertexEnd = true; } else if ( e->mSelectedPart == e->mEditPoints->n_points - 1 && dist2 < maxdist ) { e->mAddVertexEnd = true; } else { e->mAddVertexEnd = false; } e->setCanvasPrompt( tr( "New vertex position" ), "", tr( "Release" ) ); } else { e->setCanvasPrompt( tr( "Select line segment" ), "", "" ); } } break; case Qt::RightButton: e->eraseDynamic(); e->displayElement( e->mSelectedLine, e->mSymb[e->mLineSymb[e->mSelectedLine]], e->mSize ); e->mSelectedLine = 0; Vect_reset_line( e->mEditPoints ); e->setCanvasPrompt( tr( "Select line segment" ), "", "" ); break; default: // ignore others break; } }
int connect_lines(struct Map_info *Map, int first, int line_from, int line_to, double thresh, struct ilist *List) { int line_new; int type_from, type_to; int n_points, seg, is; double x, y, px, py, x1, y1; double dist, spdist, lpdist, length, dist_p; double angle_t, angle_f, angle; struct line_pnts *Points_from, *Points_to, *Points_final; struct line_cats *Cats_from, *Cats_to; Points_from = Vect_new_line_struct(); Points_to = Vect_new_line_struct(); Points_final = Vect_new_line_struct(); Cats_from = Vect_new_cats_struct(); Cats_to = Vect_new_cats_struct(); type_from = Vect_read_line(Map, Points_from, Cats_from, line_from); type_to = Vect_read_line(Map, Points_to, Cats_to, line_to); line_new = 0; if (!(type_from & GV_LINES) || !(type_to & GV_LINES)) line_new = -1; if (line_new > -1) { if (first) { x = Points_from->x[0]; y = Points_from->y[0]; } else { n_points = Points_from->n_points - 1; x = Points_from->x[n_points]; y = Points_from->y[n_points]; } seg = Vect_line_distance(Points_to, x, y, 0.0, WITHOUT_Z, &px, &py, NULL, &dist, &spdist, &lpdist); if (seg > 0 && dist > 0.0 && (thresh < 0. || dist <= thresh)) { /* lines in threshold */ if (first) length = 0; else length = Vect_line_length(Points_from); if (Vect_point_on_line(Points_from, length, NULL, NULL, NULL, &angle_f, NULL) > 0) { if (Vect_point_on_line(Points_to, lpdist, NULL, NULL, NULL, &angle_t, NULL) > 0) { angle = angle_t - angle_f; dist_p = fabs(dist / sin(angle)); if (first) { if (angle_f < 0) angle_f -= M_PI; else angle_f += M_PI; } x1 = x + dist_p * cos(angle_f); y1 = y + dist_p * sin(angle_f); length = Vect_line_length(Points_to); Vect_line_insert_point(Points_to, seg, x1, y1, 0.); if (fabs(Vect_line_length(Points_to) - length) < length * 1e-3) { /* lines connected -> split line_to */ /* update line_from */ if (first) { Points_from->x[0] = x1; Points_from->y[0] = y1; } else { Points_from->x[n_points] = x1; Points_from->y[n_points] = y1; } line_new = Vect_rewrite_line(Map, line_from, type_from, Points_from, Cats_from); /* Vect_list_append(List, line_new); */ /* update line_to -- first part */ Vect_reset_line(Points_final); for (is = 0; is < seg; is++) { Vect_append_point(Points_final, Points_to->x[is], Points_to->y[is], Points_to->z[is]); } Vect_append_point(Points_final, x1, y1, 0.0); line_new = Vect_rewrite_line(Map, line_to, type_to, Points_final, Cats_to); /* Vect_list_append(List, line_new); */ /* write second part */ Vect_reset_line(Points_final); Vect_append_point(Points_final, x1, y1, 0.0); for (is = seg; is < Points_to->n_points; is++) { Vect_append_point(Points_final, Points_to->x[is], Points_to->y[is], Points_to->z[is]); } /* rewrite first part */ line_new = Vect_write_line(Map, type_to, Points_final, Cats_to); /* Vect_list_append(List, line_new); */ } } } } } Vect_destroy_line_struct(Points_from); Vect_destroy_line_struct(Points_to); Vect_destroy_line_struct(Points_final); Vect_destroy_cats_struct(Cats_from); Vect_destroy_cats_struct(Cats_to); return line_new > 0 ? 1 : 0; }