
    ը	f                    P   d Z ddlmZ ddlZddlmc mZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZmZ 	 e 	 dd	l dd	l dd	l dd	l  G d d      Z! G d d      Z"y# e$ r eZY 3w xY w# eeef$ r-Z ed
j=                  e      ej@                         Y dZ[RdZ[ww xY w)a  
@package vdigit.wxdigit

@brief wxGUI vector digitizer (base class)

Code based on wxVdigit C++ component from GRASS 6.4.0
(gui/wxpython/vdigit). Converted to Python in 2010/12-2011/01.

List of classes:
 - wxdigit::VDigitError
 - wxdigit::IVDigit

.. todo::
    Read large amounts of data from Vlib into arrays, which could
    then be processed using NumPy and rendered using glDrawArrays or
    glDrawElements, so no per-line/per-vertex processing in Python. Bulk
    data processing with NumPy is much faster than iterating in Python
    (and NumPy would be an excellent candidate for acceleration via
    e.g. OpenCL or CUDA; I'm surprised it hasn't happened already).

(C) 2007-2016 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>
    )print_functionN)Signal)GError)Debug)UserSettings)DisplayDriverGetLastError)*zwxdigit.py: {})filec                   J    e Zd Zd ZddZd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zy)VDigitErrorc                 2    || _         t        d      | _        y)zpClass for managing error messages of vector digitizer

        :param parent: parent window for dialogs
        zDigitization ErrorN)parent_caption)selfr   s     //usr/lib/grass83/gui/wxpython/vdigit/wxdigit.py__init__zVDigitError.__init__7   s    
 -.    Nc                     |rt        d      |z  }nt        d      }t        |dz   t        d      z   | j                  | j                         y)zNo map for editingzUnable to open vector map <%s>.zNo vector map open for editing. zOperation canceled.)r   r   N)r   r   r   r   )r   namemessages      r   NoMapzVDigitError.NoMap?   sH    9:TAG9:GcMA344;;LL	
r   c                 p    t        t        d      t               z  | j                  | j                         y)zWriting line failedz;Writing new feature failed. Operation canceled.

Reason: %sr   r   r   N)r   r   r	   r   r   r   s    r   	WriteLinezVDigitError.WriteLineK   s1    U n ;;LL	
r   c                 `    t        t        d      |z  | j                  | j                         y)zReading line failedz1Reading feature id %d failed. Operation canceled.r   Nr   r   r   r   r   lines     r   ReadLinezVDigitError.ReadLineV   s'    LMPTT;;LL	
r   c                 `    t        t        d      |z  | j                  | j                         y)zNo dblink availablez3Database link %d not available. Operation canceled.r   Nr    )r   dblinks     r   DbLinkzVDigitError.DbLink^   s)    NO;;LL		
r   c                 `    t        t        d      |z  | j                  | j                         y)zStaring driver failedz9Unable to start database driver <%s>. Operation canceled.r   Nr    )r   drivers     r   DriverzVDigitError.Driverg   s)    TU;;LL		
r   c                 f    t        t        d      ||dz  | j                  | j                         y)zOpening database failedzLUnable to open database <%(db)s> by driver <%(driver)s>. Operation canceled.)dbr(   r   Nr    )r   r(   databases      r   DatabasezVDigitError.Databasep   s6    & 0	1
 ;;LL	
r   c                 `    t        t        d      |z  | j                  | j                         y)zSql query failedz5Unable to execute SQL query '%s'. Operation canceled.r   Nr    )r   sqls     r   	DbExecutezVDigitError.DbExecute|   s'    PQTWW;;LL	
r   c                 `    t        t        d      |z  | j                  | j                         y)z	Dead linez4Feature id %d is marked as dead. Operation canceled.r   Nr    r!   s     r   DeadLinezVDigitError.DeadLine   s'    OPSWW;;LL	
r   c                 `    t        t        d      |z  | j                  | j                         y)zUnknown feature typez0Unsupported feature type %d. Operation canceled.r   Nr    )r   ftypes     r   FeatureTypezVDigitError.FeatureType   s&    KLuT;;LL	
r   )N)__name__
__module____qualname__r   r   r   r#   r&   r)   r-   r0   r2   r5    r   r   r   r   6   s4    /

	








r   r   c                      e Zd ZefdZd Zd Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d  Z#d! Z$d" Z%g fd#Z&d?d$Z'd% Z(d& Z)d' Z*d( Z+d) Z,d* Z-d@d+Z.d, Z/dAd-Z0d. Z1d/ Z2dBd0Z3d1 Z4d2 Z5d3 Z6d4 Z7d@d5Z8d6 Z9d7 Z:d8 Z;d9 Z<d: Z=d; Z>d< Z?d= Z@y>)CIVDigitc                    d| _         || _        || _        t               | _        dx| _        | _        	 | j                  j                         }| j                  j                  d      }|j                  j                  d   | _        t        | j                        | _         ||j                  |j                   |j"                  |||      | _        t'               | _        t+               | _        t/               | _        t/               | _        | j5                          t7               | _        d| _        | j                   r| j=                          d| _        tA        d	      | _!        tA        d
      | _"        tA        d      | _#        tA        d      | _$        tA        d      | _%        tA        d      | _&        tA        d      | _'        tA        d      | _(        y# t        $ r d}Y w xY w)zpBase class for vector digitizer (ctypes interface)

        :param mapwindow: reference to a map window
        NT)errvdigit)r   )device	deviceTmpmapObjwindowglog	gprogressFzIVDigit.featureAddedzIVDigit.areasDeletedzIVDigit.vertexMovedzIVDigit.vertexAddedzIVDigit.vertexRemovedzIVDigit.featuresDeletedzIVDigit.featuresMovedzIVDigit.lineEdited))	poMapInfo	mapWindow_gifaceMap_info	bgMapInfopoBgMapInfopopoBgMapInfoGetProgressNotImplementedErrorGetLogr   toolbarstoolbarr   _error	pdcVectorpdcTmpMap_displayVect_new_line_structpoPointsVect_new_cats_structpoCatsdictcats	_settingsUpdateSettingslist
