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;
  }

}
Example #2
0
File: break.c Project: caomw/grass
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;
}