[GRASS-SVN] r32930 - grass/trunk/gui/wxpython/vdigit

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Aug 20 15:04:18 EDT 2008


Author: martinl
Date: 2008-08-20 15:04:18 -0400 (Wed, 20 Aug 2008)
New Revision: 32930

Added:
   grass/trunk/gui/wxpython/vdigit/driver_draw.cpp
   grass/trunk/gui/wxpython/vdigit/driver_select.cpp
Modified:
   grass/trunk/gui/wxpython/vdigit/driver.cpp
   grass/trunk/gui/wxpython/vdigit/driver.h
Log:
wxGUI/vdigit: simplify driver.cpp, add driver_draw/select.cpp
(merge from devrb6, r32928, r32929)


Modified: grass/trunk/gui/wxpython/vdigit/driver.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.cpp	2008-08-20 19:02:02 UTC (rev 32929)
+++ grass/trunk/gui/wxpython/vdigit/driver.cpp	2008-08-20 19:04:18 UTC (rev 32930)
@@ -86,510 +86,6 @@
     return;
 }
 
-/**
-   \brief Draw content of the vector map to device
-   
-   \return number of lines which were drawn
-   \return -1 on error
- */
-int DisplayDriver::DrawMap(bool force)
-{
-    if (!mapInfo || !dc)
-	return -1;
-
-    int nlines;
-    BOUND_BOX mapBox;
-    struct ilist *listLines;
-
-    // ids.clear();
-    listLines = Vect_new_list();
-
-    ResetTopology();
-
-    /* nlines = Vect_get_num_lines(mapInfo); */
-
-    Vect_get_map_box(mapInfo, &mapBox);
-
-    // draw lines inside of current display region
-    nlines = Vect_select_lines_by_box(mapInfo, &(region.box),
-     				      GV_POINTS | GV_LINES, // fixme
-				      listLines);
-
-    G_debug(3, "wxDriver.DrawMap(): region: w=%f, e=%f, s=%f, n=%f",
-	    region.box.W, region.box.E, region.box.S, region.box.N);
-
-    dc->BeginDrawing();
-
-    if (settings.area.enabled) {
-	/* draw area fills first */
-	int area, centroid, isle;
-	int num_isles;
-	bool draw;
-	struct ilist *listAreas, *listCentroids;
-	struct line_pnts *points, *ipoints, **isles;
-
-	wxBrush *fillArea, *fillIsle;
-
-	fillArea = new wxBrush(settings.area.color);
-	fillIsle = new wxBrush(*wxWHITE_BRUSH);
-	
-	listAreas = Vect_new_list();
-	listCentroids = Vect_new_list();
-	
-	points = Vect_new_line_struct();
-	ipoints = NULL;
-
-	Vect_select_areas_by_box(mapInfo, &region.box,
-				 listAreas);
-
-	for (int i = 0; i < listAreas->n_values; i++) {
-	    area = listAreas->value[i];
-	    
-	    if (!Vect_area_alive (mapInfo, area))
-		return -1;
-
-	    /* check for other centroids -- only area with one centroid is valid */
-	    centroid = Vect_get_area_centroid(mapInfo, area);
-
-	    if(centroid > 0) {
-		/* check for isles */
-		num_isles = Vect_get_area_num_isles(mapInfo, area); /* TODO */
-		if (num_isles < 1)
-		    isles = NULL;
-		else
-		    isles = (struct line_pnts **) G_malloc(num_isles * sizeof(struct line_pnts *));
-		for (int j = 0; j < num_isles; j++) {
-		    ipoints = Vect_new_line_struct();
-		    isle = Vect_get_area_isle(mapInfo, area, j);
-
-		    if (!Vect_isle_alive (mapInfo, isle))
-			return -1;
-
-		    Vect_get_isle_points(mapInfo, isle, ipoints);
-		    isles[j] = ipoints;
-		}
-
-		Vect_get_area_points(mapInfo, area, points);
-
-		/* avoid processing areas with large number of polygon points (ugly) */
-		if (points->n_points < 5000) {
-		    Vect_select_lines_by_polygon(mapInfo, points,
-						 num_isles, isles, GV_CENTROID, listCentroids);
-		}
-		else {
-		    Vect_reset_list(listCentroids);
-		}
-
-		draw = true;
-		for (int c = 0; c < listCentroids->n_values; c++) {
-		    if(Vect_get_centroid_area(mapInfo, listCentroids->value[c]) < 0) {
-			draw = false;
-			break;
-		    }
-		}
-		
-		if (draw) {
-		    dc->SetBrush(*fillArea);
-		    dc->SetPen(*wxTRANSPARENT_PEN);
-		    DrawArea(points);
-
-		    for (int j = 0; j < num_isles; j++) {
-			/* draw isles in white */
-			dc->SetBrush(*fillIsle);
-			dc->SetPen(*wxTRANSPARENT_PEN);
-			DrawArea(isles[j]);
-		    }
-		}
-
-		if(isles) {
-		    for (int j = 0; j < num_isles; j++) {
-			Vect_destroy_line_struct(isles[j]);
-			isles[j] = NULL;
-		    }
-		    G_free((void *) isles);
-		}
-	    }
-	}
-
-	delete fillArea;
-	delete fillIsle;
-
-	Vect_destroy_line_struct(points);
-
-	Vect_destroy_list(listAreas);
-	Vect_destroy_list(listCentroids);
-    }
-
-    for (int i = 0; i < listLines->n_values; i++) {
-	DrawLine(listLines->value[i]);
-    }
-    dc->EndDrawing();
-
-    // PrintIds();
-    
-    Vect_destroy_list(listLines);
-
-    return listLines->n_values;
-}	
-
-/**
-   \brief Draw area fill
-
-   \param area boundary points
-
-   \return 1 on success
-   \return -1 on failure (vector object is dead, etc.)
-*/
-int DisplayDriver::DrawArea(const line_pnts* points)
-{
-    double x, y, z;
-
-    // convert EN -> xy
-    wxPoint wxPoints[points->n_points];
-
-    for (int i = 0; i < points->n_points; i++) {
-	Cell2Pixel(points->x[i], points->y[i], points->z[i],
-		   &x, &y, &z);
-	wxPoints[i] = wxPoint((int) x, (int) y);
-    }
-
-    // draw polygon
-    dc->DrawPolygon(points->n_points, wxPoints);
-
-    return 1;
-}
-
-/**
-   \brief Draw selected vector objects to the device
- 
-   \param[in] line id
-
-   \return 1 on success
-   \return -1 on failure (vector object is dead, etc.)
-*/
-int DisplayDriver::DrawLine(int line)
-{
-    int dcId;       // 0 | 1 | segment id
-    int type;       // line type
-    double x, y, z; // screen coordinates
-    bool draw;      // draw object ?
-    wxPen *pen;
-    
-    pen = NULL;
-    draw = false;
-
-    if (!dc || !Vect_line_alive (mapInfo, line))
-	return -1;
-
-    // read line
-    type = Vect_read_line (mapInfo, points, cats, line);
-
-    // add ids
-    // -> node1, line1, vertex1, line2, ..., node2
-    // struct lineDesc desc = {points->n_points, dcId};
-    // ids[line] = desc;
-    // update id for next line
-    // dcId += points->n_points * 2 - 1;
-
-    if (IsSelected(line)) { // line selected ?
-	if (settings.highlightDupl.enabled && IsDuplicated(line)) {
-	    pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
-	}
-	else {
-	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	}
-	if (drawSelected) {
-	    draw = true;
-	}
-	else {
-	    draw = false;
-	}
-	dcId = 1;
-	topology.highlight++;
-    }
-    else {
-	dcId = 0;
-	if (type & GV_LINES) {
-	    switch (type) {
-	    case GV_LINE:
-		pen = new wxPen(settings.line.color, settings.lineWidth, wxSOLID);
-		topology.line++;
-		draw = settings.line.enabled;
-		break;
-	    case GV_BOUNDARY:
-		int left, right;
-		Vect_get_line_areas(mapInfo, line,
-				    &left, &right);
-		if (left == 0 && right == 0) {
-		    pen = new wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryNo++;
-		    draw = settings.boundaryNo.enabled;
-		}
-		else if (left > 0 && right > 0) {
-		    pen = new wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryTwo++;
-		    draw = settings.boundaryTwo.enabled;
-		}
-		else {
-		    pen = new wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryOne++;
-		    draw = settings.boundaryOne.enabled;
-		}
-		break;
-	    default:
-		draw = false;
-		break;
-	    }
-	}
-	else if (type & GV_POINTS) {
-	    if (type == GV_POINT && settings.point.enabled) {
-		pen = new wxPen(settings.point.color, settings.lineWidth, wxSOLID);
-		topology.point++;
-		draw = settings.point.enabled;
-	    }
-	    else if (type == GV_CENTROID) {
-		int cret = Vect_get_centroid_area(mapInfo, line);
-		if (cret > 0) { // -> area
-		    draw = settings.centroidIn.enabled;
-		    pen = new wxPen(settings.centroidIn.color, settings.lineWidth, wxSOLID);
-		    topology.centroidIn++;
-		}
-		else if (cret == 0) {
-		    draw = settings.centroidOut.enabled;
-		    pen = new wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID);
-		    topology.centroidOut++;
-		}
-		else {
-		    draw = settings.centroidDup.enabled;
-		    pen = new wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID);
-		    topology.centroidDup++;
-		}
-	    }
-	}
-    }
-    
-    // clear screen points & convert EN -> xy
-    pointsScreen->Clear();
-    for (int i = 0; i < points->n_points; i++) {
-	Cell2Pixel(points->x[i], points->y[i], points->z[i],
-		   &x, &y, &z);
-	pointsScreen->Append((wxObject*) new wxPoint((int) x, (int) y)); /* TODO: 3D */
-    }
-    
-    dc->SetId(dcId); /* 0 | 1 (selected) */
-   
-    if (draw) {
-	dc->SetPen(*pen);
-	if (type & GV_POINTS) {
-	    DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData());
-	}
-	else {
-	    // long int startId = ids[line].startId + 1;
-	    if (dcId > 0 && drawSegments) {
-		dcId = 2; // first segment
-		for (size_t i = 0; i < pointsScreen->GetCount() - 1; dcId += 2) {
-		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
-		    wxPoint *point_end = (wxPoint *) pointsScreen->Item(++i)->GetData();
-		    
-		    // set bounds for line
-		    // wxRect rect (*point_beg, *point_end);
-		    // dc->SetIdBounds(startId, rect);
-		    
-		    dc->SetId(dcId); // set unique id & set bbox for each segment
-		    dc->SetPen(*pen);
-		    wxRect rect (*point_beg, *point_end);
-		    dc->SetIdBounds(dcId, rect);
-		    dc->DrawLine(point_beg->x, point_beg->y,
-				 point_end->x, point_end->y);
-		}
-	    }
-	    else {
-		wxPoint wxPoints[pointsScreen->GetCount()];
-		for (size_t i = 0; i < pointsScreen->GetCount(); i++) {
-		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
-		    wxPoints[i] = *point_beg;
-		}
-		
-		dc->DrawLines(pointsScreen->GetCount(), wxPoints);
-
-		if (!IsSelected(line) && settings.direction.enabled) {
-		    DrawDirectionArrow();
-		    // restore pen
-		    dc->SetPen(*pen);
-		}
-	    }
-	}
-    }
-
-    if (type & GV_LINES) {
-	DrawLineVerteces(line); // draw vertices
-	DrawLineNodes(line);    // draw nodes
-    }
-
-    delete pen;
-
-    return 1;
-}
-
-/**
-   \brief Draw line verteces to the device
- 
-   Except of first and last vertex, see DrawLineNodes().
-
-   \param line id
-
-   \return number of verteces which were drawn
-   \return -1 if drawing vertices is disabled
-*/
-int DisplayDriver::DrawLineVerteces(int line)
-{
-    int dcId;
-    wxPoint *point;
-    wxPen *pen;
-
-    if (!IsSelected(line) && !settings.vertex.enabled)
-	return -1;
-
-    // determine color
-    if (!IsSelected(line)) {
-	pen = new wxPen(settings.vertex.color, settings.lineWidth, wxSOLID);
-	dcId = 0;
-    }
-    else {
-	if (!drawSelected) {
-	    return -1;
-	}
-	if (settings.highlightDupl.enabled && IsDuplicated(line)) {
-	    pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
-	}
-	else {
-	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	}
-	if (drawSegments) {
-	    dcId = 3; // first vertex
-	}
-	else {
-	    dcId = 1;
-	}
-    }
-
-    dc->SetId(dcId); /* 0 | 1 (selected) */
-    dc->SetPen(*pen);
-
-    for (size_t i = 1; i < pointsScreen->GetCount() - 1; i++, dcId += 2) {
-	point = (wxPoint*) pointsScreen->Item(i)->GetData();
-
-	if (IsSelected(line) && drawSegments) {
-	    dc->SetId(dcId);
-	    dc->SetPen(*pen);
-	    wxRect rect (*point, *point);
-	    dc->SetIdBounds(dcId, rect);
-	}
-	
-	if (settings.vertex.enabled) {
-	    DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData());
-	    topology.vertex++;
-	}
-    }
-
-    delete pen;
-
-    return pointsScreen->GetCount() - 2;
-}
-
-/**
-   \brief Draw line nodes to the device
- 
-   \param line id
-
-   \return 1
-   \return -1 if no nodes were drawn
-*/
-int DisplayDriver::DrawLineNodes(int line)
-{
-    int dcId;
-    int node;
-    double east, north, depth;
-    double x, y, z;
-    int nodes [2];
-    bool draw;
-
-    wxPen *pen;
-
-    // draw nodes??
-    if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled)
-	return -1;
-
-    // get nodes
-    Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1]));
-        
-    for (size_t i = 0; i < sizeof(nodes) / sizeof(int); i++) {
-	node = nodes[i];
-	// get coordinates
-	Vect_get_node_coor(mapInfo, node,
-			   &east, &north, &depth);
-
-	// convert EN->xy
-	Cell2Pixel(east, north, depth,
-		   &x, &y, &z);
-
-	// determine color
-	if (IsSelected(line)) {
-	    if (!drawSelected) {
-		return -1;
-	    }
-	    if (settings.highlightDupl.enabled && IsDuplicated(line)) {
-		pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
-	    }
-	    else {
-		pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	    }
-	    draw = true;
-	    if (!drawSegments) {
-		dcId = 1;
-	    }
-	    else {
-		// node1, line1, vertex1, line2, vertex2, ..., node2
-		if (i == 0) // first node
-		    dcId = 1; 
-		else // last node
-		    dcId = 2 * points->n_points - 1;
-	    }
-	}
-	else {
-	    dcId = 0;
-	    if (Vect_get_node_n_lines(mapInfo, node) == 1) {
-		pen = new wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID);
-		topology.nodeOne++;
-		draw = settings.nodeOne.enabled;
-	    }
-	    else {
-		pen = new wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID);
-		topology.nodeTwo++;
-		draw = settings.nodeTwo.enabled;
-	    }
-	}
-	
-	wxPoint point((int) x, (int) y);
-	if (IsSelected(line) && drawSegments) {
-	    wxRect rect (point, point);
-	    dc->SetIdBounds(dcId, rect);
-	}
-
-	// draw node if needed
-	if (draw) {
-	    dc->SetId(dcId);
-	    dc->SetPen(*pen);
-	    DrawCross(line, &point);
-	}
-    }
-    
-    delete pen;
-
-    return 1;
-}
-
-
 /*
   \brief Close vector map layer
   
@@ -773,27 +269,6 @@
     return;
 }
 
-/**
-   \brief Draw cross symbol of given size to device content
-   
-   Used for points, nodes, vertices
-
-   \param[in] point coordinates of center
-   \param[in] size size of the cross symbol
-   
-   \return 1 on success
-   \return -1 on failure
-*/
-int DisplayDriver::DrawCross(int line, const wxPoint* point, int size)
-{
-    if (!dc || !point)
-	return -1;
-
-    dc->DrawLine(point->x - size, point->y, point->x + size, point->y);
-    dc->DrawLine(point->x, point->y - size, point->x, point->y + size);
-    return 1;
-}
-
 /*
   \brief Set settings for displaying vector feature
  
@@ -922,394 +397,6 @@
 }
 
 /**
-   \brief Select vector objects by given bounding box
-   
-   If line id is already in the list of selected lines, then it will
-   be excluded from this list.
-
-
-   \param[in] x1,y1,z1,x2,y2,z3 bounding box definition
-   \param[in] type feature type
-   \param[in] onlyInside if true select only features inside
-   of bounding box (not overlapping)
-
-   \return number of selected features
-   \return -1 on error
-*/
-int DisplayDriver::SelectLinesByBox(double x1, double y1, double z1, 
-				    double x2, double y2, double z2,
-				    int type, bool onlyInside)
-{
-    if (!mapInfo)
-	return -1;
-
-    int line;
-
-    struct ilist *list;
-    struct line_pnts *bbox;
-
-    drawSegments = false;
-    drawSelected = true;
-
-    selected.isId = true;
-
-    list = Vect_new_list();
-    bbox = Vect_new_line_struct();
-
-    Vect_append_point(bbox, x1, y1, z1);
-    Vect_append_point(bbox, x2, y1, z2);
-    Vect_append_point(bbox, x2, y2, z1);
-    Vect_append_point(bbox, x1, y2, z2);
-    Vect_append_point(bbox, x1, y1, z1);
-        
-    Vect_select_lines_by_polygon(mapInfo, bbox,
-				 0, NULL, /* isles */
-				 type, list);
-
-    for (int i = 0; i < list->n_values; i++) {
-	line = list->value[i];
-	if (onlyInside) {
-	    bool inside;
-	    inside = true;
-	    Vect_read_line(mapInfo, points, cats, line);
-	    for (int p = 0; p < points->n_points; p++) {
-		if (!Vect_point_in_poly(points->x[p], points->y[p],
-					bbox)) {
-		    inside = false;
-		    break;
-		}
-	    }
-	    if (!inside)
-		continue; /* skip lines just overlapping bbox */
-	}
-	
-	if (!IsSelected(line)) {
-	    Vect_list_append(selected.values, line);
-	}
-	else {
-	    Vect_list_delete(selected.values, line);
-	}
-    }
-
-    Vect_destroy_line_struct(bbox);
-    Vect_destroy_list(list);
-
-    return list->n_values;
-}
-
-/**
-   \brief Select vector feature by given point in given
-   threshold
-   
-   Only one vector object can be selected. Bounding boxes of
-   all segments are stores.
-
-   \param[in] x,y point of searching
-   \param[in] thresh threshold value where to search
-   \param[in] type select vector object of given type
-
-   \return point on line if line found
-*/
-std::vector<double> DisplayDriver::SelectLineByPoint(double x, double y, double z,
-						     double thresh, int type, int with_z)
-{
-    long int line;
-    double px, py, pz;
-
-    std::vector<double> p;
-
-    drawSelected = true;
-
-    selected.isId = true;
-
-    line = Vect_find_line(mapInfo, x, y, z,
-			  type, thresh, with_z, 0);
-
-    if (line > 0) {
-	if (!IsSelected(line)) {
-	    Vect_list_append(selected.values, line);
-	}
-	else {
-	    Vect_list_delete(selected.values, line);
-	}
-
-	type = Vect_read_line (mapInfo, points, cats, line);
-	Vect_line_distance (points, x, y, z, with_z,
-			    &px, &py, &pz,
-			    NULL, NULL, NULL);
-	p.push_back(px);
-	p.push_back(py);
-	if (with_z) {
-	    p.push_back(pz);
-	}
-    }
-
-    drawSegments = true;
-
-    return p;
-}
-
-/**
-   \brief Is vector object selected?
-   
-   \param[in] line id
-
-   \return true if vector object is selected
-   \return false if vector object is not selected
-*/
-bool DisplayDriver::IsSelected(int line)
-{
-    if (selected.isId) {
-	if (Vect_val_in_list(selected.values, line))
-	    return true;
-    }
-    else {
-	for (int i = 0; i < cats->n_cats; i++) {
-	    if (cats->field[i] == 1 &&
-		Vect_val_in_list(selected.values, cats->cat[i])) 
-		return true;
-	}
-    }
-    
-    return false;
-}
-
-/**
-   \brief Get ids of selected objects
-
-   \param[in] grassId if true return GRASS line ids
-   if false return PseudoDC ids
-   
-   \return list of ids of selected vector objects
-*/
-std::vector<int> DisplayDriver::GetSelected(bool grassId)
-{
-    if (grassId)
-	return ListToVector(selected.values);
-
-    std::vector<int> dc_ids;
-
-    if (!drawSegments) {
-	dc_ids.push_back(1);
-    }
-    else {
-	int npoints;
-	Vect_read_line(mapInfo, points, NULL, selected.values->value[0]);
-	npoints = points->n_points;
-	for (int i = 1; i < 2 * npoints; i++) {
-	  dc_ids.push_back(i);
-	}
-    }
-
-    return dc_ids;
-}
-
-/**
-   \brief Get feature (grass) ids of duplicated objects
-
-   \return list of ids
-*/
-std::map<int, std::vector <int> > DisplayDriver::GetDuplicates()
-{
-    std::map<int, std::vector<int> > ids;
-
-    struct line_pnts *APoints, *BPoints;
- 
-    int line;
-
-    APoints = Vect_new_line_struct();
-    BPoints = Vect_new_line_struct();
-
-    Vect_reset_list(selected.valuesDupl);
-
-    for (int i = 0; i < selected.values->n_values; i++) {
-	line = selected.values->value[i];
-	if (IsDuplicated(line))
-	    continue;
-	
-	Vect_read_line(mapInfo, APoints, NULL, line);
-	
-	for (int j = 0; j < selected.values->n_values; j++) {
-	    if (i == j || IsDuplicated(selected.values->value[j]))
-		continue;
-	    
-	    Vect_read_line(mapInfo, BPoints, NULL, selected.values->value[j]);
-	    
-	    if (Vect_line_check_duplicate (APoints, BPoints, WITHOUT_Z)) {
-		if (ids.find(i) == ids.end()) {
-		    ids[i] = std::vector<int> ();
-		    ids[i].push_back(selected.values->value[i]);
-		    Vect_list_append(selected.valuesDupl, selected.values->value[i]);
-		}
-		ids[i].push_back(selected.values->value[j]);
-		Vect_list_append(selected.valuesDupl, selected.values->value[j]);
-	    }
-	}
-    }
-    
-    Vect_destroy_line_struct(APoints);
-    Vect_destroy_line_struct(BPoints);
-    
-    return ids;
-}
-
-/**
-   \brief Check for already marked duplicates
-
-   \param line line id
-
-   \return 1 line already marked as duplicated
-   \return 0 not duplicated
-*/
-bool DisplayDriver::IsDuplicated(int line)
-{
-    if (Vect_val_in_list(selected.valuesDupl, line))
-	return true;
-    
-    return false;
-}
-
-/**
-   \brief Set selected vector objects
-   
-   \param[in] list of GRASS ids to be set
-   \param[in] cat if True expect categories instead of feature ids
-
-   \return 1
-*/
-int DisplayDriver::SetSelected(std::vector<int> id, bool cat)
-{
-    drawSelected = true;
-
-    VectorToList(selected.values, id);
-    
-    selected.isId = !cat;
-
-    if (selected.values->n_values <= 0)
-	drawSegments = false;
-
-    return 1;
-}
-
-/**
-   \brief Unselect selected vector features
-   
-   \param[in] list of GRASS feature ids
-
-   \return number of selected features
-*/
-int DisplayDriver::UnSelect(std::vector<int> id)
-{
-    bool checkForDupl;
-
-    checkForDupl = false;
-
-    for (std::vector<int>::const_iterator i = id.begin(), e = id.end();
-	 i != e; ++i) {
-	if (IsSelected(*i)) {
-	    Vect_list_delete(selected.values, *i);
-	}
-	if (settings.highlightDupl.enabled && IsDuplicated(*i)) {
-	    checkForDupl = true;
-	}
-    }
-
-    if (checkForDupl) {
-	GetDuplicates();
-    }
-
-    return selected.values->n_values;
-}
-
-/**
-   \brief Get PseudoDC vertex id of selected line
-
-   Set bounding box for vertices of line.
-
-   \param[in] x,y coordinates of click
-   \param[in] thresh threshold value
-
-   \return id of center, left and right vertex
-
-   \return 0 no line found
-   \return -1 on error
-*/
-std::vector<int> DisplayDriver::GetSelectedVertex(double x, double y, double thresh)
-{
-    int startId;
-    int line, type;
-    int Gid, DCid;
-    double vx, vy, vz;      // vertex screen coordinates
-
-    double dist, minDist;
-
-    std::vector<int> returnId;
-
-    // only one object can be selected
-    if (selected.values->n_values != 1 || !drawSegments) 
-	return returnId;
-
-    startId = 1;
-    line = selected.values->value[0];
-
-    type = Vect_read_line (mapInfo, points, cats, line);
-
-    minDist = 0.0;
-    Gid = -1;
-    // find the closest vertex (x, y)
-    DCid = 1;
-    for(int idx = 0; idx < points->n_points; idx++) {
-	dist = Vect_points_distance(x, y, 0.0,
-				    points->x[idx], points->y[idx], points->z[idx], 0);
-	
-	if (idx == 0) {
-	    minDist = dist;
-	    Gid  = idx;
-	}
-	else {
-	    if (minDist > dist) {
-		minDist = dist;
-		Gid = idx;
-	    }
-	}
-
-	Cell2Pixel(points->x[idx], points->y[idx], points->z[idx],
-		   &vx, &vy, &vz);
-	wxRect rect (wxPoint ((int) vx, (int) vy), wxPoint ((int) vx, (int) vy));
-	dc->SetIdBounds(DCid, rect);
-	DCid+=2;
-    }	
-
-    if (minDist > thresh)
-	return returnId;
-
-    // desc = &(ids[line]);
-
-    // translate id
-    DCid = Gid * 2 + 1;
-
-    // add selected vertex
-    returnId.push_back(DCid);
-    // left vertex
-    if (DCid == startId) {
-	returnId.push_back(-1);
-    }
-    else {
-	returnId.push_back(DCid - 2);
-    }
-
-    // right vertex
-    if (DCid == (points->n_points - 1) * 2 + startId) {
-	returnId.push_back(-1);
-    }
-    else {
-	returnId.push_back(DCid + 2);
-    }
-
-    return returnId;
-}
-
-/**
    \brief Reset topology structure.
 
    \return
@@ -1423,194 +510,3 @@
     
     return 0;
 }
-
-/**
-   \brief Draw selected features
-
-   \param draw if true draw selected features
-*/
-void DisplayDriver::DrawSelected(bool draw)
-{
-    drawSelected = draw;
-
-    return;
-}
-
-/**
-   \brief Draw line direction arrow
-
-   \return number of drawn arrows
-*/
-int DisplayDriver::DrawDirectionArrow()
-{
-    int narrows;
-    int size; // arrow length in pixels
-    int limit; // segment length limit for drawing symbol (in pixels)
-    double dist, angle, pos;
-    double e, n, d, x0, y0, z0, x1, y1, z1;
-    struct line_pnts *points_seg;
-    wxPen *pen_arrow;
-    
-    narrows = 0;
-    size = 5;
-    limit = 5; // 5px for line segment
-
-    points_seg = Vect_new_line_struct();
-    pen_arrow = new wxPen(settings.direction.color, settings.lineWidth, wxSOLID);
-
-    dc->SetPen(*pen_arrow);
-
-    dist = Vect_line_length(points);
-    
-    if (DistanceInPixels(dist) >= limit) {
-	while (1) {
-	    pos = (narrows + 1) * 8 * limit * region.map_res;
-
-	    if (Vect_point_on_line(points, pos,
-				   &e, &n, &d, NULL, NULL) < 1) {
-		break;
-	    }
-	    
-	    Cell2Pixel(e, n, d, &x0, &y0, &z0);
-	    
-	    if (Vect_point_on_line(points, pos - 3 * size * region.map_res,
-				   &e, &n, &d, &angle, NULL) < 1) {
-		break;
-	    }
-	    
-	    Cell2Pixel(e, n, d, &x1, &y1, &z1);
-	    
-	    DrawArrow(x0, y0, x1, y1, angle, size);
-
-	    if(narrows > 1e2) // low resolution, break
-		break;
-
-	    narrows++;
-	}
-
-	// draw at least one arrow in the middle of line
-	if (narrows < 1) {
-	    dist /= 2.;
-	    if (Vect_point_on_line(points, dist,
-				   &e, &n, &d, NULL, NULL) > 0) {
-	    
-		Cell2Pixel(e, n, d, &x0, &y0, &z0);
-		
-		if (Vect_point_on_line(points, dist - 3 * size * region.map_res,
-				       &e, &n, &d, &angle, NULL) > 0) {
-		    
-		    Cell2Pixel(e, n, d, &x1, &y1, &z1);
-		    
-		    DrawArrow(x0, y0, x1, y1, angle, size);
-		}
-	    }
-	}
-    }
-
-    Vect_destroy_line_struct(points_seg);
-    
-    return narrows;
-}
-
-/**
-   \brief Draw arrow symbol on line
-
-   \param x0,y0 arrow origin
-   \param x1,x1 arrow ending point (on line)
-   \param angle point ending point angle
-   \param size arrow size
-
-   \return 1
-*/
-int DisplayDriver::DrawArrow(double x0, double y0,
-			     double x1, double y1, double angle,
-			     int size)
-{
-    double x, y;
-    double angle_symb;
-
-    angle_symb = angle - M_PI / 2.;
-    x = x1 + size * std::cos(angle_symb);
-    y = y1 - size * std::sin(angle_symb);
-    dc->DrawLine((wxCoord) x, (wxCoord) y, (wxCoord) x0, (wxCoord) y0);
-    
-    angle_symb = M_PI / 2. + angle;
-    x = x1 + size * std::cos(angle_symb);
-    y = y1 - size * std::sin(angle_symb);
-    dc->DrawLine((wxCoord) x0, (wxCoord) y0, (wxCoord) x, (wxCoord) y);
-
-    return 1;
-}
-
-/*!
-  \brief Get minimal region extent of selected features
-
-  \return n,s,w,e
-*/
-std::vector<int> DisplayDriver::GetRegionSelected()
-{
-    std::vector<int> region;
-
-    BOUND_BOX region_box, line_box;
-    struct ilist *list, *list_tmp;
-
-    list = list_tmp = NULL;
-
-    G_zero(&region_box, sizeof(region_box));
-    
-    if (!selected.isId) { /* -> cats */
-	list = Vect_new_list();
-	list_tmp = Vect_new_list();
-	/* can't use here
-	 *
-	  Vect_cidx_find_all(mapInfo, 1, GV_POINTS | GV_LINES,
-	  selected.values->value[i],
-	  list_tmp);
-	*/
-	int type;
-	bool found;
-	for (int line = 1; line < Vect_get_num_lines(mapInfo); line++) {
-	    type = Vect_read_line (mapInfo, NULL, cats, line);
-	    if (!(type & (GV_POINTS | GV_LINES)))
-		continue;
-	    
-	    found = false;
-	    for (int i = 0; i < cats->n_cats && !found; i++) {
-		for (int j = 0; j < selected.values->n_values && !found; j++) {
-		    if (cats->cat[i] == selected.values->value[j])
-			found = true;
-		}
-	    }
-	    if (found)
-		Vect_list_append(list, line);
-	}
-    }
-    else {
-	list = selected.values;
-    }
-    
-    for (int i = 0; i < list->n_values; i++) {
-	if (!Vect_get_line_box(mapInfo, list->value[i], &line_box))
-	    continue;
-
-	if (i == 0) {
-	    Vect_box_copy(&region_box, &line_box);
-	}
-	else {
-	    Vect_box_extend(&region_box, &line_box);
-	}
-    }
-
-    if (list && list != selected.values) {
-	Vect_destroy_list(list);
-    }
-    if (list_tmp)
-	Vect_destroy_list(list_tmp);
-	
-    region.push_back(region_box.N);
-    region.push_back(region_box.S);
-    region.push_back(region_box.W);
-    region.push_back(region_box.E);
-
-    return region;
-}