changesetschangesetCurrentInitCatsemit_signalsr   featureAddedareasDeletedvertexMovedvertexAddedvertexRemovedfeaturesDeletedfeaturesMoved
lineEdited)r   giface	mapwindowr(   progresslogs         r   r   zIVDigit.__init__   s   
 " "0444-	||//1H ll!!d!+ ''00:!8&&&&==
 -.*,
 F	 & ">>MMO!4 ##9:"#9:!"78!"78#$;<%&?@#$;< !56I # 	H	s   G G)(G)c                    t        j                  dd       t        | j                         d | _        t	        | j
                         d | _        | j                  r&t        | j                         d x| _        | _        | `	y y )N   zIVDigit.__del__())
r   msgVect_destroy_line_structrX   Vect_destroy_cats_structrZ   rK   
Vect_closerL   rJ   r   s    r   __del__zIVDigit.__del__   sh    		!() / -t''(488Dt1 r   c                     || _         y)zQActivate/deactivate signals which describes features changes during digitization.N)rc   )r   emits     r   EmitSignalszIVDigit.EmitSignals   s
     r   c                 d    | j                   syt        | j                          dx| _         | _        y)zClose background vector mapN)rK   ru   rL   r   s    r   CloseBackgroundMapzIVDigit.CloseBackgroundMap   s,    4##$0444-r   c                    t        t              }t        t              }t        |||      s"|}t	        j
                  t        |d            }n>t	        j
                  |j                        }t	        j
                  |j                        }|t        | j                        k(  rB|t        | j                        k(  r*dx| _        | _        | j                  j                  |       yt        | j                         | _        t        | j                        | _        t#        | j                  ||      dk(  r*dx| _        | _        | j                  j                  |       yy)a  Open background vector map

        .. todo::
            support more background maps then only one

        :param bgmap: name of vector map to be opened
        :type bgmap: str

        :return: pointer to map_info
        :return: None on error
         NrE   )create_string_buffer	GNAME_MAXGMAPSET_MAXG_name_is_fully_qualifiedgrassdecodeG_find_vector2valueVect_get_namerF   Vect_get_mapsetrK   rL   rR   r   pointerrJ   Vect_open_old)r   bgmapr   mapsets       r   OpenBackgroundMapzIVDigit.OpenBackgroundMap  s    $I.%k2(f=D\\.";<F<<

+D\\&,,/F=00VNN@
 6
 598Dt1KKe$"4>>2$T%5%56))48B>488Dt1KKe$ ?r   c                     | j                   j                         }|dkD  r$t        j                  ddd      rt        S t
        S t        S )zGet snapping mode

         - snap to vertex
         - snap to nodes
         - no snapping

        :return: snap mode
                r>   snapToVertexenabledgroupkeysubkey)rV   GetThresholdr   Get
SNAPVERTEXSNAPNO_SNAP)r   	thresholds     r   _getSnapModezIVDigit._getSnapMode$  s?     MM..0	s?hN9U!!Nr   c                 t    t        j                  ddd      dk(  rd}|S t        j                  ddd      }|S )	z,Returns layer of new feature (from settings)r>   categoryMode	selectionr      rE   layerr   r   r   )r   r   s     r   _getNewFeaturesLayerzIVDigit._getNewFeaturesLayer6  sG     8T E  !$$8QEr   c                 d    t        j                  ddd      dk(  rd}|S | j                         }|S )z/Returns category of new feature (from settings)r>   r   r   r   r   rE   )r   r   SetCategory)r   cats     r   _getNewFeaturesCatzIVDigit._getNewFeaturesCatB  sA     8T C 
 ""$C
r   c                    | j                         syt        | j                  |      sy|sNt        | j                  | j                  d|      dk  r| j
                  j                  |       y| j                  }n|}t        d      }t               }t               }t               }t               }t        | j                  |t        |             t        | j                  t        |      t        |       t        ||       t        ||       t!        |j"                  j$                        D ]k  }	|j"                  j&                  |	   }
|
|k(  r"t        | j                  |d|
      }|t        z  sDt)        | j                  |t*              s`t        ||
       m t-        | j                  ||t        d      }t/        |       t1        |       t3        |       t3        |       |S )zBreak given line at intersection

        :param line: line id
        :param pointsLine: line geometry

        :return: number of modified lines
        rE   r   N)	_checkMapVect_line_aliverF   Vect_read_linerX   rR   r#   Vect_new_boxlistVect_new_listrW   	bound_boxVect_get_line_boxbyrefVect_select_lines_by_boxGV_LINESVect_list_appendrangecontentsn_valuesidVect_line_check_intersection	WITHOUT_ZVect_break_lines_listrs   Vect_destroy_boxlistVect_destroy_list)r   r"   
pointsLinepointslistLinelistRef	listBreakpointsChecklineBoxi	lineBreakltyperets                r   _breakLineAtIntersectionz IVDigit._breakLineAtIntersectionN  s    ~~t~~t4dnndmmT4H1L$$T*]]FF#A&/!O	*,+$..$g? w8T 	D)$'x((112 
	7A )),,Q/ID "4>>;iPEH$+DMM;	R I6
	7 $DNNIwRVW -X&)$'"
r   c                 z   t        | j                        dz
  }| j                  |k  rRt        | j                        dkD  r:| j                  | j                  dz   |dz   = | j                  j	                  d       t               }t        t        | j                        dz
  dd      D ]B  }t        | j                  |      }t        | j                  |      }|j                  ||d       D | xj                  dz  c_        | j                  j                  | j                  |       t        | j                         y )Nrq   r   FrE   )r"   offset)lenr`   ra   rQ   
EnableRedor_   r   Vect_get_num_updated_linesrF   Vect_get_updated_lineVect_get_updated_line_offsetappendinsertVect_reset_updated)r   changesetLastdatar   r"   r   s         r   _addChangesetzIVDigit._addChangeset  s    DOO,q0  =0S5IA5M 5 5 9MA<M MNLL##E*v1$..AAEr2N 	:A(;D1$..!DFKK89	:
 	"t44d;4>>*r   c                    |dk  s|t        | j                        k\  ryd}| j                  |   }|rd}t        |      }d}nt        |      dz
  }d}d}t        |||      D ]  }||   }	|	d   }
|	d   dkD  r`t        | j                  |
      r1t        j                  dd||
       t        | j                  |
       d}nt        j                  dd||
       nst        |	d         }t        | j                  |
      s7t        j                  dd	||
       t        | j                  ||
      dk  r yd}nt        j                  dd
||
       |	dxx   dz  cc<    t        | j                         |S )a  Apply changeset (undo/redo changeset)

        :param changeset: changeset id
        :param undo: True for undo otherwise redo
        :type undo: bool

        :return: 1 changeset applied
        :return: 0 changeset not applied
        :return: -1 on error
        r   rE   rq   r"   r      zGIVDigit._applyChangeset(): changeset=%d, action=add, line=%d -> deletedz>Digit.ApplyChangeset(): changeset=%d, action=add, line=%d deadzEDigit.ApplyChangeset(): changeset=%d, action=delete, line=%d -> addedzBDigit.ApplyChangeset(): changeset=%d, action=delete, line=%d alive)r   r`   r   r   rF   r   rr   Vect_delete_lineabsVect_restore_liner   )r   	changesetundor   actionsfirstaction
lastactionstepr   actionr"   r   s               r   _applyChangesetzIVDigit._applyChangeset  s~    q=IT__)==//),KWJDg,*KJD{J5 -	#AQZF&>Dh!#"4>>48IIa!	 %T^^T:CIIX!	 VH-.&t~~t<II_!	 )FJ!CII\!	 8"[-	#\ 	4>>*
r   c           	         | j                         }| j                         }|dk(  rt        }nT|dk(  rt        }nH|dk(  rt        }n<|dk(  rt
        }n0|dk(  rt        }n$t        | j                  t        d      |z         y|t        z  r/t        |      d	k  r!t        | j                  t        d
             y| j                  j                          | j                  ||||| j                         | j                   j#                               }|d   dkD  r?| j$                  r3| j&                  j)                  | j+                  |      g||gidgg       |S )zAdd new feature

        :param ftype: feature type (point, line, centroid, boundary)
        :param points: tuple of points ((x, y), (x, y), ...)

        :return: tuple (number of added features, feature ids)
        pointr"   centroidboundaryareazUnknown feature type '%s')r   r   rE   Nr   zNot enough points for liner   rE   N)	new_bboxsnew_areas_cats)r   r   GV_POINTGV_LINEGV_CENTROIDGV_BOUNDARYGV_AREAr   rG   r   r   r   rQ   
EnableUndo_addFeaturer   rV   r   rc   rd   rx   _createBbox)r   r4   r   r   r   vtyper   s          r   
AddFeaturezIVDigit.AddFeature  sD    ))+%%'GEf_Ej Ej Ef_E~~q1L/MPU/U 8Fa$..!4P2QR!65#t'8'8':DMM<V<V<X
 q6B;4,,""++F34"'# 67 # 
 
