Ver código fonte

wxGUI/vdigit: visualize line directions implemented, trac https://trac.osgeo.org/grass/ticket/209

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@31996 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa 17 anos atrás
pai
commit
6e9b1914dc

+ 2 - 1
gui/wxpython/gui_modules/preferences.py

@@ -125,6 +125,7 @@ class Settings:
                 'symbolNodeOne'     : { 'enabled' : True,  'color' : (255, 0, 0, 255) }, # red
                 'symbolNodeOne'     : { 'enabled' : True,  'color' : (255, 0, 0, 255) }, # red
                 'symbolNodeTwo'     : { 'enabled' : True,  'color' : (0, 86, 45, 255) }, # dark green
                 'symbolNodeTwo'     : { 'enabled' : True,  'color' : (0, 86, 45, 255) }, # dark green
                 'symbolVertex'      : { 'enabled' : False, 'color' : (255, 20, 147, 255) }, # deep pink
                 'symbolVertex'      : { 'enabled' : False, 'color' : (255, 20, 147, 255) }, # deep pink
+                'symbolDirection'   : { 'enabled' : False, 'color' : (255, 0, 0, 255) }, # red
                 # display
                 # display
                 'lineWidth' : { 'value' : 2, 'units' : 'screen pixels' },
                 'lineWidth' : { 'value' : 2, 'units' : 'screen pixels' },
                 # snapping
                 # snapping
@@ -327,7 +328,7 @@ class Settings:
         
         
         if self.filePath:
         if self.filePath:
             self.__ReadFile(self.filePath, settings)
             self.__ReadFile(self.filePath, settings)
-            
+        
     def __ReadFile(self, filename, settings=None):
     def __ReadFile(self, filename, settings=None):
         """Read settings from file to dict"""
         """Read settings from file to dict"""
         if settings is None:
         if settings is None:

+ 7 - 1
gui/wxpython/gui_modules/vdigit.py

@@ -1563,6 +1563,11 @@ class CDisplayDriver(AbstractDisplayDriver):
                                                 UserSettings.Get(group='vdigit', key='symbolVertex', subkey='color')[1],
                                                 UserSettings.Get(group='vdigit', key='symbolVertex', subkey='color')[1],
                                                 UserSettings.Get(group='vdigit', key='symbolVertex', subkey='color')[2],
                                                 UserSettings.Get(group='vdigit', key='symbolVertex', subkey='color')[2],
                                                 255).GetRGB(),
                                                 255).GetRGB(),
+                                       UserSettings.Get(group='vdigit', key='symbolDirection', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolDirection', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolDirection', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolDirection', subkey='color')[2],
+                                                255).GetRGB(),
                                        UserSettings.Get(group='vdigit', key='lineWidth', subkey='value'))
                                        UserSettings.Get(group='vdigit', key='lineWidth', subkey='value'))
 
 
 class VDigitSettingsDialog(wx.Dialog):
 class VDigitSettingsDialog(wx.Dialog):
@@ -1969,7 +1974,8 @@ class VDigitSettingsDialog(wx.Dialog):
             (_("Centroid (duplicate in area)"), "symbolCentroidDup"),
             (_("Centroid (duplicate in area)"), "symbolCentroidDup"),
             (_("Node (one line)"), "symbolNodeOne"),
             (_("Node (one line)"), "symbolNodeOne"),
             (_("Node (two lines)"), "symbolNodeTwo"),
             (_("Node (two lines)"), "symbolNodeTwo"),
-            (_("Vertex"), "symbolVertex"))
+            (_("Vertex"), "symbolVertex"),
+            (_("Direction"), "symbolDirection"),)
 
 
     def OnChangeCategoryMode(self, event):
     def OnChangeCategoryMode(self, event):
         """Change category mode"""
         """Change category mode"""

+ 3 - 3
gui/wxpython/vdigit/digit.h

@@ -1,5 +1,5 @@
-#ifndef __DIGIT_H__
-#define __DIGIT_H__
+#ifndef WXVDIGIT_DIGIT_H
+#define WXVDIGIT_DIGIT_H
 
 
 #define GSQL_MAX 4000
 #define GSQL_MAX 4000
 
 
@@ -83,5 +83,5 @@ public:
     int GetUndoLevel();
     int GetUndoLevel();
 };
 };
 
 
-#endif /* __DIGIT_H__ */
+#endif /* WXVDIGIT_DIGIT_H */
 
 

+ 145 - 9
gui/wxpython/vdigit/driver.cpp

@@ -6,16 +6,18 @@
    This driver is designed for wxPython GRASS GUI (digitization tool).
    This driver is designed for wxPython GRASS GUI (digitization tool).
    Draw vector map layer to PseudoDC.
    Draw vector map layer to PseudoDC.
 
 
+   (C) by the GRASS Development Team
    This program is free software under the GNU General Public
    This program is free software under the GNU General Public
    License (>=v2). Read the file COPYING that comes with GRASS
    License (>=v2). Read the file COPYING that comes with GRASS
    for details.
    for details.
 
 
-   \author (C) by the GRASS Development Team
-   Martin Landa <landa.martin gmail.com>
+   \author Martin Landa <landa.martin gmail.com>
 
 
    \date 2007-2008 
    \date 2007-2008 
 */
 */
 
 
