[GRASS-SVN] r31527 - in grass/trunk/gui/wxpython: gui_modules vdigit
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon May 26 05:34:06 EDT 2008
Author: martinl
Date: 2008-05-26 05:34:05 -0400 (Mon, 26 May 2008)
New Revision: 31527
Modified:
grass/trunk/gui/wxpython/gui_modules/mapdisp.py
grass/trunk/gui/wxpython/gui_modules/preferences.py
grass/trunk/gui/wxpython/gui_modules/vdigit.py
grass/trunk/gui/wxpython/vdigit/cats.cpp
grass/trunk/gui/wxpython/vdigit/driver.cpp
grass/trunk/gui/wxpython/vdigit/driver.h
Log:
wxGUI/vdigit: check for duplicates functionality implemented (merge from devbr6, r31526)
Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2008-05-26 09:12:05 UTC (rev 31526)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2008-05-26 09:34:05 UTC (rev 31527)
@@ -62,6 +62,7 @@
import gdialogs
from vdigit import VDigitCategoryDialog as VDigitCategoryDialog
from vdigit import VDigitZBulkDialog as VDigitZBulkDialog
+from vdigit import VDigitDuplicatesDialog as VDigitDuplicatesDialog
from vdigit import GV_LINES as VDigit_Lines_Type
from debug import Debug as Debug
from icon import Icons as Icons
@@ -1384,6 +1385,25 @@
if len(self.moveIds) == 0: # no vertex found
digitClass.driver.SetSelected([])
+
+ #
+ # check for duplicates
+ #
+ if UserSettings.Get(group='vdigit', key='checkForDupl', subkey='enabled') is True:
+ dupl = digitClass.driver.GetDuplicates()
+ self.UpdateMap(render=False)
+
+ if dupl:
+ posWindow = self.ClientToScreen((self.mouse['end'][0] + self.dialogOffset,
+ self.mouse['end'][1] + self.dialogOffset))
+
+ dlg = VDigitDuplicatesDialog(parent=self, data=dupl, pos=posWindow)
+
+ if dlg.ShowModal() == wx.ID_OK:
+ digitClass.driver.UnSelect(dlg.GetUnSelected())
+ # update selected
+ self.UpdateMap(render=False)
+
if digitToolbar.action != "editLine":
# -> move line || move vertex
self.UpdateMap(render=False)
Modified: grass/trunk/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/preferences.py 2008-05-26 09:12:05 UTC (rev 31526)
+++ grass/trunk/gui/wxpython/gui_modules/preferences.py 2008-05-26 09:34:05 UTC (rev 31527)
@@ -110,7 +110,8 @@
#
'vdigit' : {
# symbology
- 'symbolHighlight' : { 'enabled' : None, 'color' : (255, 255, 0, 255) }, #yellow
+ 'symbolHighlight' : { 'enabled' : None, 'color' : (255, 255, 0, 255) }, # yellow
+ 'symbolHighlightDupl' : { 'enabled' : None, 'color' : (255, 72, 0, 255) }, # red
'symbolPoint' : { 'enabled' : True, 'color' : (0, 0, 0, 255) }, # black
'symbolLine' : { 'enabled' : True, 'color' : (0, 0, 0, 255) }, # black
'symbolBoundaryNo' : { 'enabled' : True, 'color' : (126, 126, 126, 255) }, # grey
@@ -145,6 +146,7 @@
'selectFeatureCentroid' : { 'enabled' : True },
'selectFeatureBoundary' : { 'enabled' : True },
'selectThresh' : { 'value' : 10, 'units' : 'screen pixels'},
+ 'checkForDupl' : { 'enabled' : False },
# exit
'saveOnExit' : { 'enabled' : False },
},
Modified: grass/trunk/gui/wxpython/gui_modules/vdigit.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/vdigit.py 2008-05-26 09:12:05 UTC (rev 31526)
+++ grass/trunk/gui/wxpython/gui_modules/vdigit.py 2008-05-26 09:34:05 UTC (rev 31527)
@@ -10,6 +10,7 @@
* VDigitSettingsDialog
* VDigitCategoryDialog
* VDigitZBulkDialog
+ * VDigitDuplicatesDialog
PURPOSE: Vector digitization tool for wxPython GUI
@@ -1341,9 +1342,10 @@
nselected = self.__display.SelectLinesByBox(x1, y1, -1.0 * wxvdigit.PORT_DOUBLE_MAX,
x2, y2, wxvdigit.PORT_DOUBLE_MAX,
type)
+
Debug.msg(4, "CDisplayDriver.SelectLinesByBox(): selected=%d" % \
nselected)
-
+
return nselected
def SelectLineByPoint(self, point, type=0):
@@ -1381,6 +1383,37 @@
return selected
+ def GetDuplicates(self):
+ """Return ids of (selected) duplicated vector features
+ """
+ # -> id : (list of ids)
+ dupl = dict(self.__display.GetDuplicates())
+
+ vdigitComp = UserSettings.Get(group='advanced', key='digitInterface', subkey='type')
+
+ # -> id : ((id, cat), ...)
+ dupl_full = {}
+ for key in dupl.keys():
+ dupl_full[key] = []
+ for id in dupl[key]:
+ catStr = ''
+
+ # categories not supported for v.edit !
+ if vdigitComp == 'vdigit':
+ cats = self.parent.GetLineCats(line=id)
+
+ for layer in cats.keys():
+ if len(cats[layer]) > 0:
+ catStr = "%d: (" % layer
+ for cat in cats[layer]:
+ catStr += "%d," % cat
+ catStr = catStr.rstrip(',')
+ catStr += ')'
+
+ dupl_full[key].append([id, catStr])
+
+ return dupl_full
+
def GetSelectedVertex(self, coords):
"""Get PseudoDC id(s) of vertex (of selected line)
on position 'coords'
@@ -1406,6 +1439,17 @@
self.__display.SetSelected(id)
+ def UnSelect(self, id):
+ """Unselect vector features
+
+ @param id list of feature id(s)
+ """
+
+ Debug.msg(4, "CDisplayDriver.UnSelect(): id=%s" % \
+ ",".join(["%d" % v for v in id]))
+
+ self.__display.UnSelect(id)
+
def UpdateRegion(self):
"""Set geographical region
@@ -1443,6 +1487,11 @@
UserSettings.Get(group='vdigit', key='symbolHighlight', subkey='color')[1],
UserSettings.Get(group='vdigit', key='symbolHighlight', subkey='color')[2],
255).GetRGB(),
+ UserSettings.Get(group='vdigit', key='checkForDupl', subkey='enabled'),
+ wx.Color(UserSettings.Get(group='vdigit', key='symbolHighlightDupl', subkey='color')[0],
+ UserSettings.Get(group='vdigit', key='symbolHighlightDupl', subkey='color')[1],
+ UserSettings.Get(group='vdigit', key='symbolHighlightDupl', subkey='color')[2],
+ 255).GetRGB(),
UserSettings.Get(group='vdigit', key='symbolPoint', subkey='enabled'),
wx.Color(UserSettings.Get(group='vdigit', key='symbolPoint', subkey='color')[0],
UserSettings.Get(group='vdigit', key='symbolPoint', subkey='color')[1],
@@ -1693,6 +1742,12 @@
flexSizer.Add(self.selectThreshValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
flexSizer.Add(units, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
border=10)
+
+ self.checkForDupl = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+ label=_("Check for duplicates"))
+ self.checkForDupl.SetValue(UserSettings.Get(group='vdigit', key="checkForDupl", subkey='enabled'))
+ flexSizer.Add(item=self.checkForDupl, proportion=0, flag=wx.EXPAND)
+
sizer.Add(item=flexSizer, proportion=0, flag=wx.EXPAND)
border.Add(item=sizer, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
@@ -1887,6 +1942,7 @@
return (
# ("Background", "symbolBackground"),
(_("Highlight"), "symbolHighlight"),
+ (_("Highlight (duplicates)"), "symbolHighlightDupl"),
(_("Point"), "symbolPoint"),
(_("Line"), "symbolLine"),
(_("Boundary (no area)"), "symbolBoundaryNo"),
@@ -2070,6 +2126,8 @@
value=self.FindWindowById(self.selectFeature[feature]).IsChecked())
UserSettings.Set(group='vdigit', key="selectThresh", subkey='value',
value=int(self.selectThreshValue.GetValue()))
+ UserSettings.Set(group='vdigit', key="checkForDupl", subkey='enabled',
+ value=self.checkForDupl.IsChecked())
# on-exit
UserSettings.Set(group='vdigit', key="saveOnExit", subkey='enabled',
@@ -2614,3 +2672,118 @@
self.SetSizer(mainSizer)
mainSizer.Fit(self)
+
+class VDigitDuplicatesDialog(wx.Dialog):
+ """
+ Show duplicated feature ids
+ """
+ def __init__(self, parent, data, title=_("List of duplicates"),
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ pos=wx.DefaultPosition):
+
+ wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style,
+ pos=pos)
+
+ self.parent = parent # BufferedWindow
+ self.data = data
+ self.winList = []
+
+ # panel = wx.Panel(parent=self, id=wx.ID_ANY)
+
+ # notebook
+ self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
+
+ id = 1
+ for key in self.data.keys():
+ panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
+ self.notebook.AddPage(page=panel, text=" %d " % (id))
+
+ # notebook body
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ win = CheckListFeature(parent=panel, data=list(self.data[key]))
+ self.winList.append(win.GetId())
+
+ border.Add(item=win, proportion=1,
+ flag=wx.ALL | wx.EXPAND, border=5)
+
+ panel.SetSizer(border)
+
+ id += 1
+
+ # buttons
+ btnCancel = wx.Button(self, wx.ID_CANCEL)
+ btnOk = wx.Button(self, wx.ID_OK)
+ btnOk.SetDefault()
+
+ # sizers
+ btnSizer = wx.StdDialogButtonSizer()
+ btnSizer.AddButton(btnCancel)
+ btnSizer.AddButton(btnOk)
+ btnSizer.Realize()
+
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+ mainSizer.Add(item=self.notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
+ mainSizer.Add(item=btnSizer, proportion=0,
+ flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+
+ self.SetSizer(mainSizer)
+ mainSizer.Fit(self)
+ self.SetAutoLayout(True)
+
+ # set min size for dialog
+ self.SetMinSize((250, 180))
+
+ def GetUnSelected(self):
+ """Get unselected items (feature id)
+
+ @return list of ids
+ """
+ ids = []
+ for id in self.winList:
+ wlist = self.FindWindowById(id)
+
+ for item in range(wlist.GetItemCount()):
+ if not wlist.IsChecked(item):
+ ids.append(int(wlist.GetItem(item, 0).GetText()))
+
+ return ids
+
+class CheckListFeature(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin):
+ """List of mapset/owner/group"""
+ def __init__(self, parent, data,
+ pos=wx.DefaultPosition, log=None):
+ self.parent = parent
+ self.data = data
+
+ wx.ListCtrl.__init__(self, parent, wx.ID_ANY,
+ style=wx.LC_REPORT)
+
+ listmix.CheckListCtrlMixin.__init__(self)
+
+ self.log = log
+
+ # setup mixins
+ listmix.ListCtrlAutoWidthMixin.__init__(self)
+
+ self.LoadData(self.data)
+
+ def LoadData(self, data):
+ """Load data into list"""
+ self.InsertColumn(0, _('Feature id'))
+ self.InsertColumn(1, _('Layer (Categories)'))
+
+ for item in data:
+ index = self.InsertStringItem(sys.maxint, str(item[0]))
+ self.SetStringItem(index, 1, str(item[1]))
+
+ # enable all items by default
+ for item in range(self.GetItemCount()):
+ self.CheckItem(item, True)
+
+ self.SetColumnWidth(col=0, width=wx.LIST_AUTOSIZE_USEHEADER)
+ self.SetColumnWidth(col=1, width=wx.LIST_AUTOSIZE_USEHEADER)
+
+ def OnCheckItem(self, index, flag):
+ """Mapset checked/unchecked"""
+ pass
Modified: grass/trunk/gui/wxpython/vdigit/cats.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/cats.cpp 2008-05-26 09:12:05 UTC (rev 31526)
+++ grass/trunk/gui/wxpython/vdigit/cats.cpp 2008-05-26 09:34:05 UTC (rev 31527)
@@ -165,7 +165,7 @@
return lc;
}
- line = -1;
+ line = line_id;
if (line_id == -1) {
line = display->selected->value[0];
}
Modified: grass/trunk/gui/wxpython/vdigit/driver.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.cpp 2008-05-26 09:12:05 UTC (rev 31526)
+++ grass/trunk/gui/wxpython/vdigit/driver.cpp 2008-05-26 09:34:05 UTC (rev 31527)
@@ -40,6 +40,7 @@
cats = Vect_new_cats_struct();
selected = Vect_new_list();
+ selectedDupl = Vect_new_list();
drawSegments = false;
@@ -66,6 +67,7 @@
delete pointsScreen;
Vect_destroy_cats_struct(cats);
Vect_destroy_list(selected);
+ Vect_destroy_list(selectedDupl);
}
/**
@@ -160,7 +162,12 @@
// dcId += points->n_points * 2 - 1;
if (IsSelected(line)) { // line selected ?
- pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+ 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;
dcId = 1;
topology.highlight++;
@@ -307,7 +314,12 @@
dcId = 0;
}
else {
- pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+ 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
}
@@ -378,7 +390,12 @@
// determine color
if (IsSelected(line)) {
- pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+ 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;
@@ -621,6 +638,7 @@
\return
*/
void DisplayDriver::UpdateSettings(unsigned long highlight,
+ bool ehighlightDupl, unsigned long chighlightDupl,
bool ePoint, unsigned long cPoint, /* enabled, color */
bool eLine, unsigned long cLine,
bool eBoundaryNo, unsigned long cBoundaryNo,
@@ -635,6 +653,9 @@
int lineWidth)
{
settings.highlight.Set(highlight);
+
+ settings.highlightDupl.enabled = ehighlightDupl;
+ settings.highlightDupl.color.Set(chighlightDupl);
settings.point.enabled = ePoint;
settings.point.color.Set(cPoint);
@@ -763,24 +784,16 @@
for (int i = 0; i < list->n_values; i++) {
line = list->value[i];
if (!IsSelected(line)) {
- // selected.push_back(line);
Vect_list_append(selected, line);
}
else {
- // selected.erase(GetSelectedIter(line));
Vect_list_delete(selected, line);
}
}
- // remove all duplicate ids
- // sort(selected.begin(), selected.end());
- // selected.erase(unique(selected.begin(), selected.end()), selected.end());
-
Vect_destroy_line_struct(bbox);
Vect_destroy_list(list);
- // return selected.size();
- // return selected->n_values;
return list->n_values;
}
@@ -810,11 +823,9 @@
if (line > 0) {
if (!IsSelected(line)) {
- // selected.push_back(line);
Vect_list_append(selected, line);
}
else {
- // selected.erase(GetSelectedIter(line));
Vect_list_delete(selected, line);
}
@@ -844,7 +855,6 @@
*/
bool DisplayDriver::IsSelected(int line)
{
- // if (GetSelectedIter(line) != selected.end())
if (Vect_val_in_list(selected, line))
return true;
@@ -852,26 +862,6 @@
}
/**
- \brief Is vector object selected?
-
- \param[in] line id
-
- \return item iterator
- \return selected.end() if object is not selected
-*/
-/*
-std::vector<int>::iterator DisplayDriver::GetSelectedIter(int line)
-{
- for(std::vector<int>::iterator i = selected.begin(), e = selected.end();
- i != e; ++i) {
- if (line == *i)
- return i;
- }
-
- return selected.end();
-}
-*/
-/**
\brief Get ids of selected objects
\param[in] grassId if true return GRASS line ids
@@ -898,35 +888,72 @@
}
}
- /*
- for(std::vector<int>::const_iterator i = selected.begin(), e = selected.end();
- i != e; ++i) {
- line = *i;
- ids_map::const_iterator ii = ids.find(line);
- if (ii != ids.end()) { // line found
- long int endId = ii->second.npoints * 2 - 1 + ii->second.startId;
- int type, i;
- int vx, vy, vz;
- type = Vect_read_line (mapInfo, points, cats, line);
- i = 0;
- for (long int id = ii->second.startId; id < endId; id++) {
- dc_ids.push_back(id);
- // set bounding boxes for all selected objects (only nodes)
- if (id % 2) {
- Cell2Pixel(points->x[i], points->y[i], points->z[i],
- &vx, &vy, &vz);
- wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
- dc->SetIdBounds(id, rect);
+ return dc_ids;
+}
- i++;
+/**
+ \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(selectedDupl);
+
+ for (int i = 0; i < selected->n_values; i++) {
+ line = selected->value[i];
+ if (IsDuplicated(line))
+ continue;
+
+ Vect_read_line(mapInfo, APoints, NULL, line);
+
+ for (int j = 0; j < selected->n_values; j++) {
+ if (i == j || IsDuplicated(selected->value[j]))
+ continue;
+
+ Vect_read_line(mapInfo, BPoints, NULL, selected->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->value[i]);
+ Vect_list_append(selectedDupl, selected->value[i]);
}
-
+ ids[i].push_back(selected->value[j]);
+ Vect_list_append(selectedDupl, selected->value[j]);
}
}
}
- */
+
+ Vect_destroy_line_struct(APoints);
+ Vect_destroy_line_struct(BPoints);
+
+ return ids;
+}
- return dc_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(selectedDupl, line))
+ return true;
+
+ return false;
}
/**
@@ -938,7 +965,6 @@
*/
int DisplayDriver::SetSelected(std::vector<int> id)
{
- // selected = id;
VectorToList(selected, id);
if (selected->n_values <= 0)
@@ -948,6 +974,36 @@
}
/**
+ \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, *i);
+ }
+ if (settings.highlightDupl.enabled && IsDuplicated(*i)) {
+ checkForDupl = true;
+ }
+ }
+
+ if (checkForDupl) {
+ GetDuplicates();
+ }
+
+ return selected->n_values;
+}
+
+/**
\brief Get PseudoDC vertex id of selected line
Set bounding box for vertices of line.
@@ -1149,4 +1205,3 @@
return 0;
}
-
Modified: grass/trunk/gui/wxpython/vdigit/driver.h
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.h 2008-05-26 09:12:05 UTC (rev 31526)
+++ grass/trunk/gui/wxpython/vdigit/driver.h 2008-05-26 09:34:05 UTC (rev 31527)
@@ -3,6 +3,7 @@
#include <iostream> // debug
#include <vector>
+#include <map>
#include <cmath>
// For compilers that support precompilation, includes "wx.h".
@@ -54,9 +55,8 @@
ids_map ids; // gId : {dcIds, ...}
*/
- // list of selected features (gId)
- // std::vector<int> selected;
struct ilist *selected;
+ struct ilist *selectedDupl;
bool drawSegments; // draw segments of selected line
@@ -88,6 +88,7 @@
struct _settings {
wxColor highlight;
+ symbol highlightDupl;
symbol point;
symbol line;
@@ -128,21 +129,22 @@
long int vertex;
} topology;
- void Cell2Pixel (double east, double north, double depth,
- double *x, double *y, double *z);
+ void Cell2Pixel (double, double, double,
+ double *, double *, double *);
- int DrawCross(int line, const wxPoint *point, int size=5);
+ int DrawCross(int, const wxPoint *, int size=5);
- int DrawLine(int line);
- int DrawLineVerteces(int line);
- int DrawLineNodes(int line);
+ int DrawLine(int);
+ int DrawLineVerteces(int);
+ int DrawLineNodes(int);
/* debug */
void PrintIds();
/* select feature */
- bool IsSelected(int line);
- // std::vector<int>::iterator GetSelectedIter(int line);
+ bool IsSelected(int);
+ bool IsDuplicated(int);
+
std::vector<int> ListToVector(struct ilist *);
int VectorToList(struct ilist *, const std::vector<int>&);
@@ -163,7 +165,9 @@
double, int, int);
std::vector<int> GetSelected(bool);
+ std::map<int, std::vector <int> > GetDuplicates();
int SetSelected(std::vector<int>);
+ int UnSelect(std::vector<int>);
std::vector<int> GetSelectedVertex(double, double, double);
/* general */
@@ -182,6 +186,7 @@
double, double);
void UpdateSettings(unsigned long,
+ bool, unsigned long,
bool, unsigned long, /* enabled, color */
bool, unsigned long,
bool, unsigned long,
More information about the grass-commit
mailing list