r   c                 $   | j                         syt        j                  ddd      }t               }g }g }|r| j                  j
                  d   D ]s  }t        | j                  d| j                  |      dk  r| j                  j                  |       | j                  sP| j                  |      }|sd||d   z  }||d	   z  }u | j                  j                         }t        | j                  |      }t        |       t!               | j                  j
                  d<   |dkD  rf|r| j#                  |       | j%                          | j&                  j)                          | j                  r| j*                  j-                  ||
       |S )zNDelete selected features

        :return: number of deleted features
        rE   r>   	delRecordr   r   idsNr   rq   	old_bboxsold_areas_cats)r   r   r   r[   rV   selectedr   rF   rZ   rR   r#   rc   _getLineAreaBboxCatsGetSelectedIListVedit_delete_linesr   r_   _deleteRecordsr   rQ   r   ri   rx   )	r   	deleteReccatDictr   r   r   r   poListnliness	            r   DeleteSelectedLineszIVDigit.DeleteSelectedLines  sb   
 ~~ !$$8YW	&	]]++E2 1!$..$QG!KKK((+$$33A6C!SV+	&#a&01" //1#DNNF;&!(,u%A:##G, LL##%  $$))' *  r   c                    t               }t        |      }t               }t        |      }t        t	        | j
                              D ]  }t        | j
                  |      }|| j                  j                  |        y|j                  }|j                  |j                         vrbt        |j                        }	|	'| j                  j                  |j                          yt        |       t!        ||j"                  d       t%        |	|      t&        k7  r2| j                  j)                  |j                  |j"                          yt+        |       t-        |d|j.                  z         d}
||j                     D ]3  }|
dkD  rt1        |d       t1        |d|j2                  |fz         |
dz  }
5 |
dkD  r9t5        |	|      t&        k7  r&| j                  j7                  t9        |              yt;        |	        y)z_Delete records from attribute table

        :param cats: directory field/list of cats
        NrE   zDELETE FROM %s WHEREr   z orz %s = %drq   )dbHandler   dbStringr   Vect_get_num_dblinksrF   Vect_get_dblinkrR   r&   r   numberkeysdb_start_driverr(   r)   db_init_handledb_set_handler,   db_open_databaseDB_OKr-   db_init_stringdb_set_stringtabledb_append_stringr   db_execute_immediater0   db_get_string!db_close_database_shutdown_driver)r   r\   handlepoHandlestmtpoStmtr%   poFiFipoDrivern_catsr   s               r   r   zIVDigit._deleteRecordsE  s   
 6?z0@A #	8F"4>>6:D|""6*Byy		+&ryy1H""299-8$(BKK6(3u<$$RYY<6"&"8288"CDFBII A:$VU3 rvvsm)CD! z28VDM%%mF&;<-h7G#	8r   c                    t        | j                  j                  d         dk  ry| j                  j                         }|j                  }d}g }g }t        |j                        D ]  }t        | j                  |j                  |         t        k7  r.| j                  rFt        | j                  |j                  |         }|dkD  r| j                  |      \  }}	||z  }||	z  }|t        | j                  |j                  |         z  } |dkD  rS| j                          | j                   j#                          | j                  r| j$                  j'                  ||       |S )zXDelete selected areas (centroid+boundaries)

        :return: number of deleted
        r   rq   r   r   )r   rV   r   r   r   r   r   Vect_get_line_typerF   r   r   rc   Vect_get_centroid_area_getaAreaBboxCatsVedit_delete_area_centroidr   rQ   r   re   rx   )
r   r  cListnareasr   r   r   r   bboxr\   s
             r   DeleteSelectedAreaszIVDigit.DeleteSelectedAreast  sF   
 t}}%%e,-1//1	u~~& 	QA!$..%++a.A[P  -dnnekk!nM!8!%!7!7!=JD$%I"d*N0QPPF	Q A: LL##%  !!&&' '  r   c                     t        | j                  dd|      }|t        k(  r| j                  |      S | j	                  |      g| j                  |      gfS )zHelper function

        :param ln_id: id of feature
        :return: None if the feature does not exists
        :return: list of :func:`_getaAreaBboxCats`
        N)r   rF   r   _getCentroidAreaBboxCats_getBbox_getLineAreasCategories)r   ln_idr   s      r   r   zIVDigit._getLineAreaBboxCats  sX     t~~tT5AK 0077MM%()D,H,H,O+PPPr   c                     t        | j                  |      syt        | j                  |      }|dkD  r| j                  |      S y)zHelper function

        :param centroid: id of an centroid
        :return: None if area does not exists
        :return: see return of :func:`_getaAreaBboxCats`
        Nr   )r   rF   r!  r"  )r   r   r   s      r   r)  z IVDigit._getCentroidAreaBboxCats  s@     t~~x8%dnnh?!8))$//r   c                    t               }t        | j                  ||       |j                  }g }g }|j                  dkD  r{t        |j                        D ]c  }|j                  |   }|j                  | j                  t        |                   |j                  | j                  t        |                   e t        |       ||fS )zHelper function

        :param area: area id
        :return: list of categories :func:`_getLineAreasCategories` and
                 list of bboxes :func:`_getBbox` of area boundary
                 features
        r   )r   Vect_get_area_boundariesrF   r   r   r   r   r   r*  r   r+  r   )r   r   	po_b_listb_listgeoms
areas_catsi_liner"   s           r   r"  zIVDigit._getaAreaBboxCats  s     "O	 yA##
??Q0 K||F+T]]3t956!!$">">s4y"IJ	K 	)$j  r   c                    t        | j                  |      sg S t        | j                  dd|      }|t        k7  rg S ddg}t	               }t	               }t        | j                  |t        |      t        |            dk(  rf|j                  |j                  g}t        |      D ]@  \  }}|dkD  st        | j                  |      }	|	dk  r(| j                  |	      }
|
s<|
||<   B |S )a  Helper function

        :param line_id: id of boundary feature
        :return: categories of areas on the left, right side of the feature
        :return: format: [[{layer : [cat]}, None]] means:
                area to the left (list of layers which has cats list as values),
                area to the right (no area there in this case (None))
        :return: [] the feature is not boundary or does not exists
        Nrq   r   )r   rF   r   r   c_intVect_get_line_areasr   r   	enumerateVect_get_area_centroid_getCategories)r   r,  r   r\   leftrightareasr   ar   cs              r   r+  zIVDigit._getLineAreasCategories  s     t~~u5It~~tT5AKId|w  wt}genU ZZ-E!%( $1q55dnnaHH1} ++H5A"#Q$ r   c                    t        | j                  |      st        S t               }t	        | j                  d||      dk  rt        |       y|j                  }i }t        |j                        D ]b  }|j                  |   |v r/||j                  |      j                  |j                  |          C|j                  |   g||j                  |   <   d t        |       |S )zHelper function

        :param line_id: id of feature
        :return: list of the feature categories [{layer : cats}, next layer...]
        :return: None feature does not exist
        Nr   )r   rF   nonerY   r   rt   r   r   r  fieldr   r   )r   r,  rZ   cCatsr\   js         r   r:  zIVDigit._getCategories  s     t~~u5K%'$..$>B$V,u||$ 	6A{{1~%U[[^$++EIIaL9(-		!~U[[^$		6 	!(r   c                     t        | j                  |      syt               }t        | j                  |d|      dk  rt	        |       g S | j                  |      }| j                  |      }t	        |       |S )zHelper function

        :param line_id: id of line feature
        :return: bbox bounding box of the feature
        :return: None feature does not exist
        Nr   )r   rF   rW   r   rs   _convertGeomr   )r   r,  rX   geomr&  s        r   r*  zIVDigit._getBbox  sn     t~~u5')$..(D%@1D$X.I  *% *r   c                     i }|D ]v  }d|vr!|d   |d<   |d   |d<   |d   |d<   |d   |d<   (|d   |d   k  r	|d   |d<   n|d   |d   kD  r|d   |d<   |d   |d   k  r	|d   |d<   c|d   |d   kD  so|d   |d<   x |S )zHelper function

        :param points: list of points [(x, y), ...] to be bbox created for
        :return: bbox bounding box of points {'maxx':, 'maxy':, 'minx':, 'miny'}
        maxyrq   minyr   maxxminxr9   )r   r   r&  pts       r   r   zIVDigit._createBbox*  s      	%BT!!!uV!!uV!!uV!!uVF|be#!!uVf1%!!uVF|be#!!uVf1%!!uV!	%" r   c                     |j                   }g }t        |j                        D ]/  }|j                  |j                  |   |j
                  |   f       1 |S )zHelper function convert geom from ctypes line_pts to python
        list

        :return: coords in python list [(x, y),...]
        )r   r   n_pointsr   xy)r   rX   Pointspts_geomrD  s        r   rF  zIVDigit._convertGeomD  sT     ""v' 	8AOOVXXa[&((1+67	8 r   c                    | j                         syt        | j                  j                  d         }|dk  ry| j                  j	                         }| j                         }| j                  j                         }| j                  rqg }g }| j                  j                  d   D ]&  }| j                  |      }	|	s||	d   z  }||	d   z  }( t        | j                  d       t        | j                        }