+#include <cmath>
+
 #include "driver.h"
 #include "driver.h"
 
 
 /**
 /**
@@ -274,12 +276,18 @@ int DisplayDriver::DrawLine(int line)
 		}
 		}
 	    }
 	    }
 	    else {
 	    else {
-		wxPoint points[pointsScreen->GetCount()];
+		wxPoint wxPoints[pointsScreen->GetCount()];
 		for (size_t i = 0; i < pointsScreen->GetCount(); i++) {
 		for (size_t i = 0; i < pointsScreen->GetCount(); i++) {
 		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
 		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
-		    points[i] = *point_beg;
+		    wxPoints[i] = *point_beg;
+		}
+		dc->DrawLines(pointsScreen->GetCount(), wxPoints);
+
+		if (!IsSelected(line) && settings.direction.enabled) {
+		    DrawDirectionArrow();
+		    // restore pen
+		    dc->SetPen(*pen);
 		}
 		}
-		dc->DrawLines(pointsScreen->GetCount(), points);
 	    }
 	    }
 	}
 	}
     }
     }
@@ -572,15 +580,33 @@ void DisplayDriver::Cell2Pixel(double east, double north, double depth,
     *x = int((east  - w) / region.map_res);
     *x = int((east  - w) / region.map_res);
     *y = int((n - north) / region.map_res);
     *y = int((n - north) / region.map_res);
     */
     */
-    *x = (east  - w) / region.map_res;
-    *y = (n - north) / region.map_res;
-
-    *z = 0;
+    if (x)
+	*x = (east  - w) / region.map_res;
+    if (y)
+	*y = (n - north) / region.map_res;
+    if (z)
+	*z = 0.;
 
 
     return;
     return;
 }
 }
 
 
 /**
 /**
+   \brief Calculate distance in pixels
+
+   \todo LL projection
+
+   \param dist real distance
+*/
+double DisplayDriver::DistanceInPixels(double dist)
+{
+    double x;
+    
+    Cell2Pixel(region.map_west + dist, region.map_north, 0.0, &x, NULL, NULL);
+
+    return std::sqrt(x * x);
+}
+
+/**
    \brief Set geographical region
    \brief Set geographical region
  
  
    Region must be upgraded because of Cell2Pixel().
    Region must be upgraded because of Cell2Pixel().
@@ -661,6 +687,7 @@ void DisplayDriver::UpdateSettings(unsigned long highlight,
 				   bool eNodeOne,     unsigned long cNodeOne,
 				   bool eNodeOne,     unsigned long cNodeOne,
 				   bool eNodeTwo,     unsigned long cNodeTwo,
 				   bool eNodeTwo,     unsigned long cNodeTwo,
 				   bool eVertex,      unsigned long cVertex,
 				   bool eVertex,      unsigned long cVertex,
+				   bool eDirection,   unsigned long cDirection,
 				   int lineWidth)
 				   int lineWidth)
 {
 {
     settings.highlight.Set(highlight);
     settings.highlight.Set(highlight);
@@ -697,6 +724,9 @@ void DisplayDriver::UpdateSettings(unsigned long highlight,
     settings.vertex.enabled = eVertex;
     settings.vertex.enabled = eVertex;
     settings.vertex.color.Set(cVertex);
     settings.vertex.color.Set(cVertex);
 
 
+    settings.direction.enabled = eDirection;
+    settings.direction.color.Set(cDirection);
+
     settings.lineWidth = lineWidth;
     settings.lineWidth = lineWidth;
 }
 }
 
 
@@ -1233,3 +1263,109 @@ void DisplayDriver::DrawSelected(bool draw)
 
 
     return;
     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;
+}

+ 11 - 4
gui/wxpython/vdigit/driver.h

@@ -1,5 +1,5 @@
-#ifndef __DRIVER_H__
-#define __DRIVER_H__
+#ifndef WXVDIGIT_DRIVER_H
+#define WXVDIGIT_DRIVER_H
 
 
 #include <iostream> // debug
 #include <iostream> // debug
 #include <vector>
 #include <vector>
@@ -107,6 +107,8 @@ private:
 
 
 	symbol vertex;
 	symbol vertex;
 
 
+	symbol direction;
+
 	int lineWidth;    // screen units 
 	int lineWidth;    // screen units 
     } settings;
     } settings;
 
 
@@ -132,12 +134,16 @@ private:
 
 
     void Cell2Pixel (double, double, double,
     void Cell2Pixel (double, double, double,
 		     double *, double *, double *);
 		     double *, double *, double *);
-    
+    double DistanceInPixels(double);
+
     int DrawCross(int, const wxPoint *, int size=5);
     int DrawCross(int, const wxPoint *, int size=5);
+    int DrawArrow(double, double, double, double, double,
+		   int);
 
 
     int DrawLine(int);
     int DrawLine(int);
     int DrawLineVerteces(int);
     int DrawLineVerteces(int);
     int DrawLineNodes(int);
     int DrawLineNodes(int);
+    int DrawDirectionArrow();
 
 
     /* debug */
     /* debug */
     void PrintIds();
     void PrintIds();
@@ -200,9 +206,10 @@ public:
 			bool, unsigned long,
 			bool, unsigned long,
 			bool, unsigned long,
 			bool, unsigned long,
 			bool, unsigned long,
 			bool, unsigned long,
+			bool, unsigned long,
 			int);
 			int);
 };
 };
 
 
 int print_error(const char *, int);
 int print_error(const char *, int);
 
 
-#endif /* __DRIVER_H__ */
+#endif /* WXVDIGIT_DRIVER_H */