[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, ®ion.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(®ion_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(®ion_box, &line_box);
- }
- else {
- Vect_box_extend(®ion_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, ®ion.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(®ion_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(®ion_box, &line_box);
+ }
+ else {
+ Vect_box_extend(®ion_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