t        | j                  | j                  t        | j                  du      ||d   |d   d||	      }t!        |       |dkD  rp| j                  rdg }g }t        | j                        }t#        
|      D ]<  }t%        | j                  |      }| j                  |      }	|	s-||	d   z  }||	d   z  }> |dkD  r:| j&                  d   r+t#        d|      D ]  }| j)                  ||z   dt*                |dkD  rU| j-                          | j.                  j1                          | j                  r| j2                  j5                         |S )zFMove selected features

        :param move: direction (x, y)
        rE   r   rq   r   N
breakLines)r   r   r   r   )r   r   rV   r   r   r   r   rc   r   Vect_set_updatedrF   r   Vedit_move_linesrL   intrK   r   r   r   r]   r   r   r   rQ   r   rj   rx   )r   movenselthreshsnapr  r   r   sel_idr   n_up_lines_oldr  r   r   
n_up_linesr   new_ids                    r   MoveSelectedLineszIVDigit.MoveSelectedLinesR  sM   
 ~~4==))%01!8++-  "//1IN--007 -//7Q'I"c!f,N	- T^^Q/7GN!NN  ,-GG

 	&!A:$++IN3DNNCJ>:6 -.t~~qA//7Q'I"c!f,N- A:$..61f% K--fqj$	JK A: LL##%  ""''''#1#1	 (  r   c                    | j                         syt        | j                  j                  d         dk7  ry| j                  j	                         }| j
                  ru|j                  }| j                  |j                  d         g}| j                  |j                  d         g}t        | j                  d       t        | j                        }t        | j                         t        | j                  |d   |d   d       t!        | j                  | j"                  t%        | j&                  du      || j                  | j                  j)                  d      | j                  j)                         |d   |d   dd| j+                               }t-        |       |dkD  r| j
                  rt        | j                        }	g }
g }t/        |	      D ]X  }t1        | j                  |      }|
j3                  | j                  |             |j3                  | j                  |             Z |dkD  r4| j4                  d	   r%| j7                  t9        | j                        d       |dkD  rU| j;                          | j<                  j?                          | j
                  r| j@                  jC                  

       |S )zMove selected vertex of the line

        :param point: location point
        :param move:  x,y direction

        :return: id of new feature
        :return: 0 vertex not moved (not found, line is not selected)
        :return: -1 on error
        rE   r   rq   r   r   NselectThreshtyperU  )r   r   r   r   )"r   r   rV   r   r   rc   r   r*  r   r+  rV  rF   r   Vect_reset_linerX   Vect_append_pointVedit_move_vertexrL   rX  rK   r   r   r   r   r   r   r]   r   Vect_get_num_linesr   rQ   r   rf   rx   )r   r   rY  r  r$  r   r   r^  movedr_  r   r   r   r`  s                 r   MoveSelectedVertexzIVDigit.MoveSelectedVertex  sW    ~~t}}%%e,-2 //1OOEu{{1~67I"::5;;q>JKNT^^Q/7GN&$--q58SA!NN  ,-MMMM&&N&;MM&&(GG
 	&!19**3DNNCJIN>:6 L.t~~qA  v!67%%d&B&B6&JKL
 195))*<T^^*LdS19 LL##%    %%'#1#1'	 &  r   c                 j    | j                  |d      }|dkD  r| j                  j                          |S )zAdd new vertex to the selected line/boundary on position 'coords'

        :param coords: coordinates to add vertex

        :return: id of new feature
        :return: 0 nothing changed
        :return: -1 on failure
        Taddr   _ModifyLineVertexrQ   r   )r   coordsaddeds      r   	AddVertexzIVDigit.AddVertex  s5     &&v4&819LL##%r   c                 j    | j                  |d      }|dkD  r| j                  j                          |S )zRemove vertex from the selected line/boundary on position 'coords'

        :param coords: coordinates to remove vertex

        :return: id of new feature
        :return: 0 nothing changed
        :return: -1 on failure
        Frm  r   ro  )r   rq  deleteds      r   RemoveVertexzIVDigit.RemoveVertex  s5     ((U(;Q;LL##%r   c                    | j                   j                  d      }| j                         sy| j                   j                         }t	        | j
                         t        | j
                  |d   |d   d       t        | j                  || j
                  |d      }t        |       |dkD  r*| j                          | j                  j                          |S )zSplit/break selected line/boundary on given position

        :param point: point where to split line

        :return: 1 line modified
        :return: 0 nothing changed
        :return: -1 error
        rc  rE   r   rq   r   N)rV   r   r   r   rf  rX   rg  Vedit_split_linesrF   r   r   rQ   r   )r   r   r[  r  r   s        r   	SplitLinezIVDigit.SplitLine  s     ++N;~~//1&$--q58SAvtT&!7 LL##%
r   c           	         | j                         syt        |      dk  r| j                          yt        | j                  |      s| j
                  j                  |       yt        | j                  d| j                  |      }|dk  r| j
                  j                  |       y| j                  r$| j                  |      g}| j                  |      g}t        | j                         |D ]   }t        | j                  |d   |d   d       " | j!                         }|t"        k7  rf|t$        k(   }t'        | j                  | j(                  t+        | j,                  du      d| j                  | j.                  j1                         |       t3        | j                  ||| j                  | j                        }	|	dkD  r0| j                  r$| j                  |	      g}