Modified: grass/trunk/gui/wxpython/vdigit/driver.h
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.h	2008-08-20 19:02:02 UTC (rev 32929)
+++ grass/trunk/gui/wxpython/vdigit/driver.h	2008-08-20 19:04:18 UTC (rev 32930)
@@ -44,17 +44,7 @@
      * segments with unique id (starting with '1')
      * are drawn only when line was selected using SelectLineByPoint()
      */
-    /*
-    struct lineDesc {
-	int      npoints;
-	long int startId;
-    };
     
-    typedef std::map<int, lineDesc> ids_map;
-    
-    ids_map ids; // gId : {dcIds, ...}
-    */
-
     struct _selected {
 	struct ilist *values;
 	struct ilist *valuesDupl;

Copied: grass/trunk/gui/wxpython/vdigit/driver_draw.cpp (from rev 32928, grass/branches/develbranch_6/gui/wxpython/vdigit/driver_draw.cpp)
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver_draw.cpp	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/driver_draw.cpp	2008-08-20 19:04:18 UTC (rev 32930)
@@ -0,0 +1,663 @@
+/**
+   \file driver_draw.cpp
+   
+   \brief Experimental C++ wxWidgets display driver
+
+   This driver is designed for wxPython GRASS GUI (digitization tool).
+   Draw vector map layer to PseudoDC.
+
+   (C) by the GRASS Development Team
+   This program is free software under the GNU General Public
+   License (>=v2). Read the file COPYING that comes with GRASS
+   for details.
+
+   \author Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008 
+*/
+
+#include <cmath>
+
+#include "driver.h"
+
+/**
+   \brief Draw content of the vector map to device
+   
+   \return number of lines which were drawn
+   \return -1 on error
+ */
+int DisplayDriver::DrawMap(bool force)
+{
+    if (!mapInfo || !dc)
+	return -1;
+
+    int nlines;
+    BOUND_BOX mapBox;
+    struct ilist *listLines;
+
+    // ids.clear();
+    listLines = Vect_new_list();
+
+    ResetTopology();
+
+    /* nlines = Vect_get_num_lines(mapInfo); */
+
+    Vect_get_map_box(mapInfo, &mapBox);
+
+    // draw lines inside of current display region
+    nlines = Vect_select_lines_by_box(mapInfo, &(region.box),
+     				      GV_POINTS | GV_LINES, // fixme
+				      listLines);
+
+    G_debug(3, "wxDriver.DrawMap(): region: w=%f, e=%f, s=%f, n=%f",
+	    region.box.W, region.box.E, region.box.S, region.box.N);
+
+    dc->BeginDrawing();
+
+    if (settings.area.enabled) {
+	/* draw area fills first */
+	int area, centroid, isle;
+	int num_isles;
+	bool draw;
+	struct ilist *listAreas, *listCentroids;
+	struct line_pnts *points, *ipoints, **isles;
+
+	wxBrush *fillArea, *fillIsle;
+
+	fillArea = new wxBrush(settings.area.color);
+	fillIsle = new wxBrush(*wxWHITE_BRUSH);
+	
+	listAreas = Vect_new_list();
+	listCentroids = Vect_new_list();
+	
+	points = Vect_new_line_struct();
+	ipoints = NULL;
+
+	Vect_select_areas_by_box(mapInfo, &region.box,
+				 listAreas);
+
+	for (int i = 0; i < listAreas->n_values; i++) {
+	    area = listAreas->value[i];
+	    
+	    if (!Vect_area_alive (mapInfo, area))
+		return -1;
+
+	    /* check for other centroids -- only area with one centroid is valid */
+	    centroid = Vect_get_area_centroid(mapInfo, area);
+
+	    if(centroid > 0) {
+		/* check for isles */
+		num_isles = Vect_get_area_num_isles(mapInfo, area); /* TODO */
+		if (num_isles < 1)
+		    isles = NULL;
+		else
+		    isles = (struct line_pnts **) G_malloc(num_isles * sizeof(struct line_pnts *));
+		for (int j = 0; j < num_isles; j++) {
+		    ipoints = Vect_new_line_struct();
+		    isle = Vect_get_area_isle(mapInfo, area, j);
+
+		    if (!Vect_isle_alive (mapInfo, isle))
+			return -1;
+
+		    Vect_get_isle_points(mapInfo, isle, ipoints);
+		    isles[j] = ipoints;
+		}
+
+		Vect_get_area_points(mapInfo, area, points);
+
+		/* avoid processing areas with large number of polygon points (ugly) */
+		if (points->n_points < 5000) {
+		    Vect_select_lines_by_polygon(mapInfo, points,
+						 num_isles, isles, GV_CENTROID, listCentroids);
+		}
+		else {
+		    Vect_reset_list(listCentroids);
+		}
+
+		draw = true;
+		for (int c = 0; c < listCentroids->n_values; c++) {
+		    if(Vect_get_centroid_area(mapInfo, listCentroids->value[c]) < 0) {
+			draw = false;
+			break;
+		    }
+		}
+		
+		if (draw) {
+		    dc->SetBrush(*fillArea);
+		    dc->SetPen(*wxTRANSPARENT_PEN);
+		    DrawArea(points);
+
+		    for (int j = 0; j < num_isles; j++) {
+			/* draw isles in white */
+			dc->SetBrush(*fillIsle);
+			dc->SetPen(*wxTRANSPARENT_PEN);
+			DrawArea(isles[j]);
+		    }
+		}
+
+		if(isles) {
+		    for (int j = 0; j < num_isles; j++) {
+			Vect_destroy_line_struct(isles[j]);
+			isles[j] = NULL;
+		    }
+		    G_free((void *) isles);
+		}
+	    }
+	}
+
+	delete fillArea;
+	delete fillIsle;
+
+	Vect_destroy_line_struct(points);
+
+	Vect_destroy_list(listAreas);
+	Vect_destroy_list(listCentroids);
+    }
+
+    for (int i = 0; i < listLines->n_values; i++) {
+	DrawLine(listLines->value[i]);
+    }
+    dc->EndDrawing();
+
+    // PrintIds();
+    
+    Vect_destroy_list(listLines);
+
+    return listLines->n_values;
+}	
+
+/**
+   \brief Draw area fill
+
+   \param area boundary points
+
+   \return 1 on success
+   \return -1 on failure (vector object is dead, etc.)
+*/
+int DisplayDriver::DrawArea(const line_pnts* points)
+{
+    double x, y, z;
+
+    // convert EN -> xy
+    wxPoint wxPoints[points->n_points];
+
+    for (int i = 0; i < points->n_points; i++) {
+	Cell2Pixel(points->x[i], points->y[i], points->z[i],
+		   &x, &y, &z);
+	wxPoints[i] = wxPoint((int) x, (int) y);
+    }
+
+    // draw polygon
+    dc->DrawPolygon(points->n_points, wxPoints);
+
+    return 1;
+}
+
+/**
+   \brief Draw selected vector objects to the device
+ 
+   \param[in] line id
+
+   \return 1 on success
+   \return -1 on failure (vector object is dead, etc.)
+*/
+int DisplayDriver::DrawLine(int line)
+{
+    int dcId;       // 0 | 1 | segment id
+    int type;       // line type
+    double x, y, z; // screen coordinates
+    bool draw;      // draw object ?
+    wxPen *pen;
+    
+    pen = NULL;
+    draw = false;
+
+    if (!dc || !Vect_line_alive (mapInfo, line))
+	return -1;
+
+    // read line
+    type = Vect_read_line (mapInfo, points, cats, line);
+
+    // add ids
+    // -> node1, line1, vertex1, line2, ..., node2
+    // struct lineDesc desc = {points->n_points, dcId};
+    // ids[line] = desc;
+    // update id for next line
+    // dcId += points->n_points * 2 - 1;
+
+    if (IsSelected(line)) { // line selected ?
+	if (settings.highlightDupl.enabled && IsDuplicated(line)) {
+	    pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
+	}
+	else {
+	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+	}
+	if (drawSelected) {
+	    draw = true;
+	}
+	else {
+	    draw = false;
+	}
+	dcId = 1;
+	topology.highlight++;
+    }
+    else {
+	dcId = 0;
+	if (type & GV_LINES) {
+	    switch (type) {
+	    case GV_LINE:
+		pen = new wxPen(settings.line.color, settings.lineWidth, wxSOLID);
+		topology.line++;
+		draw = settings.line.enabled;
+		break;
+	    case GV_BOUNDARY:
+		int left, right;
+		Vect_get_line_areas(mapInfo, line,
+				    &left, &right);
+		if (left == 0 && right == 0) {
+		    pen = new wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID);
+		    topology.boundaryNo++;
+		    draw = settings.boundaryNo.enabled;
+		}
+		else if (left > 0 && right > 0) {
+		    pen = new wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID);
+		    topology.boundaryTwo++;
+		    draw = settings.boundaryTwo.enabled;
+		}
+		else {
+		    pen = new wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID);
+		    topology.boundaryOne++;
+		    draw = settings.boundaryOne.enabled;
+		}
+		break;
+	    default:
+		draw = false;
+		break;
+	    }
+	}
+	else if (type & GV_POINTS) {
+	    if (type == GV_POINT && settings.point.enabled) {
+		pen = new wxPen(settings.point.color, settings.lineWidth, wxSOLID);
+		topology.point++;
+		draw = settings.point.enabled;
+	    }
+	    else if (type == GV_CENTROID) {
+		int cret = Vect_get_centroid_area(mapInfo, line);
+		if (cret > 0) { // -> area
+		    draw = settings.centroidIn.enabled;
+		    pen = new wxPen(settings.centroidIn.color, settings.lineWidth, wxSOLID);
+		    topology.centroidIn++;
+		}
+		else if (cret == 0) {
+		    draw = settings.centroidOut.enabled;
+		    pen = new wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID);
+		    topology.centroidOut++;
+		}
+		else {
+		    draw = settings.centroidDup.enabled;
+		    pen = new wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID);
+		    topology.centroidDup++;
+		}
+	    }
+	}
+    }
+    
+    // clear screen points & convert EN -> xy
+    pointsScreen->Clear();
+    for (int i = 0; i < points->n_points; i++) {
+	Cell2Pixel(points->x[i], points->y[i], points->z[i],
+		   &x, &y, &z);
+	pointsScreen->Append((wxObject*) new wxPoint((int) x, (int) y)); /* TODO: 3D */
+    }
+    
+    dc->SetId(dcId); /* 0 | 1 (selected) */
+   
+    if (draw) {
+	dc->SetPen(*pen);
+	if (type & GV_POINTS) {
+	    DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData());
+	}
+	else {
+	    // long int startId = ids[line].startId + 1;
+	    if (dcId > 0 && drawSegments) {
+		dcId = 2; // first segment
+		for (size_t i = 0; i < pointsScreen->GetCount() - 1; dcId += 2) {
+		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
+		    wxPoint *point_end = (wxPoint *) pointsScreen->Item(++i)->GetData();
+		    
+		    // set bounds for line
+		    // wxRect rect (*point_beg, *point_end);
+		    // dc->SetIdBounds(startId, rect);
+		    
+		    dc->SetId(dcId); // set unique id & set bbox for each segment
+		    dc->SetPen(*pen);
+		    wxRect rect (*point_beg, *point_end);
+		    dc->SetIdBounds(dcId, rect);
+		    dc->DrawLine(point_beg->x, point_beg->y,
+				 point_end->x, point_end->y);
+		}
+	    }
+	    else {
+		wxPoint wxPoints[pointsScreen->GetCount()];
+		for (size_t i = 0; i < pointsScreen->GetCount(); i++) {
+		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
+		    wxPoints[i] = *point_beg;
+		}
+		
+		dc->DrawLines(pointsScreen->GetCount(), wxPoints);
+
+		if (!IsSelected(line) && settings.direction.enabled) {
+		    DrawDirectionArrow();
+		    // restore pen
+		    dc->SetPen(*pen);
+		}
+	    }
+	}
+    }
+
+    if (type & GV_LINES) {
+	DrawLineVerteces(line); // draw vertices
+	DrawLineNodes(line);    // draw nodes
+    }
+
+    delete pen;
+
+    return 1;
+}
+
+/**
+   \brief Draw line verteces to the device
+ 
+   Except of first and last vertex, see DrawLineNodes().
+
+   \param line id
+
+   \return number of verteces which were drawn
+   \return -1 if drawing vertices is disabled
+*/
+int DisplayDriver::DrawLineVerteces(int line)
+{
+    int dcId;
+    wxPoint *point;
+    wxPen *pen;
+
+    if (!IsSelected(line) && !settings.vertex.enabled)
+	return -1;
+
+    // determine color
+    if (!IsSelected(line)) {
+	pen = new wxPen(settings.vertex.color, settings.lineWidth, wxSOLID);
+	dcId = 0;
+    }
+    else {
+	if (!drawSelected) {
+	    return -1;
+	}
+	if (settings.highlightDupl.enabled && IsDuplicated(line)) {
+	    pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
+	}
+	else {
+	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+	}
+	if (drawSegments) {
+	    dcId = 3; // first vertex
+	}
+	else {
+	    dcId = 1;
+	}
+    }
+
+    dc->SetId(dcId); /* 0 | 1 (selected) */
+    dc->SetPen(*pen);
+
+    for (size_t i = 1; i < pointsScreen->GetCount() - 1; i++, dcId += 2) {
+	point = (wxPoint*) pointsScreen->Item(i)->GetData();
+
+	if (IsSelected(line) && drawSegments) {
+	    dc->SetId(dcId);
+	    dc->SetPen(*pen);
+	    wxRect rect (*point, *point);
+	    dc->SetIdBounds(dcId, rect);
+	}
+	
+	if (settings.vertex.enabled) {
+	    DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData());
+	    topology.vertex++;
+	}
+    }
+
+    delete pen;
+
+    return pointsScreen->GetCount() - 2;
+}
+
+/**
+   \brief Draw line nodes to the device
+ 
+   \param line id
+
+   \return 1
+   \return -1 if no nodes were drawn
+*/
+int DisplayDriver::DrawLineNodes(int line)
+{
+    int dcId;
+    int node;
+    double east, north, depth;
+    double x, y, z;
+    int nodes [2];
+    bool draw;
+
+    wxPen *pen;
+
+    // draw nodes??
+    if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled)
+	return -1;
+
+    // get nodes
+    Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1]));
+        
+    for (size_t i = 0; i < sizeof(nodes) / sizeof(int); i++) {
+	node = nodes[i];
+	// get coordinates
+	Vect_get_node_coor(mapInfo, node,
+			   &east, &north, &depth);
+
+	// convert EN->xy
+	Cell2Pixel(east, north, depth,
+		   &x, &y, &z);
+
+	// determine color
+	if (IsSelected(line)) {
+	    if (!drawSelected) {
+		return -1;
+	    }
+	    if (settings.highlightDupl.enabled && IsDuplicated(line)) {
+		pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
+	    }
+	    else {
+		pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+	    }
+	    draw = true;
+	    if (!drawSegments) {
+		dcId = 1;
+	    }
+	    else {
+		// node1, line1, vertex1, line2, vertex2, ..., node2
+		if (i == 0) // first node
+		    dcId = 1; 
+		else // last node
+		    dcId = 2 * points->n_points - 1;
+	    }
+	}
+	else {
+	    dcId = 0;
+	    if (Vect_get_node_n_lines(mapInfo, node) == 1) {
+		pen = new wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID);
+		topology.nodeOne++;
+		draw = settings.nodeOne.enabled;
+	    }
+	    else {
+		pen = new wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID);
+		topology.nodeTwo++;
+		draw = settings.nodeTwo.enabled;
+	    }
+	}
+	
+	wxPoint point((int) x, (int) y);
+	if (IsSelected(line) && drawSegments) {
+	    wxRect rect (point, point);
+	    dc->SetIdBounds(dcId, rect);
+	}
+
+	// draw node if needed
+	if (draw) {
+	    dc->SetId(dcId);
+	    dc->SetPen(*pen);
+	    DrawCross(line, &point);
+	}
+    }
+    
+    delete pen;
+
+    return 1;
+}
+/**
+   \brief Draw cross symbol of given size to device content
+   
+   Used for points, nodes, vertices
+
+   \param[in] point coordinates of center
+   \param[in] size size of the cross symbol
+   
+   \return 1 on success
+   \return -1 on failure
+*/
+int DisplayDriver::DrawCross(int line, const wxPoint* point, int size)
+{
+    if (!dc || !point)
+	return -1;
+
+    dc->DrawLine(point->x - size, point->y, point->x + size, point->y);
+    dc->DrawLine(point->x, point->y - size, point->x, point->y + size);
+    return 1;
+}
+
+/**
+   \brief Draw selected features
+
+   \param draw if true draw selected features
+*/
+void DisplayDriver::DrawSelected(bool draw)
+{
+    drawSelected = draw;
+
+    return;
+}
+
+/**
+   \brief Draw line direction arrow
+
+   \return number of drawn arrows
+*/
+int DisplayDriver::DrawDirectionArrow()
+{
+    int narrows;
+    int size; // arrow length in pixels
+    int limit; // segment length limit for drawing symbol (in pixels)
+    double dist, angle, pos;
+    double e, n, d, x0, y0, z0, x1, y1, z1;
+    struct line_pnts *points_seg;
+    wxPen *pen_arrow;
+    
+    narrows = 0;
+    size = 5;
+    limit = 5; // 5px for line segment
+
+    points_seg = Vect_new_line_struct();
+    pen_arrow = new wxPen(settings.direction.color, settings.lineWidth, wxSOLID);
+
+    dc->SetPen(*pen_arrow);
+
+    dist = Vect_line_length(points);
+    
+    if (DistanceInPixels(dist) >= limit) {
+	while (1) {
+	    pos = (narrows + 1) * 8 * limit * region.map_res;
+
+	    if (Vect_point_on_line(points, pos,
+				   &e, &n, &d, NULL, NULL) < 1) {
+		break;
+	    }
+	    
+	    Cell2Pixel(e, n, d, &x0, &y0, &z0);
+	    
+	    if (Vect_point_on_line(points, pos - 3 * size * region.map_res,
+				   &e, &n, &d, &angle, NULL) < 1) {
+		break;
+	    }
+	    
+	    Cell2Pixel(e, n, d, &x1, &y1, &z1);
+	    
+	    DrawArrow(x0, y0, x1, y1, angle, size);
+
+	    if(narrows > 1e2) // low resolution, break
+		break;
+
+	    narrows++;
+	}
+
+	// draw at least one arrow in the middle of line
+	if (narrows < 1) {
+	    dist /= 2.;
+	    if (Vect_point_on_line(points, dist,
+				   &e, &n, &d, NULL, NULL) > 0) {
+	    
+		Cell2Pixel(e, n, d, &x0, &y0, &z0);
+		
+		if (Vect_point_on_line(points, dist - 3 * size * region.map_res,
+				       &e, &n, &d, &angle, NULL) > 0) {
+		    
+		    Cell2Pixel(e, n, d, &x1, &y1, &z1);
+		    
+		    DrawArrow(x0, y0, x1, y1, angle, size);
+		}
+	    }
+	}
+    }
+
+    Vect_destroy_line_struct(points_seg);
+    
+    return narrows;
+}
+
+/**
+   \brief Draw arrow symbol on line
+
+   \param x0,y0 arrow origin
+   \param x1,x1 arrow ending point (on line)
+   \param angle point ending point angle
+   \param size arrow size
+
+   \return 1
+*/
+int DisplayDriver::DrawArrow(double x0, double y0,
+			     double x1, double y1, double angle,
+			     int size)
+{
+    double x, y;
+    double angle_symb;
+
+    angle_symb = angle - M_PI / 2.;
+    x = x1 + size * std::cos(angle_symb);
+    y = y1 - size * std::sin(angle_symb);
+    dc->DrawLine((wxCoord) x, (wxCoord) y, (wxCoord) x0, (wxCoord) y0);
+    
+    angle_symb = M_PI / 2. + angle;
+    x = x1 + size * std::cos(angle_symb);
+    y = y1 - size * std::sin(angle_symb);
+    dc->DrawLine((wxCoord) x0, (wxCoord) y0, (wxCoord) x, (wxCoord) y);
+
+    return 1;
+}
+

