Source code for pylayers.gis.selectl

# -*- coding: utf-8 -*-
r"""

.. currentmodule:: pylayers.gis.selectl

.. autosummary::

"""
from __future__ import print_function
import os
import pdb
from PIL import Image
import numpy as np
from pylayers.util import geomutil as geu
from pylayers.util import pyutil as pyu
import pylayers.util.plotutil as plu

import matplotlib.pyplot as plt
#from pylayers.util.easygui import *
from matplotlib.widgets import RectangleSelector

import copy


[docs]class SelectL(object): """ Associates a Layout and a figure 'l' : select activelayer 'i' : back to init state 'e' : edit segment 'CTLR + t' : translate structure 'h' : add subsegment 'd' : delete subsegment 'r' : refresh 'o' : toggle overlay 'm' : toggle mode (point or segment) 'z' : change display parameters 'q' : quit interactive mode 'x' : save .str2 file 'w' : display all layers """ def __init__(self,L,fig,ax): """ SelectL is a class which associates a Layout and a figure Parameters ---------- L : Layout fig : figure ax : axes """ self.fig=fig self.ax=ax self.L = L self.text = self.ax.text(0.05, 0.95, 'Selected : none', transform=self.ax.transAxes, va='top') self.set_origin = False self.set_x = False self.set_y = False self.pt = [] self.seg = [] self.coseg = [] self.pt1 = np.array([]) self.pt2 = np.array([]) self.selected_pt1 = 0 self.selected_pt2 = 0 self.selected_edge1 = 0 self.selected_edge2 = 0 self.current_layer = self.L.display['activelayer'] self.npsel = 0 self.nedge_sel = 0 self.indp = 0 self.state = 'Init' self.evt='' self.statename={'Init':'Point/Segment Selection', 'CP':'Create Point', 'SP1':'Select Point 1', 'SP2':'Select Point 2, Click Again for Creating Segment', 'SS':'Select Segment', 'SSS':'Select Sub Segment', 'CPS':'Click again for Split Segment', 'CPSS':'Create Point On Sub Segment', 'SMP': 'Multiple Points Selection', 'SMS': 'Multiple Segments Selection' } self.help={'':'', 'Init':'Select Point or Segment/ F1: Multiple selection/ F2: Create Point/ CTRL+q: Quit', 'CP':'Create Point/ +CTRL same x/ +SHIFT same y', 'SP1':'Select Point/ Click another point to create segment', 'SP2':'Click Again for Creating Segment', 'SS':'e: edit segment properties, h: add a sub-segment', 'SSS':'Select Sub Segment', 'CPS':'Click again for Split Segment', 'CPSS':'Create Point On Sub Segment', 'SMP': 't: toggle point/segment, Shift + select : add selected points, CTRL + select : remove selected points', 'SMS': 't: toggle point/segment, e: Edit Selected Segments Propeties' } self.nsel = 0 self.ax.axis(self.L.display['box']) plt.title(self.statename[self.state]) self.undoGs=[] self.bundo=False self.update_state() self.shift_is_held = False self.ctrl_is_held = False self.alt_is_held = False self.selectpt=[] self.selectseg=[] self.selected='pt' # save matplotlib config self.rcconf = {} self.rcconf['keymap.save']= plt.rcParams['keymap.save'] plt.rcParams['keymap.save']=[] self.ddoc = {'l' : 'select activelayer', 'i' :' back to init state', 'j' :' vertical and horizontal scaling', 'e' :' edit segment', 'b' :' edit segment keyboard', 'CTRL + t' :' translate structure', 'h' :' add subsegment', 'd' :' delete selected object', 'r' :' refresh', 'o' :' toggle overlay (<> CP mode) set origin (CP mode) ', 'm' :' toggle mode (point or segment)', 'n' : 'toggle node label display ', 'z' : 'change display parameters', 'x' : 'save .str2 and .ini file', 'w' :' display all layers', 'v' :' flip layout w.r.t y axis', 'f' :' toggle points nodes display', 'g' :' toggle segments nodes display', '=' :' increment layer ', ',' : 'this help', 'delete' :'delete selected', '$' :' decrement layer '}
[docs] def show(self,fig,ax,clear=False, dnodes=True, dedges=True, font_size=14, title=''): """ show layout Parameters ---------- clear : boolean dnodes : boolean dedges : boolean dlabels : boolean font_size : integer title : string """ if title=='': title = self.statename[self.state] axis = self.ax.axis() self.L.display['clear'] = clear self.L.display['fontsize'] = font_size self.L.display['title'] = title self.fig,self.ax = self.L.showGs(fig=self.fig,ax=self.ax,axis=axis,isonb=True) return(self.fig,self.ax)
[docs] def plotselptseg(self,pt,color='y',ms=10,marker='o'): """ plot selected point or segments Parameters ---------- pt : list list of points or segments to plot """ if len(pt)>0: pts = np.array([self.L.Gs.pos[x] for x in pt]) p1 = self.ax.plot(pts[:,0], pts[:,1],marker=marker, visible=True, color =color, ms=10, alpha=0.4) self.fig.canvas.draw() return self.fig,self.ax
[docs] def OnPress(self,event,verbose=True): """ Keyboard event handler Parameters ---------- event verbose """ # fig = plt.gcf() # ax = plt.gca() # selected self.nsel = 0 self.ptsel = np.array([]) self.evt = event.key if event.key == 'shift': self.shift_is_held = True if event.key == 'control': self.ctrl_is_held = True if event.key == 'alt': self.alt_is_held = True if verbose: try: print("Evenement :", self.evt,self.ddoc[self.evt]) except: print(self.evt + 'N/A') self.new_state()
[docs] def OnRelease(self, event): if event.key == 'shift': self.shift_is_held = False if event.key == 'control': self.ctrl_is_held = False if event.key == 'alt': self.alt_is_held = False
[docs] def OnClickRelease(self, event): pass
[docs] def OnMotion(self, event): pass
[docs] def OnClick(self, event): """ handle OnClick event Parameters ---------- event : See Also -------- pylayers.gis.layout.Layout.ispoint """ fig = self.fig#plt.gcf() ax = self.ax#plt.gca() self.nsel = 0 self.ptsel = np.array([]) xmin, xmax, ymin, ymax = self.ax.axis() #print( xmin,xmax,ymin,ymax) dx = xmax - xmin dy = ymax - ymin dd = np.minimum(dx, dy) if event.button == 1 and event.inaxes: self.evt = 'lclic' x = event.xdata y = event.ydata self.ptsel = np.array((x, y)) self.nsel = self.L.ispoint(self.ptsel, dd / 100) if event.button == 2 and event.inaxes: self.evt = 'cclic' x = event.xdata y = event.ydata self.ptsel = np.array((x, y)) self.nsel = self.L.ispoint(self.ptsel, dd / 100) if event.button == 3 and event.inaxes: self.evt = 'rclic' x = event.xdata y = event.ydata self.ptsel = np.array((x, y)) self.nsel = self.L.ispoint(self.ptsel, dd / 100) #print("Selected point coord : ", self.ptsel) #print("Selected point number: ", self.nsel) if self.nsel > 0: print("Selected segment : ", self.nsel) self.new_state()
[docs] def format_coord(self,x, y): col = int(x+0.5) row = int(y+0.5) string = 'x=%1.4f, y=%1.4f'%(x, y) try: string = string + ' ' + self.L.Gs.node[self.nsel]['name'] except: pass try: string = string + ' with ' +str(len(self.L.Gs.node[self.nsel]['ss_name'])) + 'subseg(s)' except: pass string = string + ' ///' +self.help[self.state] return string
# if col>=0 and col<numcols and row>=0 and row<numrows: # z = X[row,col] # return 'x=%1.4f, y=%1.4f, z=%1.4f'%(x, y, z) # else: # return 'x=%1.4f, y=%1.4f'%(x, y)
[docs] def update_state(self): """ update state """ # fig = plt.gcf() # ax = plt.gca() if not self.bundo: self.undoGs.append(self.L.Gs.copy()) if len(self.undoGs) > 50: self.undoGs.pop(0) self.ax.format_coord=self.format_coord if self.state == 'Init': self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.ax.title.set_text(self.statename[self.state]) self.selected_edge1 = 0 self.selected_pt1 = 0 self.selected_pt2 = 0 self.selectpt=[] self.selectseg=[] try: del self.pt_previous except: pass try: self.selector.set_active(False) print('inhib select') except: pass #ax.title.set_text(self.state) #ax.title.set_text('Init : ' # +self.L.display['activelayer']) try: self.p1[0].set_visible(False) except: pass try: self.p2[0].set_visible(False) except: pass try: self.segment[0].set_visible(False) except: pass # # If Layout has no point go to CP state # if self.L.Np==0: self.state='CP' self.update_state() if self.state == 'SP1': self.fig,self.ax = self.show(self.fig,self.ax,clear=False) self.ax.title.set_text(self.statename[self.state]) print('Selected node : '+str(self.nsel)) #ax.title.set_text(self.nsel)) self.selected_pt1 = self.nsel self.pt1 = np.array(self.L.Gs.pos[self.nsel]).reshape(2, 1) self.pt_previous = self.pt1 self.p1 = self.ax.plot([self.pt1[0]], [self.pt1[1]], 'o', visible=True) self.p1[0].set_color('yellow') self.p1[0].set_ms(10) self.p1[0].set_alpha(0.4) try: self.p2.set_visible(False) except: pass if self.state == 'SP2': self.p1[0].set_color('green') self.ax.title.set_text(self.statename[self.state]) #ax.title.set_text('Selected node : %d ' % (self.nsel)) print('Selected node : ' + str(self.nsel)) self.selected_pt2 = self.nsel self.pt2 = np.array(self.L.Gs.pos[self.nsel]).reshape(2, 1) self.pt_previous = self.pt2 self.p2 = self.ax.plot([self.pt2[0]], [self.pt2[1]], 'o', visible=True) self.p2[0].set_color('green') self.p2[0].set_ms(10) self.p2[0].set_alpha(0.4) #ax.title.set_text('SP2') if self.state == 'SS': self.ax.title.set_text(self.statename[self.state]) try: self.p1[0].set_visible(False) except: pass try: self.p2[0].set_visible(False) except: pass self.selected_edge1 = self.nsel nse = self.nsel ta, he = self.L.Gs.neighbors(nse) pta = np.array(self.L.Gs.pos[ta]) phe = np.array(self.L.Gs.pos[he]) alpha = self.L.display['alpha'] self.current_layer = self.L.Gs.node[nse]['name'] self.L.display['activelayer'] = self.current_layer #self.seg = linet(ax,pta,phe,alpha,'red',3.5) segdico = self.L.Gs.node[nse] self.fig,self.ax=self.show(self.fig,self.ax,clear=False) self.segment = self.ax.plot([pta[0],phe[0]], [pta[1],phe[1]], 'r',linewidth=3, visible=True) if 'ss_name' in segdico: cosegname = segdico['ss_name'] titre = 'Select Segment : %d (%d->%d) Layer : %s Coseg : %s ' % (nse, ta, he, self.current_layer, cosegname) else: titre = 'Select Segment : %d (%d->%d) Layer : %s' % (nse, ta, he, self.L.Gs.node[nse]['name']) print(titre) #ax.title.set_text(titre) self.L.show_nodes(ndlist=[nse], size=200, color='r', alpha=0.5) if self.state == 'SSS': self.ax.title.set_text(self.statename[self.state]) nse = self.selected_edge1 segdico = self.L.Gs.node[nse] z = segdico['ss_z'] #ax.title.set_text('SSS : '+self.L.Gs.node[nse]['name']+' ['+str(z[0])+']') print(self.L.Gs.node[nse]['name']+' ['+str(z[0])+']') self.segment[0].set_color('blue') # # Create Point state # if self.state == 'CP': self.ax.title.set_text(self.statename[self.state]) try: self.segment[0].set_visible(False) except: pass try: self.segment1[0].set_visible(False) except: pass try: self.segment2[0].set_visible(False) except: pass print('lclic : free point, +CTRL same x, +SHIFT: same y') self.fig,self.ax=self.show(self.fig,self.ax,clear=False) self.L.g2npy() # # Create Point on Segment state # if self.state == 'CPS': self.ax.title.set_text(self.statename[self.state]) self.selected_edge1 = self.nsel ta, he = self.L.Gs.neighbors(self.nsel) self.pta1 = np.array(self.L.Gs.pos[ta]) self.phe1 = np.array(self.L.Gs.pos[he]) self.current_layer = self.L.Gs.node[self.nsel]['name'] self.L.display['activelayer'] = self.current_layer self.segment1 = self.ax.plot([self.pta1[0],self.phe1[0]], [self.pta1[1],self.phe1[1]], 'g',linewidth=3, visible=True) try: self.segment2[0].set_visible(False) except: pass if self.state == 'CPSS': self.ax.title.set_text(self.statename[self.state]) self.selected_edge2 = self.nsel ta, he = self.L.Gs.neighbors(self.nsel) self.pta2 = np.array(self.L.Gs.pos[ta]) self.phe2 = np.array(self.L.Gs.pos[he]) self.current_layer = self.L.Gs.node[self.nsel]['name'] self.L.display['activelayer'] = self.current_layer self.segment2 = self.ax.plot([self.pta2[0],self.phe2[0]], [self.pta2[1],self.phe2[1]], 'c',linewidth=3, visible=True) if 'SM' in self.state: self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.ax.title.set_text(self.statename[self.state]) self.selected_edge1 = 0 self.selected_pt1 = 0 self.selected_pt2 = 0 try: del self.pt_previous except: pass # self.state='SM' #print self.state #print self.nsel #print self.selected_pt1 #print self.selected_pt2 self.fig.canvas.draw() return(self.fig,self.ax)
[docs] def new_state(self): """ layout editor state machine Parameters ---------- 'l' : select activelayer 'i' : back to init state 'j' : vertical and horizontal scaling 'e' : edit segment 'b' : edit segment keyboard 'CTRL + t' : translate structure 'h' : add subsegment 'd |Del' : delete subsegment 'r |F5' : refresh 'o' : toggle overlay (<> CP mode) set origin (CP mode) 'm' : toggle mode (point or segment) 'n' : toggle node label display 'z' : change display parameters 'CTRL+q' : quit 'x |CTRL+s' : save .str2 and .ini file 'w' : display all layers 'v' : flip layout w.r.t y axis 'f' : toggle points nodes display 'g' : toggle segments nodes display '=' : increment layer '$' : decrement layer """ fig = plt.gcf() ax = plt.gca() sl = self.L.sl cold = pyu.coldict() #print "In State ",self.state #print "In Event ",self.evt # # flip layout in y # if self.evt == ',': for k in self.ddoc.keys(): print(k,self.ddoc[k]) if self.evt == 'v': for n in self.L.Gs.pos: self.L.Gs.pos[n]=(self.L.Gs.pos[n][0],-self.L.Gs.pos[n][1]) self.update_state() return # # translation of layout (open a box) # # if self.evt == 't' : # offx,offy = offsetbox() # for n in self.L.Gs.pos: # self.L.Gs.pos[n]=(self.L.Gs.pos[n][0]+offx,self.L.Gs.pos[n][1]+offy) # self.update_state() # return if self.evt=='escape': self.state='Init' self.update_state() self.fig.canvas.draw() return if self.evt=='ctrl+z': self.bundo=True print( len(self.L.Gs)) if len (self.undoGs) >2: oGs=self.undoGs.pop(-1) oGs=self.undoGs.pop(-1) self.L.Gs=oGs self.L.g2npy() self.update_state() self.bundo=False return if self.evt=='t': if 'SM' in self.state: self.update_state() # fig=plt.gcf() # ax=plt.gca() if self.selected == 'pt': self.plotselptseg(self.selectseg,color='r') PP=self.L.pt[:,self.L.tahe[:,self.L.tgs[self.selectseg]]] if PP.shape[-1]!=0: self.fig,self.ax=plu.displot(PP[:,0],PP[:,1],fig=self.fig,ax=self.ax,color='r',linewidth=3,alpha=0.4) plt.draw() self.selected='seg' self.state='SMS' else: self.fig,self.ax= self.plotselptseg(self.selectpt) self.selected='pt' self.state='SMP' self.ax.title.set_text(self.statename[self.state]) # self.update_state() if self.evt == '3': self.L._show3() return # Choose layers to visualized # if self.evt == 'l': listchoices = self.L.name.keys() self.L.display['layers'] = multchoicebox('message', 'titre', listchoices) self.state = 'Init' self.update_state() return # # 'f' toggle points nodes display # if self.evt=='f': self.L.display['nodes'] = not self.L.display['nodes'] print (self.L.display['nodes']) self.update_state() return # # 'g' toggle segment nodes dislay # if self.evt=='g': self.L.display['ednodes'] = not self.L.display['ednodes'] print (self.L.display['ednodes']) self.update_state() return # # '=' Increment layer # if self.evt=='=': N = len(self.L.display['layerset']) index = self.L.display['layerset'].index(self.L.display['activelayer']) self.L.display['activelayer'] = self.L.display['layerset'][(index+1) % N] self.current_layer = self.L.display['activelayer'] print (self.current_layer) self.update_state() return # # '=' Decrement layer # if self.evt=='$': N = len(self.L.display['layerset']) index = self.L.display['layerset'].index(self.L.display['activelayer']) self.L.display['activelayer'] = self.L.display['layerset'][(index-1) % N] self.current_layer = self.L.display['activelayer'] print (self.current_layer) self.update_state() return # # 'i' : Back to init state # if self.evt == 'i': self.state = 'Init' self.update_state() return # # 'e' # if state == Init # egalize points coordinates # # if state == SS # edit segment properties # if self.evt == 'e': if (self.state == 'Init'): # # averaging one point coordinate along the smallest dimension # x1 = self.ax.get_xbound() y1 = self.ax.get_ybound() # get node list and edge list ndlist, edlist = self.L.get_zone([x1[0],x1[1],y1[0],y1[1]]) for k,nd in enumerate(ndlist): try: tp = np.vstack((tp,np.array(self.L.Gs.pos[nd]))) except: tp = np.array(self.L.Gs.pos[nd]) mtp = np.sum(tp,axis=0)/(k+1) stp = np.sqrt(np.sum((tp-mtp)*(tp-mtp),axis=0)/(k+1)) # if the standard deviation is lower than 10cm # averaging coordinates along the shortest axis if min(stp) < 0.10: ind = np.where(stp==min(stp))[0][0] for nd in ndlist: x = self.L.Gs.pos[nd][0] y = self.L.Gs.pos[nd][1] if ind ==0: self.L.Gs.pos[nd]=(mtp[0],y) if ind ==1: self.L.Gs.pos[nd]=(x,mtp[1]) plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return() if (self.state == 'SS') | (self.state =='SSS'): self.L.edit_segment(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state == 'SP1': self.L.edit_point(self.selected_pt1) self.state = 'Init' self.update_state() return if self.state == 'SMS': outdata=self.L.edit_segment(self.selectseg[0]) [self.L.edit_segment(s,outdata=outdata,gui=False) for s in self.selectseg] self.update_state() return # # "b" : enter a segment node value with keyboard # if self.evt == 'b': if self.state == 'Init': self.nsel = eval(raw_input("seg number :")) #self.L.edit_segment(nseg) self.state='SS' self.update_state() return # # j : vertical and horizontal scaling (Init) # if self.evt == 'j': if self.state == 'Init': vscale = eval(enterbox('enter vscale',argDefaultText='1.0')) hscale = eval(enterbox('enter hscale',argDefaultText='1.0')) for n in self.L.Gs.pos: self.L.Gs.pos[n]=(self.L.Gs.pos[n][0]*hscale,self.L.Gs.pos[n][1]*vscale) plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return # Init # h : horizontal scaling factor # add subsegment (SS) # if self.evt == 'h': # if self.state == 'Init': # hscale = eval(raw_input("horizontal scaling factor : ")) # for n in self.L.Gs.pos: # self.L.Gs.pos[n]=(self.L.Gs.pos[n][0]*hscale,self.L.Gs.pos[n][1]) # plt.axis('tight') # fig,ax = self.show(fig,ax,clear=True) # self.update_state() # return() if self.state == 'SS': result = self.L.add_subseg(self.selected_edge1,self.current_layer) if result: self.state = 'SSS' else : self.state = 'Init' self.update_state() return # # d : delete # if self.evt == 'd' or self.evt =='delete': if self.state == 'SP1': self.state = 'Init' self.L.del_points(self.selected_pt1) self.update_state() return if self.state == 'SS': self.L.del_segment(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state == 'SSS': self.L.del_subseg(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state=='SMP': # get boundary of the region if hasattr(self,'selectpt'): ptlist = self.selectpt self.selectpt=[] self.selectseg=[] self.L.del_points(ptlist) self.state = 'Init' self.update_state() return else : print ('no selected region') if self.state=='SMS': seglist = self.selectseg self.selectpt=[] self.selectseg=[] self.L.del_segment(seglist) self.state = 'Init' self.update_state() return else : print ('no selected region') # # r : Refresh # if self.evt == 'r' or self.evt == 'f5': #plt.axis('tight') plt.axis(self.L.display['box']) self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.state = 'Init' self.update_state() return # # o : Toggle overlay # if self.evt == 'o' and not self.ctrl_is_held: self.state='Init' self.update_state() if self.L.display['overlay']: self.L.display['overlay'] = False self.update_state() else: self.L.display['overlay'] = True self.update_state() return if self.evt == 'o' : self.set_origin = True # # F2 : Create point # if self.evt == 'f2': self.state = "CP" self.update_state() return # # m : Toggle mode edition Point | Segment # if self.evt == 'm': if self.state == "Init": self.state = "CP" elif self.state == "CP": self.state = "Init" self.update_state() return # # 'z' : change display parameters # if self.evt == 'z': self.L.displaygui() self.fig,self.ax = self.show(fig=self.fig,ax=self.ax,clear=True) return # # 'q' : quit interactive mode # # if self.evt == 'q': # plt.rcParams.update(self.rcconf) # fig.canvas.mpl_disconnect(self.L.cid1) # fig.canvas.mpl_disconnect(self.L.cid2) # return if self.evt == 'ctrl+q': plt.rcParams.update(self.rcconf) self.fig.canvas.mpl_disconnect(self.L.cid1) self.fig.canvas.mpl_disconnect(self.L.cid2) plt.close() return # # 'x' save structure # if self.evt == 'x' or self.evt =='ctrl+s': racine, ext = os.path.splitext(self.L.filename) filename = racine + '.str2' fileini = racine + '.ini' # Commented because ss_ce not updated #self.L.savestr2(filename) self.L.saveini(fileini) print( "structure saved in ", filename) print( "structure saved in ", fileini) return # # 'n' : toggle node label display # if self.evt == 'n': self.L.display['ndlabel'] = not self.L.display['ndlabel'] self.L.display['edlabel'] = not self.L.display['edlabel'] print( self.L.display['activelayer']) self.fig,ax = self.show(fig=self.fig,ax=self.ax,clear=True) self.fig.canvas.draw() return # # "w" : display all layers # if self.evt == 'w': # display all layer self.L.display['activelayer'] = self.L.name.keys() print( self.L.display['activelayer']) self.fig,self.ax = self.show(fig=self.fig,ax=self.ax,clear=True) return self.fig,self.ax # # Left clic and selected node is a point # if (self.evt == 'lclic') & (self.nsel < 0): # # select point 1 : Init -> SP1 # if self.state=='Init': # yellow point self.state = 'SP1' self.update_state() return # # select point 2 : SP1 --> SP2 # if self.state=='SP1': if self.nsel != self.selected_pt1: # green point self.state = 'SP2' self.update_state() return else: self.state = 'Init' # yellow point self.update_state() return # # Create point on selected segment orthogonaly to segment starting in # selected point # # Not finished # if self.state=='SS': # get the connection of the selected segment connect = self.L.Gs.node[self.selected_edge1]['connect'] if (self.nsel != connect[0]) & (self.nsel != connect[1]): self.L.add_nfpe(self.nsel,self.nsel,self.selected_edge1,self.selected_edge2) pass # # Left clic and selected node is a segment # if (self.evt == 'lclic') & (self.nsel > 0): if self.state=='Init': self.state = 'SS' self.update_state() return if self.state=='SS': self.nsel = self.selected_edge1 segdico = self.L.Gs.node[self.nsel] if 'ss_name' in segdico: self.state = 'SSS' else: self.state = 'CPS' self.update_state() return # # Right clic and selected node is a point # if (self.evt == 'rclic') & (self.nsel < 0): if self.state=='SP1': if self.nsel==self.selected_pt1: self.state = 'Init' self.update_state() return # # Right clic and selected node is a segment # if (self.evt == 'rclic') & (self.nsel > 0): if self.state=='SS': self.state = 'Init' self.update_state() return if self.state=='SSS': self.state = 'SS' self.update_state() return if self.state == 'CP': # create point on edge self.state = 'CPS' self.update_state() return if (self.state == 'CPS') & (self.nsel!= self.selected_edge1): # create point on edge self.state = 'CPSS' self.update_state() return # # Left clic # if (self.evt == 'lclic') and not (self.shift_is_held or self.alt_is_held or self.ctrl_is_held ): # add free node # or set origin if self.state == 'CP': if self.set_origin: offx = self.ptsel[0] offy = self.ptsel[1] print( offx,offy) xmin,xmax,ymin,ymax = self.L.display['box'] self.L.display['box'] = [xmin-offx,xmax-offx,ymin-offy,ymax-offy] self.set_origin=False self.set_x=True plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return if self.set_x: offx = self.ptsel[0] val = eval(enterbox('enter x value')) ratio = val/offx print( ratio) xmin,xmax,ymin,ymax = self.L.display['box'] self.L.display['box'] = [ratio*xmin,ratio*xmax,ymin,ymax] self.set_x=False self.set_y=True plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return if self.set_y: offx = self.ptsel[1] val = eval(enterbox('enter y value')) ratio = val/offx print( ratio) xmin,xmax,ymin,ymax = self.L.display['box'] self.L.display['box'] = [xmin,xmax,ratio*ymin,ratio*ymax] self.set_y=False plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return else: self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return if self.state == 'SP2': ta = self.selected_pt1 he = self.selected_pt2 segexist = self.L.isseg(ta,he) print( segexist) # if segment do not already exist, create it if not segexist: self.nsel = self.L.add_segment(ta, he,name=self.current_layer) else: print( "segment ("+str(ta)+","+str(he)+") already exists") self.L.g2npy() self.state = 'Init' self.update_state() return # create point on segment if self.state == 'CPS': pt_new = geu.ptonseg(self.pta1, self.phe1, self.ptsel) pd1 = pt_new - self.pta1 pd2 = self.phe1 - self.pta1 alpha = np.sqrt(np.dot(pd1, pd1)) / np.sqrt(np.dot(pd2, pd2)) if (pt_new != []): # calculate alpha self.L.add_pons(self.selected_edge1, 1. - alpha) self.current_layer = self.L.Gs.node[self.selected_edge1]['name'] self.state = 'Init' self.update_state() return # # Right Clic event # if (self.evt == 'rclic') or (self.evt == 'lclic' and self.ctrl_is_held ): if self.state == 'CP': try: self.ptsel[0] = self.pt_previous[0] self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return except: return if self.state=='SP2': if self.nsel == self.selected_pt1: self.p1[0].set_visible(False) self.p2[0].set_visible(False) self.nsel = self.selected_pt2 self.state = 'SP1' self.update_state() return if self.nsel == self.selected_pt2: self.p1[0].set_visible(False) self.p2[0].set_visible(False) self.nsel = self.selected_pt1 self.state = 'SP1' self.update_state() return # # right click : back to SS from CPS # if self.state == 'CPS': self.state = 'SS' self.update_state() return # # right click : back to CPS from CPSS # if self.state == 'CPSS': self.state = 'CPS' self.update_state(self.fig,self.ax) return # # Center Clic event # if (self.evt == 'cclic') or (self.evt == 'lclic' and self.shift_is_held ): if self.state == 'CP': try: self.ptsel[1] = self.pt_previous[1] self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return except: return # # Left clic and selected node is a point # def point_select_callback(eclick, erelease): 'eclick and erelease are the press and release events' self.update_state() if not (self.shift_is_held or self.ctrl_is_held): self.selectpt=[] self.selectseg=[] x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata # print x1,x2,y1,y2 if x1>x2: x1,x2=x2,x1 if y1>y2: y1,y2=y2,y1 # try: selectpt,selectseg = self.L.get_zone([x1,x2,y1,y2]) if not self.ctrl_is_held: self.selectpt.extend(selectpt) self.selectseg.extend(selectseg) self.selectseg=filter(lambda x: self.L.Gs.node[x]['connect'][0] in self.selectpt and self.L.Gs.node[x]['connect'][1] in self.selectpt, self.selectseg) self.selectpt=np.unique(self.selectpt).tolist() self.selectseg=np.unique(self.selectseg).tolist() else: [self.selectpt.pop(self.selectpt.index(x)) for x in selectpt if x in self.selectpt] [self.selectseg.pop(self.selectseg.index(x)) for x in selectseg if x in self.selectseg] # except: # print 'empty selection' print(self.selectpt,self.selectseg) self.plotselptseg(self.selectpt) self.selected='pt' print(self.state) def toggle_selector(event): if toggle_selector.RS.active: toggle_selector.RS.set_active(False) if not toggle_selector.RS.active: toggle_selector.RS.set_active(True) if self.evt == 'f1': #avoid conflict between zoom and selection # fm=plt.get_current_fig_manager() # if fm.toolbar._active == 'PAN': # fm.toolbar.pan() # if fm.toolbar._active == 'ZOOM': # fm.toolbar.zoom() self.state='SMP' toggle_selector.RS = RectangleSelector(self.ax, point_select_callback, drawtype='box', useblit=True, button=[1,3], # don't use middle button minspanx=5, minspany=5, spancoords='pixels') self.selector = toggle_selector.RS self.update_state() if self.evt == 'f9': print(self.selectpt, self.selectseg)
#print self.selectsl # plt.connect('key_press_event', toggle_selector) if __name__ == '__main__': import doctest doctest.testmod()