| j                  |	      g}|	dkD  r!| j4                  d   r| j7                  |	d       |	dkD  rY| j9                          | j:                  j=                          | j                  r#| j>                  jA                  tB               |	S )	zEdit existing line/boundary

        :param line: feature id to be modified
        :param coords: list of coordinates of modified line

        :return: feature id of new line
        :return: -1 on error
        rE   r   r   Nrq   r   rU  )r   r   r   r   )"r   r   r  r   rF   rR   r2   r   rZ   r#   rc   r*  r+  rf  rX   rg  r   r   r   Vedit_snap_linerL   rX  rK   rV   r   Vect_rewrite_liner]   r   r   rQ   r   rk   rx   r   )r   r"   rq  r   r   r   pr\  modeSnapnewlinenew_geomr   s               r   EditLinezIVDigit.EditLine  s#    ~~v;?$$&t~~t4KK  & t~~tT[[$G19KK  &t,-I"::4@AN 	& 	>AdmmQqT1Q4=	>   "7? DL)H""D$$D01**, $NND%
 Q;4,,g./H"::7CDNQ;4>>,7))'48Q; LL##%  $$'#1'#1	 %  r   c                 &   | j                         syt        | j                        }| j                  j	                         }t        | j                  |      }t        |       |dkD  r*| j                          | j                  j                          |S )zoFlip selected lines/boundaries

        :return: number of modified lines
        :return: -1 on error
        rE   r   )
r   ri  rF   rV   r   Vedit_flip_linesr   r   rQ   r   )r   r  r  r   s       r   FlipLinezIVDigit.FlipLinef  sq     ~~#DNN3//1t~~v6&!7 LL##%
r   c                     | j                         sy| j                  j                         }t        | j                  |      }t        |       |dkD  r*| j                          | j                  j                          |S )zpMerge selected lines/boundaries

        :return: number of modified lines
        :return: -1 on error
        rE   r   )	r   rV   r   Vedit_merge_linesrF   r   r   rQ   r   r   r  r   s      r   	MergeLinezIVDigit.MergeLine{  sc     ~~//17&!7 LL##%
r   c                 
   | j                         sy| j                  j                         }t        | j                  |dt
        d      }t        |       |dkD  r*| j                          | j                  j                          |S )zpBreak selected lines/boundaries

        :return: number of modified lines
        :return: -1 on error
        rE   Nr   )
r   rV   r   r   rF   r   r   r   rQ   r   r  s      r   	BreakLinezIVDigit.BreakLine  si     ~~//1#DNNFD(DQ&!7 LL##%
r   c                 ~   | j                         syt        | j                        }| j                  j	                         }t        | j                  || j                  j                         d       t        |       |t        | j                        k  r*| j                          | j                  j                          y)zcSnap selected lines/boundaries

        :return: 0 on success
        :return: -1 on error
        rE   Nr   )r   ri  rF   rV   r   Vect_snap_lines_listr   r   r   rQ   r   )r   r  r  s      r   SnapLinezIVDigit.SnapLine  s     ~~#DNN3//1T^^VT]]5O5O5QSWX&!&t~~66 LL##%r   c                 .   | j                         sy| j                  j                         }t        | j                  || j                  j                               }t        |       |dkD  r*| j                          | j                  j                          |S )zConnect selected lines/boundaries

        :return: 1 lines connected
        :return: 0 lines not connected
        :return: -1 on error
        rE   r   )
r   rV   r   Vedit_connect_linesrF   r   r   r   rQ   r   r  s      r   ConnectLinezIVDigit.ConnectLine  sr     ~~//1!$..&$--:T:T:VW&!7 LL##%
r   c                    | j                         syt        | j                        }| j                  j	                  |      }t        | j                  | j                  |      }t        |       |dkD  rA| j                  r5| j                  d   r&t        d|      D ]  }| j                  ||z   d        |dkD  r*| j                          | j                  j                          |S )zCopy features from (background) vector map

        :param ids: list of line ids to be copied

        :return: number of copied features
        :return: -1 on error
        rE   r   rU  rq   N)r   ri  rF   rV   r   Vedit_copy_linesrK   r   r]   r   r   r   rQ   r   )r   r   r  r  r   r   s         r   CopyLinezIVDigit.CopyLine  s     ~~#DNN3//4t~~t/?/?H&!7t''DNN<,H1c] @--fqj$?@ 7 LL##%
r   c                 
   t        |      dk  st        |      dk  ry| j                  }t               }d}|D ]  }t        | j                  |      st        | j                  d||      dk  r| j                  j                  |        y|D ]  }t        | j                  |      st        | j                  | j                  ||      }	|	dk  r| j                  j                  |         y|j                  }
t        |
j                        D ]  }|s|
j                  |   }| j                  |
j                  |      dz   }|| j                  |
j                  |   <   t        | j                  |
j                  |         }|s| j                  j!                  |          y|j                  }t#        |j$                        }|s)| j                  j'                  |j$                            yt)               }t+        t-        |             t/        t-        |      |j0                  d       t3        |t-        |            t4        k7  r?t7        |       | j                  j9                  |j$                  |j0                            yt;               }t=        t-        |             t?        t-        |      d|j@                  |jB                  |
j                  |   fz         tE               }tG        |t-        |      t-        |      tH              t4        k7  rtK        |          ytM        t-        |            }tO        |      }d|j@                  z  }tQ               }	 tS        t-        |      tT        t-        |            t4        k7  rtK        |          y|jV                  snt;               }t        |      D ]  }|dkD  r|dz  }tY        ||      }t[        |      |jB                  k(  r	|d|z  z  }:t]        |      }t_        |t-        |             ta        |      r|d	z  }ktc        te        |            }|tf        k7  r|ti        t-        |            z  }|d
ti        t-        |            z  z  } |dz  }t?        t-        |      |       tk        |t-        |            t4        k7  rtK        |          ytK        |       tm        |        to        ||
j                           dk  rhtq        | j                  ||	| j                  |      dk  r| j                  js                            y|dz  } 
 tu        |       |dkD  r| jv                  jy                          |S )zCopy given categories to objects with id listed in ids

        :param cats: ids of 'from' feature
        :param ids: ids of 'to' feature(s)

        :return: number of modified features
        :return: -1 on error
        rq   r   NrE   zSELECT * FROM %s WHERE %s=%dzINSERT INTO %s VALUES (,z%dNULLz'%s'))=r   rZ   rY   r   rF   r   rR   r#   rX   r   r   r  r   r\   rB  Vect_get_fieldr&   r  r(   r)   r  r  r   r  r,   r  r  db_shutdown_driverr-   r  r  r  r  r   dbCursordb_open_select_cursorDB_SEQUENTIALr  db_get_cursor_tabledb_get_table_number_of_columnsr6  db_fetchDB_NEXTr   db_get_table_columndb_get_column_namedb_get_column_value!db_convert_column_value_to_stringdb_test_value_isnulldb_sqltype_to_Ctypedb_get_column_sqltypeDB_C_TYPE_STRINGr  r  G_freeVect_cat_setr|  r   rt   rQ   r   )r   fromIdtoId	copyAttrb