Copied: grass/trunk/gui/wxpython/vdigit/driver_select.cpp (from rev 32928, grass/branches/develbranch_6/gui/wxpython/vdigit/driver_select.cpp)
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver_select.cpp	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/driver_select.cpp	2008-08-20 19:04:18 UTC (rev 32930)
@@ -0,0 +1,482 @@
+/**
+   \file driver_select.cpp
+   
+   \brief Experimental C++ wxWidgets display driver
+
+   This driver is designed for wxPython GRASS GUI (digitization tool).
+   Draw vector map layer to PseudoDC.
+
+   (C) by the GRASS Development Team
+   This program is free software under the GNU General Public
+   License (>=v2). Read the file COPYING that comes with GRASS
+   for details.
+
+   \author Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008 
+*/
+
+#include <cmath>
+
+#include "driver.h"
+
+/**
+   \brief Select vector objects by given bounding box
+   
+   If line id is already in the list of selected lines, then it will
+   be excluded from this list.
+
+
+   \param[in] x1,y1,z1,x2,y2,z3 bounding box definition
+   \param[in] type feature type
+   \param[in] onlyInside if true select only features inside
+   of bounding box (not overlapping)
+
+   \return number of selected features
+   \return -1 on error
+*/
+int DisplayDriver::SelectLinesByBox(double x1, double y1, double z1, 
+				    double x2, double y2, double z2,
+				    int type, bool onlyInside)
+{
+    if (!mapInfo)
+	return -1;
+
+    int line;
+
+    struct ilist *list;
+    struct line_pnts *bbox;
+
+    drawSegments = false;
+    drawSelected = true;
+
+    selected.isId = true;
+
+    list = Vect_new_list();
+    bbox = Vect_new_line_struct();
+
+    Vect_append_point(bbox, x1, y1, z1);
+    Vect_append_point(bbox, x2, y1, z2);
+    Vect_append_point(bbox, x2, y2, z1);
+    Vect_append_point(bbox, x1, y2, z2);
+    Vect_append_point(bbox, x1, y1, z1);
+        
+    Vect_select_lines_by_polygon(mapInfo, bbox,
+				 0, NULL, /* isles */
+				 type, list);
+
+    for (int i = 0; i < list->n_values; i++) {
+	line = list->value[i];
+	if (onlyInside) {
+	    bool inside;
+	    inside = true;
+	    Vect_read_line(mapInfo, points, cats, line);
+	    for (int p = 0; p < points->n_points; p++) {
+		if (!Vect_point_in_poly(points->x[p], points->y[p],
+					bbox)) {
+		    inside = false;
+		    break;
+		}
+	    }
+	    if (!inside)
+		continue; /* skip lines just overlapping bbox */
+	}
+	
+	if (!IsSelected(line)) {
+	    Vect_list_append(selected.values, line);
+	}
+	else {
+	    Vect_list_delete(selected.values, line);
+	}
+    }
+
+    Vect_destroy_line_struct(bbox);
+    Vect_destroy_list(list);
+
+    return list->n_values;
+}
+
+/**
+   \brief Select vector feature by given point in given
+   threshold
+   
+   Only one vector object can be selected. Bounding boxes of
+   all segments are stores.
+
+   \param[in] x,y point of searching
+   \param[in] thresh threshold value where to search
+   \param[in] type select vector object of given type
+
+   \return point on line if line found
+*/
+std::vector<double> DisplayDriver::SelectLineByPoint(double x, double y, double z,
+						     double thresh, int type, int with_z)
+{
+    long int line;
+    double px, py, pz;
+
+    std::vector<double> p;
+
+    drawSelected = true;
+
+    selected.isId = true;
+
+    line = Vect_find_line(mapInfo, x, y, z,
+			  type, thresh, with_z, 0);
+
+    if (line > 0) {
+	if (!IsSelected(line)) {
+	    Vect_list_append(selected.values, line);
+	}
+	else {
+	    Vect_list_delete(selected.values, line);
+	}
+
+	type = Vect_read_line (mapInfo, points, cats, line);
+	Vect_line_distance (points, x, y, z, with_z,
+			    &px, &py, &pz,
+			    NULL, NULL, NULL);
+	p.push_back(px);
+	p.push_back(py);
+	if (with_z) {
+	    p.push_back(pz);
+	}
+    }
+
+    drawSegments = true;
+
+    return p;
+}
+
+/**
+   \brief Is vector object selected?
+   
+   \param[in] line id
+
+   \return true if vector object is selected
+   \return false if vector object is not selected
+*/
+bool DisplayDriver::IsSelected(int line)
+{
+    if (selected.isId) {
+	if (Vect_val_in_list(selected.values, line))
+	    return true;
+    }
+    else {
+	for (int i = 0; i < cats->n_cats; i++) {
+	    if (cats->field[i] == 1 &&
+		Vect_val_in_list(selected.values, cats->cat[i])) 
+		return true;
+	}
+    }
+    
+    return false;
+}
+
+/**
+   \brief Get ids of selected objects
+
+   \param[in] grassId if true return GRASS line ids
+   if false return PseudoDC ids
+   
+   \return list of ids of selected vector objects
+*/
+std::vector<int> DisplayDriver::GetSelected(bool grassId)
+{
+    if (grassId)
+	return ListToVector(selected.values);
+
+    std::vector<int> dc_ids;
+
+    if (!drawSegments) {
+	dc_ids.push_back(1);
+    }
+    else {
+	int npoints;
+	Vect_read_line(mapInfo, points, NULL, selected.values->value[0]);
+	npoints = points->n_points;
+	for (int i = 1; i < 2 * npoints; i++) {
+	  dc_ids.push_back(i);
+	}
+    }
+
+    return dc_ids;
+}
+
+/**
+   \brief Get feature (grass) ids of duplicated objects
+
+   \return list of ids
+*/
+std::map<int, std::vector <int> > DisplayDriver::GetDuplicates()
+{
+    std::map<int, std::vector<int> > ids;
+
+    struct line_pnts *APoints, *BPoints;
+ 
+    int line;
+
+    APoints = Vect_new_line_struct();
+    BPoints = Vect_new_line_struct();
+
+    Vect_reset_list(selected.valuesDupl);
+
+    for (int i = 0; i < selected.values->n_values; i++) {
+	line = selected.values->value[i];
+	if (IsDuplicated(line))
+	    continue;
+	
+	Vect_read_line(mapInfo, APoints, NULL, line);
+	
+	for (int j = 0; j < selected.values->n_values; j++) {
+	    if (i == j || IsDuplicated(selected.values->value[j]))
+		continue;
+	    
+	    Vect_read_line(mapInfo, BPoints, NULL, selected.values->value[j]);
+	    
+	    if (Vect_line_check_duplicate (APoints, BPoints, WITHOUT_Z)) {
+		if (ids.find(i) == ids.end()) {
+		    ids[i] = std::vector<int> ();
+		    ids[i].push_back(selected.values->value[i]);
+		    Vect_list_append(selected.valuesDupl, selected.values->value[i]);
+		}
+		ids[i].push_back(selected.values->value[j]);
+		Vect_list_append(selected.valuesDupl, selected.values->value[j]);
+	    }
+	}
+    }
+    
+    Vect_destroy_line_struct(APoints);
+    Vect_destroy_line_struct(BPoints);
+    
+    return ids;
+}
+
+/**
+   \brief Check for already marked duplicates
+
+   \param line line id
+
+   \return 1 line already marked as duplicated
+   \return 0 not duplicated
+*/
+bool DisplayDriver::IsDuplicated(int line)
+{
+    if (Vect_val_in_list(selected.valuesDupl, line))
+	return true;
+    
+    return false;
+}
+
+/**
+   \brief Set selected vector objects
+   
+   \param[in] list of GRASS ids to be set
+   \param[in] cat if True expect categories instead of feature ids
+
+   \return 1
+*/
+int DisplayDriver::SetSelected(std::vector<int> id, bool cat)
+{
+    drawSelected = true;
+
+    VectorToList(selected.values, id);
+    
+    selected.isId = !cat;
+
+    if (selected.values->n_values <= 0)
+	drawSegments = false;
+
+    return 1;
+}
+
+/**
+   \brief Unselect selected vector features
+   
+   \param[in] list of GRASS feature ids
+
+   \return number of selected features
+*/
+int DisplayDriver::UnSelect(std::vector<int> id)
+{
+    bool checkForDupl;
+
+    checkForDupl = false;
+
+    for (std::vector<int>::const_iterator i = id.begin(), e = id.end();
+	 i != e; ++i) {
+	if (IsSelected(*i)) {
+	    Vect_list_delete(selected.values, *i);
+	}
+	if (settings.highlightDupl.enabled && IsDuplicated(*i)) {
+	    checkForDupl = true;
+	}
+    }
+
+    if (checkForDupl) {
+	GetDuplicates();
+    }
+
+    return selected.values->n_values;
+}
+
+/**
+   \brief Get PseudoDC vertex id of selected line
+
+   Set bounding box for vertices of line.
+
+   \param[in] x,y coordinates of click
+   \param[in] thresh threshold value
+
+   \return id of center, left and right vertex
+
+   \return 0 no line found
+   \return -1 on error
+*/
+std::vector<int> DisplayDriver::GetSelectedVertex(double x, double y, double thresh)
+{
+    int startId;
+    int line, type;
+    int Gid, DCid;
+    double vx, vy, vz;      // vertex screen coordinates
+
+    double dist, minDist;
+
+    std::vector<int> returnId;
+
+    // only one object can be selected
+    if (selected.values->n_values != 1 || !drawSegments) 
+	return returnId;
+
+    startId = 1;
+    line = selected.values->value[0];
+
+    type = Vect_read_line (mapInfo, points, cats, line);
+
+    minDist = 0.0;
+    Gid = -1;
+    // find the closest vertex (x, y)
+    DCid = 1;
+    for(int idx = 0; idx < points->n_points; idx++) {
+	dist = Vect_points_distance(x, y, 0.0,
+				    points->x[idx], points->y[idx], points->z[idx], 0);
+	
+	if (idx == 0) {
+	    minDist = dist;
+	    Gid  = idx;
+	}
+	else {
+	    if (minDist > dist) {
+		minDist = dist;
+		Gid = idx;
+	    }
+	}
+
+	Cell2Pixel(points->x[idx], points->y[idx], points->z[idx],
+		   &vx, &vy, &vz);
+	wxRect rect (wxPoint ((int) vx, (int) vy), wxPoint ((int) vx, (int) vy));
+	dc->SetIdBounds(DCid, rect);
+	DCid+=2;
+    }	
+
+    if (minDist > thresh)
+	return returnId;
+
+    // desc = &(ids[line]);
+
+    // translate id
+    DCid = Gid * 2 + 1;
+
+    // add selected vertex
+    returnId.push_back(DCid);
+    // left vertex
+    if (DCid == startId) {
+	returnId.push_back(-1);
+    }
+    else {
+	returnId.push_back(DCid - 2);
+    }
+
+    // right vertex
+    if (DCid == (points->n_points - 1) * 2 + startId) {
+	returnId.push_back(-1);
+    }
+    else {
+	returnId.push_back(DCid + 2);
+    }
+
+    return returnId;
+}
+
+/*!
+  \brief Get minimal region extent of selected features
+
+  \return n,s,w,e
+*/
+std::vector<int> DisplayDriver::GetRegionSelected()
+{
+    std::vector<int> region;
+
+    BOUND_BOX region_box, line_box;
+    struct ilist *list, *list_tmp;
+
+    list = list_tmp = NULL;
+
+    G_zero(&region_box, sizeof(region_box));
+    
+    if (!selected.isId) { /* -> cats */
+	list = Vect_new_list();
+	list_tmp = Vect_new_list();
+	/* can't use here
+	 *
+	  Vect_cidx_find_all(mapInfo, 1, GV_POINTS | GV_LINES,
+	  selected.values->value[i],
+	  list_tmp);
+	*/
+	int type;
+	bool found;
+	for (int line = 1; line < Vect_get_num_lines(mapInfo); line++) {
+	    type = Vect_read_line (mapInfo, NULL, cats, line);
+	    if (!(type & (GV_POINTS | GV_LINES)))
+		continue;
+	    
+	    found = false;
+	    for (int i = 0; i < cats->n_cats && !found; i++) {
+		for (int j = 0; j < selected.values->n_values && !found; j++) {
+		    if (cats->cat[i] == selected.values->value[j])
+			found = true;
+		}
+	    }
+	    if (found)
+		Vect_list_append(list, line);
+	}
+    }
+    else {
+	list = selected.values;
+    }
+    
+    for (int i = 0; i < list->n_values; i++) {
+	if (!Vect_get_line_box(mapInfo, list->value[i], &line_box))
+	    continue;
+
+	if (i == 0) {
+	    Vect_box_copy(&region_box, &line_box);
+	}
+	else {
+	    Vect_box_extend(&region_box, &line_box);
+	}
+    }
+
+    if (list && list != selected.values) {
+	Vect_destroy_list(list);
+    }
+    if (list_tmp)
+	Vect_destroy_list(list_tmp);
+	
+    region.push_back(region_box.N);
+    region.push_back(region_box.S);
+    region.push_back(region_box.W);
+    region.push_back(region_box.E);
+
+    return region;
+}



More information about the grass-commit mailing list