poCatsFrompoCatsTor  flinetliner   catsFromr   r   r  fir(   r  r  cursorr  ncolsr/   morevalue_stringcolcolumnr   ctypes                               r   CopyCatszIVDigit.CopyCats  s    v;?c$i!m[[
') |	E"4>>59dnndJFJ$$U+ t&t~~u=&t~~t}}hPUV19KK((/%..x/ \%A$&ll1o #iiq(9:Q>7:		(.."34-dnnhnnQ>OP# KK..q1#%!]]!0!;% KK..ryy9#%!)&uV}5%eFmR[[$G+FE&MBeK.v6 KK00BKKH#%'z&uT{3%!$K:!xxaAB "*1 &dU6]M  %%
 >fE#% 3E&M B >u E7"((B$w"'fwdLPUU A& I')#':: %+3:L',U| *#&7$'3JC)<UC)H#5f#=#G$'4#:$5C$,(;F(C A$*E,,?!" $8#>$'6MC,?(=f(E-&E (-0@'@(+}U<=P/Q(Q(+v,1,,?9* 0* )*-* #D s
%eDk37/dDM=fE#%9&Aty\%|  (..*;SAAE &udmmX 
 KK))+!it|	| 	!*A:LL##%r   c                 $   d}t        j                  ddd      dk(  r:t        j                  ddd      }t        j                  ddd	      dk(  rd
|z  }|S t        j                  ddd      }t        j                  ddd	      dk(  rd
|z  }|S )zNGeneric method used for SelectLinesByQuery() -- to get
        threshold valuer   r>   queryr   r   r   queryLengthr[  zthan-selectionrE   queryDangler   )r   r[  s     r   _selectLinesByQueryThreshz!IVDigit._selectLinesByQueryThreshz  s     (LPQQ!%%M(F   ">N 
 f  "%%M(F   ">N 
 fr   c                    | j                         sy| j                         }t        }t        j                  ddd      dk(  rt
        }nt        }t        t        z  }d}t               }t               }|j                  }t        j                  ddd      rt        | j                         |d   \  }	}
|d   \  }}d	x}}t        | j                  |	|
|       t        | j                  ||
|       t        | j                  |||       t        | j                  |	||       t        | j                  |	|
|       t        | j                   | j                  dd
||       |j"                  dk(  r|S t%        | j                   |||||       t'        |j"                        D ])  }|j)                  t+        |j,                  |                + t/        j0                  dd|j"                         t3        |       |S )zySelect features by query

        .. todo::
            layer / 3D

        :param bbox: bounding box definition
        rE   r>   r  r   r   r   rq   boxr   Nr   z&IVDigit.SelectLinesByQuery(): lines=%d)r   r  QUERY_UNKNOWNr   r   QUERY_LENGTHQUERY_DANGLE	GV_POINTSr   r_   r   r   rf  rX   rg  Vect_select_lines_by_polygonrF   r   Vedit_select_by_queryr   r   rX  r   r   rr   r   )r   r&  r[  r  r4   r   r   r  coListx1y1x2y2z1z2r   s                   r   SelectLinesByQueryzIVDigit.SelectLinesByQuery  s    ~~//1(LPQQ E EH$f(FDMM*!WFB!WFBMBdmmRR8dmmRR8dmmRR8dmmRR8dmmRR8(q$v !#
dnneUFE6Rv' 	-AJJs6<<?+,	- 			!=vO&!
r   c                 N    | j                         syt        | j                        S )zCheck if open vector map is 3DF)r   
Vect_is_3drF   r   s    r   
IsVector3DzIVDigit.IsVector3D  s    ~~$..))r   c                 &   | j                         syt        | j                  |      syt        | j                  | j                  d|      }|dk  r!| j
                  j                  |       t        S d}|t        z  rt        | j                        }|S )ztGet line length

        :param line: feature id

        :return: line length
        :return: -1 on error
        rE   Nr   )
r   r   rF   r   rX   rR   r#   r   r   Vect_line_length)r   r"   r   lengths       r   GetLineLengthzIVDigit.GetLineLength  sx     ~~t~~t4t~~t}}dDI19KK  &J8%dmm4Fr   c                 V   | j                         syt        | j                  dd|      }|dk  r%| j                  j	                  t
               t        S |t        k7  ryt        | j                  |      }d}|dkD  r.t        | j                  |      s|S t        | j                  |      }|S )zuGet area size

        :param centroid: centroid id

        :return: area size
        :return: -1 on error
        rE   Nr   )r   r   rF   rR   r#   r"   r   r   r!  Vect_area_aliveVect_get_area_area)r   r   r   r   sizes        r   GetAreaSizezIVDigit.GetAreaSize  s     ~~t~~tT8D19KK  &JK%dnnh?!8"4>>48%dnnd;Dr   c                    | j                         syt        | j                  dd|      }|dk  r%| j                  j	                  t
               t        S |t        k7  ryt        | j                  |      }d}|dkD  rMt        | j                  |      syt        | j                  || j                         t        | j                        }|S )zzGet area perimeter

        :param centroid: centroid id

        :return: area size
        :return: -1 on error
        rE   Nr   )r   r   rF   rR   r#   r"   r   r   r!  r  Vect_get_area_pointsrX   Vect_area_perimeter)r   r   r   r   	perimeters        r   GetAreaPerimeterzIVDigit.GetAreaPerimeter
  s     ~~t~~tT8D19KK  &JK%dnnh?	!8"4>>48 t}}E+DMM:Ir   c                    | j                         sy|dk  r&t        | j                  j                  d         dk  ryd}|dk(  rd}| j                  j                  d   d   }t	        | j
                  |      syt        | j
                  | j                  | j                  |      }|dk  r| j                  j                  |       y|D ]3  }|rt        | j                  ||       t        | j                  ||       5 t        | j
                  ||| j                  | j                        }|dkD  r*| j                          | j                  j!                          |r|| j                  j                  d   d<   |S )aY  Set categories for given line and layer

        :param line: feature id
        :param layer: layer number (-1 for first selected line)
        :param cats: list of categories
        :param add: if True to add, otherwise do delete categories

        :return: new feature id (feature need to be rewritten)
        :return: -1 on error
        rE   rq   r   FTr   )r   r   rV   r   r   rF   r   rX   rZ   rR   r#   r  Vect_field_cat_delr|  r   rQ   r   )	r   r"   r   r\   rn  updater   r?  r  s	            r   SetLineCatszIVDigit.SetLineCats(  sD    ~~!8DMM2259:Q>2:F==))%03Dt~~t4t~~t}}dkk4P19KK  & 	:AT[[%3"4;;q9		: $NND%
 Q; LL##%/6DMM""5)!,r   c                     | j                         sy| j                  j                         }t        | j                  |      }t        |       |dkD  r*| j                          | j                  j                          |S )zFeature type conversion for selected objects.

        Supported conversions:
         - point <-> centroid
         - line <-> boundary

        :return: number of modified features
        :return: -1 on error
        rE   r   )	r   rV   r   Vedit_chtype_linesrF   r   r   rQ   r   r  s      r   TypeConvForSelectedLinesz IVDigit.TypeConvForSelectedLinesZ  sc     ~~//1 8&!7 LL##%
r   c                 4   t        | j                        dz
  }|dk  r|S |dk  r| j                  |kD  r|| _        n|dk(  rd| j                  z  dz
  }t        j                  dd|| j                  |       |dk  r[| j                  |z   dk  r| j                  S t        | j                  | j                  |z   d      D ]  }| j                  |d        nd|dkD  r_| j                  dz   |kD  r| j                  S t        | j                  dz   | j                  dz   |z         D ]  }| j                  |d        | xj                  |z  c_        t        j                  dd	| j                  |       | j                  j                  d
       | j                  dk  r| j                  j                  d       n| j                  j                  d       | j                  |k  r| j                  j                  d       y| j                  j                  d       y)zvUndo action

        :param level: levels to undo (0 to revert all)

        :return: id of current changeset
        rq   r   rE   r   z?Digit.Undo(): changeset_last=%d, changeset_current=%d, level=%dT)r   Fz5Digit.Undo(): changeset_current=%d, changeset_last=%d)renderN)r   r`   ra   r   rr   r   r   rG   	UpdateMaprQ   r   r   )r   levelr   r   s       r   UndozIVDigit.Undoq  s    DOO,q01  19..>$1D!aZ...2E		M!!	
 19$$u,r1,,,"%%t'<'<u'Db ;	 $$YT$:; QY$$q(=8,,,"%%)4+@+@1+Du+L <	 $$YU$;<
 	&		C!!		
 	   .  1$LL##E*LL##D)  =0LL##D)LL##E*r   c           
          | j                         sy| j                  j                         }t        | j                  ||d   |d   |d   |d   ||      }t        |       |dkD  r*| j                          | j                  j                          |S )a  Z-bulk labeling

        :param pos1: reference line (start point)
        :param pos1: reference line (end point)
        :param start: starting value
        :param step: step value

        :return: number of modified lines
        :return: -1 on error
        rE   r   rq   )	r   rV   r   Vedit_bulk_labelingrF   r   r   rQ   r   )r   pos1pos2startr   r  r   s          r   
ZBulkLineszIVDigit.ZBulkLines  s     ~~//1!NNFDGT!Wd1gtAwt
 	&!7 LL##%
r   c                     | j                   S )zGet display driver instance)rV   r   s    r   
GetDisplayzIVDigit.GetDisplay  s    }}r   c                 N   t        j                  dd|z         d|v r|j                  d      \  }}nt        j                         d   }| j
                  j                  t        |      t        |      ||      | _        | j                  r| j                          | j                  S )zOpen vector map for editing

        :param map: name of vector map to be set up
        :type map: str
        :param tmp: True to open temporary vector map
        r   zAbstractDigit.SetMapName map=%s@MAPSET)
r   rr   splitr   gisenvrV   OpenMapstrrF   rb   )r   r   r  tmpr   s        r   r  zIVDigit.OpenMap  s~     			!6=>$;::c?LD&\\^H-F..s4y#f+vsS>>MMO~~r   c                     | j                         syt        j                  j                  t        j
                         | j                  j                          y)zClose currently open vector mapN)r   sysstdoutwriteoslineseprV   CloseMapr   s    r   r  zIVDigit.CloseMap  s7    ~~ 	

$ r   c                    | j                   j                          | j                         syt        | j                        }t        |      D ]>  }t        | j                  |      j                  }|s&d| j                   |j                  <   @ t        | j                        }t        j                  dd|       t        |      D ]*  }t        | j                  |      }t        | j                  |      }|dk  r6t        |      D ]  }t               }t               }	t               }
t        | j                  ||t!        |      t!        |	      t!        |
             || j                   v rF| j                   |   |j"                  | j                   |   kD  s|j"                  | j                   |<   |j"                  | j                   |<    t        j                  dd|| j                   |          - t%        j&                  | j                         D ];  \  }}|d| j                   |<   t        j                  dd|| j                   |          = y)zfInitialize categories information

        :return: 0 on success
        :return: -1 on error
        rE   Nr   zwxDigit.InitCats(): nfields=%dr   r   z$wxDigit.InitCats(): layer=%d, cat=%d)r\   clearr   r  rF   r   r  r   r	  Vect_cidx_get_num_fieldsr   rr   Vect_cidx_get_field_numberVect_cidx_get_num_cats_by_indexr6  Vect_cidx_get_cat_by_indexr   r   six	iteritems)r   ndblinksr   r  nfieldsrB  ncatsrD  r   re  r   s              r   rb   zIVDigit.InitCats  s    			~~'7x 	,A 3<<B'+		"))$	, +4>>:		!5w?w 	A.t~~qAE3DNNAFEz5\ 1gwW*NNAq%*eDk59 DII%yy'/399tyy?O3O+.99		%('*yyDIIe$1 II95$))EBR#	, --		2 	JE3{#$		% II95$))EBR	r   c                 R    | j                   s| j                  j                          yy)zCheck if map is openFT)rF   rR   r   r   s    r   r   zIVDigit._checkMap  s    ~~KKr   c           	         t               }| j                         syt        t        | j                              }t        j                  ddt        |      |||       |t        t        z  t        z  z  s| j                  j                  |       yt        | j                         |dkD  rS|t        k7  rJt        | j                  ||       t!        || j"                  j%                  |d            | j"                  |<   t'        | j(                         |D ]   }	t+        | j(                  |	d   |	d   d       " |t,        t        z  z  r*| j(                  j.                  }
|
j0                  dz
  }| j2                  d   r@t+        | j(                  |
j4                  d   |
j6                  d   |
j8                  d          nt;        |
j4                  d   |
j6                  d   |
j8                  d   |
j4                  |   |
j6                  |   |
j8                  |   |      |k  rT|
j4                  d   |
j4                  |<   |
j6                  d   |
j6                  |<   |
j8                  d   |
j8                  |<   |t<        k7  rN|t>        k(   }tA        | j                  | jB                  tE        | jF                  du      d	| j(                  ||       |t        k(  rt,        }n|}tI        | j                  || j(                  | j                        }|dk  r| j                  jK                          y|jM                  |       |t        z  rd	x}}tO               }tQ               }tQ               }tS        | j                  |tU        |      tU        |             |jV                  }|jV                  }t        j                  d
d||       |dkD  rT|dkD  s|dkD  rJt        | j                  ||       t!        || j"                  j%                  |d            | j"                  |<   tY               }tY               }|dkD  rt[        | j                  |      dk(  rt]        | j                  |tU        |      tU        |            dk(  rt'        |       t+        ||jV                  |jV                  d       tI        | j                  t^        || j                        }|dk  r'| j                  jK                          t        |      |fS |jM                  |       |dkD  rt[        | j                  |      dk(  rt]        | j                  |tU        |      tU        |            dk(  rt'        |       t+        ||jV                  |jV                  d       tI        | j                  t^        || j                        }|dk  r&| j                  jK                          t        ||      S |jM                  |       ta        |       | j2                  d   r| jc                  || j(                         | je                          |t        z  rt        |      dz
  |fS t        |      |fS )a  Add new feature(s) to the vector map

        :param ftype: feature type (GV_POINT, GV_LINE, GV_BOUNDARY, ...)
        :param coords: tuple of coordinates ((x, y), (x, y), ...)
        :param layer: layer number (-1 for no cat)
        :param cat: category number
        :param snap: snap to node/vertex
        :param threshold: threshold for snapping

        :return: tuple (number of added features, list of fids)
        :return: number of features -1 on error
        r   r   z<IVDigit._addFeature(): npoints=%d, layer=%d, cat=%d, snap=%dr   rq   r   closeBoundaryNrE   r   z.IVDigit._addFeature(): area - left=%d right=%drU  )3r_   r   boolr  rF   r   rr   r   r  r   r   rR   r5   Vect_reset_catsrZ   r  maxr\   getrf  rX   rg  r   r   rO  r]   rP  rQ  zVect_points_distancer   r   r{  rL   rX  rK   Vect_write_liner   r   rW   r6  r7  r   r   c_doubler9  Vect_get_point_in_arear   rs   r   r   )r   r4   rq  r   r   r\  r   fidsis3Dr?  r   lastr~  r   r  r;  r<  bpointscleftcrightrP  rQ  newcs                          r   r   zIVDigit._addFeature%  s    v~~Jt~~./		JK	
 X-78KK##E* 	$19')eS1"3		eQ(?@DIIe 	& 	>AdmmQqT1Q4=	> K')*]]++F??Q&D~~o.!$--!fhhqk688TU;W$HHQKHHQKHHQKHHTNHHTNHHTN 	 "(!!'!!'!7? DL)H""D$$D01 GEE!$..%TQ;KK!!#G 7?D5*,GGEWFuuV}U;;DLLEIIaI4QVW qydQh%!)T[[%5#&sDIIMM%,C#D		% 
A
Aax24>>4HAM +4>>4q5QR8T $G,%gqwwE*WdkkD ax--/ #D	400D)qy3DNNEJaO +4>>5%(ERSHU $G,%gqwwE*WdkkD ax--/"4.D)$W- >>,'))'4==A7?IM4((D	4  r   c                 P   | j                         sy| j                  j                  }t        |d         dk7  ry| j                  j	                         }| j
                  ru|j                  }| j                  |j                  d         g}| j                  |j                  d         g}t        | j                  d       t        | j                        }t        | j                         t        | j                  |d   |d   d       | j                  j!                  d      }	|r#t#        | j                  || j                  |	      }
n"t%        | j                  || j                  |	      }
t'        |       |
dkD  r| j
                  rg }g }t        | j                        }t)        |      D ]X  }t+        | j                  |      }|j-                  | j                  |             |j-                  | j                  |             Z |s9|
dkD  r4| j.                  d   r%| j1                  t3        | j                        d	       |
dkD  r| j5                          |
dkD  rK| j
                  r?|r| j6                  j9                  
       y| j:                  j9                         y)a6  Add or remove vertex

        Shape of line/boundary is not changed when adding new vertex.

        :param coords: coordinates of point
        :param add: True to add, False to remove
        :type add: bool

        :return: 1 on success
        :return: 0 nothing changed
        :return: -1 error
        rE   r   rq   r   r   rc  rd  rU  N)r   r   )r   r   r   r   )r   rV   r   r   r   rc   r   r*  r   r+  rV  rF   r   rf  rX   rg  r   Vedit_add_vertexVedit_remove_vertexr   r   r   r   r]   r   ri  r   rg   rx   rh   )r   rq  rn  r   r  r$  r   r   r^  r[  r   r   r   r_  r   r`  s                   r   rp  zIVDigit._ModifyLineVertex  s<    ~~==))x1$//1OOEu{{1~67I"::5;;q>JKNT^^Q/7GN&$--F1IsC+++@"4>>64==&QC%dnnfdmmVTC&!7t((IN3DNNCJ>:6 8.t~~qA%%d&B&B6&JK  v!678
 sQw4>>,#?))*<T^^*LdS7 7t((  %%	Y%O  ""''''#1#1	 (  r   c                    t               }| j                         s|S |dk(  r't        | j                  j                  d         dk  r|S |dk(  r| j                  j                  d   d   }t        | j                  |      s| j                  j                  |       |S t        | j                  d| j                  |      dk  r| j                  j                  |       |S | j                  j                  }t        |j                        D ]C  }|j                  |   }||vrt!               ||<   ||   j#                  |j$                  |          E |S )zGet list of layer/category(ies) for selected feature.

        :param line: feature id (-1 for first selected feature)

        :return: list of layer/cats
        rE   r   rq   r   N)r[   r   r   rV   r   r   rF   rR   r2   r   rZ   r#   r   r   r  rB  r_   r   r   )r   r"   r   r\   r   rB  s         r   GetLineCatszIVDigit.GetLineCats  s     f~~J2:#dmm44U;<q@J2:==))%03Dt~~t4KK  &J$..$TBQFKK  &J{{##t{{# 	+AJJqMEC!VE
Jdhhqk*		+ 
r   c                 6    | j                   j                         S )zlGet list of layers

        Requires self.InitCats() to be called.

        :return: list of layers
        )r\   r
  r   s    r   	GetLayerszIVDigit.GetLayers.  s     yy~~r   c                     | j                   j                          t        t        j                  ddd            | j
                  d<   t        t        j                  ddd            | j
                  d<   y)z#Update digit (and display) settingsr>   rU  r   r   r  N)rV   r^   r  r   r   r]   r   s    r   r^   zIVDigit.UpdateSettings7  s^    $$&'+8iP(
|$ +/8S+
'r   c                     t        j                  ddd      }d}|dk(  r| j                         }n|dk(  rt        j                  ddd	      }|r't        j                  dd
d	      }|| j                  |<   |S )z"Update self.cats based on settingsr>   r   r   r   Nr   rq   categoryr   r   )r   r   _setCategoryNextToUser\   )r   selr   r   s       r   r   zIVDigit.SetCategoryB  su    X>+V!8,,.CAX""z'RC $$8QE"DIIe
r   c                     t        j                  ddd      }| j                  j                  |d      dz   }t        j                  ddd|       t        j                  dd	|       |S )
zFind maximum category number for the given layer and
        update the settings

        :return: category to be used
        r>   r   r   r   r   rq   r,  )r   r   r   r   z'IVDigit._setCategoryNextToUse(): cat=%d)r   r   r\   r  Setr   rr   )r   r   r   s      r   r-  zIVDigit._setCategoryNextToUseQ  s[       xWWMiimmE1%)xZsS		!>D
r   c                     | j                   j                  || j                        dk  r-| j                   j                  |d   | j                        d    | j                   j                  d   S )zSelect features from background map

        :param bbox: bounding box definition

        :return: list of selected feature ids
        )rF   rq   r   r"   r   )rV   SelectLinesByBoxrK   SelectLineByPointr   )r   r&  s     r   SelectLinesFromBackgroundMapz$IVDigit.SelectLinesFromBackgroundMap_  sb     ==))$$:J:J)KaOMM++DGt?O?O+PQWX}}%%e,,r   c                     | j                   S )z]Get undo level (number of active changesets)

        Note: Changesets starts with 0
        )ra   r   s    r   GetUndoLevelzIVDigit.GetUndoLevell  s    
 $$$r   c                 p    t        | j                  ddd      }|t        k(  rt        | j                        S y)zGet feature type for OGR layers

        :return: feature type as string (point, linestring, polygon)
        :return: None for native format
        Nr}   )Vect_get_finfo_topology_inforF   GV_TOPO_PSEUDOVect_get_finfo_geometry_type)r   
topoFormats     r   GetFeatureTypezIVDigit.GetFeatureTypes  s2     2$..$dS
'/??r   N)F)T)rE   )TF)Ar6   r7   r8   r   r   rv   ry   r{   r   r   r   r   r   r   r   r   r  r   r'  r   r)  r"  r+  r:  r*  r   rF  ra  rk  rs  rv  ry  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rb   r   r   rp  r'  r)  r^   r   r-  r4  r6  r<  r9   r   r   r;   r;      sX   1> R7h
!5 D$

8t+$JX*X1f-8^$LQ  !4%N6(4FPGR  4GR*&&((  6Tl:4l*2:<0d.<+|4*!/b]!~FP D 	
-%
r   r;   )#__doc__
__future__r   r  grass.script.corescriptcorer   grass.pydispatch.signalr   	core.gcmdr   
core.debugr   core.settingsr   vdigit.wxdisplayr   r	   WindowsError	NameErrorOSErrorgrass.lib.gisgrass.lib.vectorgrass.lib.veditgrass.lib.dbmiImportError	TypeErroreprintformatr  stderrr   r;   r9   r   r   <module>rT     s   8 & 
 ! ! *   & 87"! 
\
 \
~h hU  L 	\9- 7	

!
!!
$3::667s(   A# A0 #A-,A-0B%8#B  B%