Пример #1
0
class SimulationCanvas( object ):
    """A canvas where blocks can be dragged around and connected up"""

    size = ( width, height ) = ( 550, 300 )

    def __init__( self, frame ):
        # Create the canvas
        self.canvas = Canvas( frame,
                             width=self.width, height=self.height,
                             relief=RIDGE,
                             background=colours["background"],
                             borderwidth=1 )
        # Add event handlers for dragable items
        self.canvas.tag_bind ( "DRAG", "<ButtonPress-1>", self.mouse_down )
        #self.canvas.tag_bind ("DRAG", "<ButtonRelease-1>", self.mouse_release)
        self.canvas.tag_bind ( "DRAG", "<Enter>", self.enter )
        self.canvas.tag_bind ( "DRAG", "<Leave>", self.leave )
        self.canvas.pack( side=TOP )

        # Some default locations
        self.PREVIEW_WIDTH = 80
        self.PREVIEW_LOCATION = ( self.PREVIEW_X, self.PREVIEW_Y ) = ( 15, 30 )


        # Draw a "preview" area
        self.canvas.create_line( self.PREVIEW_WIDTH, 0, self.PREVIEW_WIDTH, self.height, dash=True )

        # A dict indexed by unique ID of elements in the canvas.
        self.blocks = {}

    def preview_actor( self, codefile ):
        """
        Display a preview of an actor or compisite actor in the canvas,
        it will be dragable into desired position
        """
        logging.debug( "Creating a preview of %(name)s on simulation canvas." % {'name':codefile.name} )

        logging.debug( "Deleting any existing items still tagged 'preview'" )
        self.canvas.delete( "preview" )

        block = CanvasBlock( self.canvas, codefile, *self.PREVIEW_LOCATION )
        self.blocks[block.id] = block



    def mouse_down( self, event ):
        logging.debug( "The mouse was pressed at (%d, %d)" % ( event.x, event.y ) )
        logging.debug( "The mouse went down on a block. Binding mouse release..." )
        selected = self.canvas.gettags( "current" )
        logging.debug( "Currently selected items tags are %s" % selected.__repr__() )
        self.selected_name = [tag for tag in selected if tag.startswith( "name:" ) ][0][5:]
        self.selected_id = [tag for tag in selected if tag.startswith( "id:" ) ][0][3:]
        self.selected_type = [tag for tag in selected if tag.startswith( "type:" ) ][0][5:]
        logging.debug( "Block selected was %s with id:%s" % ( self.selected_name, self.selected_id ) )

        #self.canvas.addtag( 'Selected', 'withtag', self.selected_id )
        logging.debug( "Current blocks are: %s" % self.blocks )
        #self.blocks[block_id].set_colour( colours['selected'] )

        if self.selected_type == "block" or self.selected_type == "text":
            self.blocks[self.selected_id].select(event.x, event.y)
            self.canvas.bind( "<ButtonRelease-1>", self.block_move_mouse_release )
        elif self.selected_type.startswith("input") or self.selected_type.startswith("output"):
            self.blocks[self.selected_id].select_port(self.selected_type)
            self.canvas.bind( "<ButtonRelease-1>", self.port_connect_mouse_release )
        else:
            logging.info("Tried to select %s" % self.selected_type)

    
    def block_move_mouse_release( self, event ):
        logging.debug( "The mouse was released at (%d, %d)" % ( event.x, event.y ) )
        self.canvas.bind( "<ButtonRelease-1>", lambda e: None )
        if event.x >= 0 and event.x <= self.canvas.winfo_width() \
            and event.y >= 0 and event.y <= self.canvas.winfo_height():
                logging.debug( "Valid move inside canvas. Relocating block." )
                self.blocks[self.selected_id].move_to(event.x, event.y)
                if event.x >= self.PREVIEW_WIDTH:
                    if self.blocks[self.selected_id].is_preview():
                        logging.info( "Moved out of preview zone, adding new component to model" )
                        #TODO HERE - add to model compiler or what ever...
                    self.blocks[self.selected_id].unselect()
                else:
                    self.blocks[self.selected_id].preview()
        else:
            logging.info( "Invalid move." )

    def port_connect_mouse_release( self, event ):
        logging.debug( "The mouse was released at (%d, %d)" % ( event.x, event.y ) )
        self.canvas.bind( "<ButtonRelease-1>", lambda e: None )
        if event.x >= 0 and event.x <= self.canvas.winfo_width() \
            and event.y >= 0 and event.y <= self.canvas.winfo_height():
                logging.debug( "Valid location inside canvas." )

                event.widget.itemconfigure( "Selected", fill="#000000" )
                event.widget.itemconfigure( "type:text", fill="#000000" )

                #block = self.canvas.gettags("Selected")
                #logging.debug("Block moved was made up of these components: %s" % block.__repr__())
                self.canvas.dtag( "Selected", "Selected" )

        else:
            logging.info( "Invalid wiring." )

    def enter( self, event ):
        logging.debug( "Enter" )

    def leave( self, event ):
        logging.debug( "Leaving" )
Пример #2
0
class histogramWidget:
    BACKGROUND = "#222222"
    EDGE_HISTOGRAM_COLOR = "#999999"
    NODE_HISTOGRAM_COLOR = "#555555"
    TOOLTIP_COLOR="#FFFF55"
    
    PADDING = 8
    CENTER_WIDTH = 1
    CENTER_COLOR = "#444444"
    ZERO_GAP = 1
    UPDATE_WIDTH = 9
    UPDATE_COLOR = "#FFFFFF"
    HANDLE_WIDTH = 5
    HANDLE_COLOR = "#FFFFFF"
    HANDLE_LENGTH = (HEIGHT-2*PADDING)
    TICK_COLOR = "#FFFFFF"
    TICK_WIDTH = 10
    TICK_FACTOR = 2
    
    LOG_BASE = 10.0
    
    def __init__(self, parent, x, y, width, height, data, logScale=False, callback=None):
        self.canvas = Canvas(parent,background=histogramWidget.BACKGROUND, highlightbackground=histogramWidget.BACKGROUND,width=width,height=height)
        self.canvas.place(x=x,y=y,width=width,height=height,bordermode="inside")
        
        self.logScale = logScale
        
        self.callback = callback
        
        self.edgeBars = []
        self.nodeBars = []
        
        self.binValues = []
        self.numBins = len(data) - 1
        
        self.currentBin = self.numBins     # start the slider at the highest bin
        
        edgeRange = 0.0
        nodeRange = 0.0
        
        for values in data.itervalues():
            if values[0] > edgeRange:
                edgeRange = values[0]
            if values[1] > nodeRange:
                nodeRange = values[1]
        
        edgeRange = float(edgeRange)    # ensure that it will yield floats when used in calculations...
        nodeRange = float(nodeRange)
        
        if logScale:
            edgeRange = math.log(edgeRange,histogramWidget.LOG_BASE)
            nodeRange = math.log(nodeRange,histogramWidget.LOG_BASE)
        
        # calculate the center line - but don't draw it yet
        self.center_x = histogramWidget.PADDING
        if self.logScale:
            self.center_x += histogramWidget.TICK_WIDTH+histogramWidget.PADDING
        self.center_y = height/2
        self.center_x2 = width-histogramWidget.PADDING
        self.center_y2 = self.center_y + histogramWidget.CENTER_WIDTH
        
        # draw the histograms with background-colored baseline rectangles (these allow tooltips to work on very short bars with little area)
        self.bar_interval = float(self.center_x2 - self.center_x) / (self.numBins+1)
        bar_x = self.center_x
        edge_y2 = self.center_y-histogramWidget.PADDING
        edge_space = edge_y2-histogramWidget.PADDING
        node_y = self.center_y2+histogramWidget.PADDING
        node_space = (height-node_y)-histogramWidget.PADDING
        
        thresholds = sorted(data.iterkeys())
        for threshold in thresholds:
            self.binValues.append(threshold)
            edgeWeight = data[threshold][0]
            nodeWeight = data[threshold][1]
            if logScale:
                if edgeWeight > 0:
                    edgeWeight = math.log(edgeWeight,histogramWidget.LOG_BASE)
                else:
                    edgeWeight = 0
                if nodeWeight > 0:
                    nodeWeight = math.log(nodeWeight,histogramWidget.LOG_BASE)
                else:
                    nodeWeight = 0
            
            bar_x2 = bar_x + self.bar_interval
            
            edge_y = histogramWidget.PADDING + int(edge_space*(1.0-edgeWeight/edgeRange))
            edge = self.canvas.create_rectangle(bar_x,edge_y,bar_x2,edge_y2,fill=histogramWidget.EDGE_HISTOGRAM_COLOR,width=0)
            baseline = self.canvas.create_rectangle(bar_x,edge_y2+histogramWidget.ZERO_GAP,bar_x2,edge_y2+histogramWidget.PADDING,fill=histogramWidget.BACKGROUND,width=0)
            self.canvas.addtag_withtag("Threshold: %f" % threshold,edge)
            self.canvas.addtag_withtag("No. Edges: %i" % data[threshold][0],edge)
            self.canvas.tag_bind(edge,"<Enter>",self.updateToolTip)
            self.canvas.tag_bind(edge,"<Leave>",self.updateToolTip)
            self.edgeBars.append(edge)
            self.canvas.addtag_withtag("Threshold: %f" % threshold,baseline)
            self.canvas.addtag_withtag("No. Edges: %i" % data[threshold][0],baseline)
            self.canvas.tag_bind(baseline,"<Enter>",self.updateToolTip)
            self.canvas.tag_bind(baseline,"<Leave>",self.updateToolTip)
            
            node_y2 = node_y + int(node_space*(nodeWeight/nodeRange))
            node = self.canvas.create_rectangle(bar_x,node_y,bar_x2,node_y2,fill=histogramWidget.NODE_HISTOGRAM_COLOR,width=0)
            baseline = self.canvas.create_rectangle(bar_x,node_y-histogramWidget.PADDING,bar_x2,node_y-histogramWidget.ZERO_GAP,fill=histogramWidget.BACKGROUND,width=0)
            self.canvas.addtag_withtag("Threshold: %f" % threshold,node)
            self.canvas.addtag_withtag("No. Nodes: %i" % data[threshold][1],node)
            self.canvas.tag_bind(node,"<Enter>",self.updateToolTip)
            self.canvas.tag_bind(node,"<Leave>",self.updateToolTip)
            self.nodeBars.append(node)
            self.canvas.addtag_withtag("Threshold: %f" % threshold,baseline)
            self.canvas.addtag_withtag("No. Nodes: %i" % data[threshold][1],baseline)
            self.canvas.tag_bind(baseline,"<Enter>",self.updateToolTip)
            self.canvas.tag_bind(baseline,"<Leave>",self.updateToolTip)
            
            bar_x = bar_x2
        
        # now draw the center line
        self.centerLine = self.canvas.create_rectangle(self.center_x,self.center_y,self.center_x2,self.center_y2,fill=histogramWidget.CENTER_COLOR,width=0)
        
        # draw the tick marks if logarithmic
        if self.logScale:
            tick_x = histogramWidget.PADDING
            tick_x2 = histogramWidget.PADDING+histogramWidget.TICK_WIDTH
            
            start_y = edge_y2
            end_y = histogramWidget.PADDING
            dist = start_y-end_y
            while dist > 1:
                dist /= histogramWidget.TICK_FACTOR
                self.canvas.create_rectangle(tick_x,end_y+dist-1,tick_x2,end_y+dist,fill=histogramWidget.TICK_COLOR,width=0)
            
            start_y = node_y
            end_y = height-histogramWidget.PADDING
            dist = end_y-start_y
            while dist > 1:
                dist /= histogramWidget.TICK_FACTOR
                self.canvas.create_rectangle(tick_x,end_y-dist,tick_x2,end_y-dist+1,fill=histogramWidget.TICK_COLOR,width=0)
        
        # draw the update bar
        bar_x = self.currentBin*self.bar_interval + self.center_x
        bar_x2 = self.center_x2
        bar_y = self.center_y-histogramWidget.UPDATE_WIDTH/2
        bar_y2 = bar_y+histogramWidget.UPDATE_WIDTH
        self.updateBar = self.canvas.create_rectangle(bar_x,bar_y,bar_x2,bar_y2,fill=histogramWidget.UPDATE_COLOR,width=0)
        
        # draw the handle
        handle_x = self.currentBin*self.bar_interval-histogramWidget.HANDLE_WIDTH/2+self.center_x
        handle_x2 = handle_x+histogramWidget.HANDLE_WIDTH
        handle_y = self.center_y-histogramWidget.HANDLE_LENGTH/2
        handle_y2 = handle_y+histogramWidget.HANDLE_LENGTH
        self.handleBar = self.canvas.create_rectangle(handle_x,handle_y,handle_x2,handle_y2,fill=histogramWidget.HANDLE_COLOR,width=0)
        self.canvas.tag_bind(self.handleBar, "<Button-1>",self.adjustHandle)
        self.canvas.tag_bind(self.handleBar, "<B1-Motion>",self.adjustHandle)
        self.canvas.tag_bind(self.handleBar, "<ButtonRelease-1>",self.adjustHandle)
        parent.bind("<Left>",lambda e: self.nudgeHandle(e,-1))
        parent.bind("<Right>",lambda e: self.nudgeHandle(e,1))
        
        # init the tooltip as nothing
        self.toolTipBox = self.canvas.create_rectangle(0,0,0,0,state="hidden",fill=histogramWidget.TOOLTIP_COLOR,width=0)
        self.toolTip = self.canvas.create_text(0,0,state="hidden",anchor="nw")
        self.canvas.bind("<Enter>",self.updateToolTip)
        self.canvas.bind("<Leave>",self.updateToolTip)
    
    def adjustHandle(self, event):
        newBin = int(self.numBins*(event.x-self.center_x)/float(self.center_x2-self.center_x)+0.5)
        if newBin == self.currentBin or newBin < 0 or newBin > self.numBins:
            return
        
        self.canvas.move(self.handleBar,(newBin-self.currentBin)*self.bar_interval,0)
        self.currentBin = newBin
        if self.callback != None:
            self.callback(self.binValues[newBin])
    
    def nudgeHandle(self, event, distance):
        temp = self.currentBin+distance
        if temp < 0 or temp > self.numBins:
            return
        
        self.canvas.move(self.handleBar,distance*self.bar_interval,0)
        self.currentBin += distance
        
        if self.callback != None:
            self.callback(self.binValues[self.currentBin])
    
    def update(self, currentBins):
        currentBar = self.canvas.coords(self.updateBar)
        self.canvas.coords(self.updateBar,currentBins*self.bar_interval+self.center_x,currentBar[1],currentBar[2],currentBar[3])
    
    def updateToolTip(self, event):
        allTags = self.canvas.gettags(self.canvas.find_overlapping(event.x,event.y,event.x+1,event.y+1))
        
        if len(allTags) == 0:
            self.canvas.itemconfig(self.toolTipBox,state="hidden")
            self.canvas.itemconfig(self.toolTip,state="hidden")
            return
        
        outText = ""
        for t in allTags:
            if t == "current":
                continue
            outText += t + "\n"
        
        outText = outText[:-1]  # strip the last return
        
        self.canvas.coords(self.toolTip,event.x+20,event.y)
        self.canvas.itemconfig(self.toolTip,state="normal",text=outText,anchor="nw")
        # correct if our tooltip is off screen
        textBounds = self.canvas.bbox(self.toolTip)
        if textBounds[2] >= WIDTH-2*histogramWidget.PADDING:
            self.canvas.itemconfig(self.toolTip, anchor="ne")
            self.canvas.coords(self.toolTip,event.x-20,event.y)
            if textBounds[3] >= HEIGHT-2*histogramWidget.PADDING:
                self.canvas.itemconfig(self.toolTip, anchor="se")
        elif textBounds[3] >= HEIGHT-2*histogramWidget.PADDING:
            self.canvas.itemconfig(self.toolTip, anchor="sw")
        
        # draw the box behind it
        self.canvas.coords(self.toolTipBox,self.canvas.bbox(self.toolTip))
        self.canvas.itemconfig(self.toolTipBox, state="normal")
Пример #3
0
class MainCanvas(object):
    """
    The shapefile displaying device based on TKinter Canvas

    Attributes
    ----------

    shapes           : array
                      The spatial units
    bbox             : array
                      The bounding box: minX, minY, maxX, maxY
    shp_type         : integer
                      The shape types: SHP_TYPE_POINT,SHP_TYPE_LINE,SHP_TYPE_POLYGON
    root             : Tk
                      The Tk Object
    attributeName    : string
                      The attribute name
    datalist         : array
                      The attribute data
                      
    """
    def __init__(self,shapes,bbox,shp_type,root,attributeName,datalist):
        self.shapes = shapes
        self.bbox = bbox
        self.shp_type = shp_type
        self.root = root
        self.attributeName = attributeName
        self.datalist = datalist
        self.__createCanvas()
         
    def __createCanvas(self):
        """
        Create the canvas and draw all the spatial objects
        """ 
        self.canvasRoot = Toplevel()
        self.canvasRoot.title(self.attributeName)
        self.canvasRoot.lower(belowThis = self.root)
        self.mainCanvas = Canvas(self.canvasRoot, bg = 'black', width = canvasWidth+margin_x, height = canvasHeight+margin_y, scrollregion=('-50c','-50c',"50c","50c"))

        #Change by Sagar for Full Screen
        self.canvasRoot.state('zoomed')
        self.canvasRoot.geometry=("1000x900+0+0")
        #Change End
        
        self.__drawShape()
        self.mainCanvas.pack()
        
    def __drawShape(self):
        """
        Draw all the spatial objects on the canvas
        """
        minX, minY, maxX, maxY = self.bbox[0],self.bbox[1],self.bbox[2],self.bbox[3]
        # calculate ratios of visualization
        ratiox = canvasWidth/(maxX-minX)
        ratioy = canvasHeight/(maxY-minY)
        # take the smaller ratio of window size to geographic distance
        ratio = ratiox
        if ratio>ratioy:
            ratio = ratioy
        
        if self.shp_type == SHP_TYPE_POINT:
            self.__drawPoints(minX, minY, maxX, maxY, ratio)
        elif self.shp_type == SHP_TYPE_LINE:
            self.__drawPolylines(minX, minY, maxX, maxY, ratio)
        elif self.shp_type == SHP_TYPE_POLYGON:
            self.__drawPolygons(minX, minY, maxX, maxY, ratio)
      
    def __drawPoints(self,minX, minY, maxX, maxY,ratio):
        """
        Draw points on the canvas
        """  
        tag_count = 0
        # loop through each point
        for point in self.shapes:
            #define an empty xylist for holding converted coordinates
            x = int((point.x-minX)*ratio)+margin_x/2
            y = int((maxY-point.y)*ratio)+margin_y/2
            _point = self.mainCanvas.create_oval(x-2, y-2, x+2, y+2,outline=point.color,  
                               fill=point.color, width=2, tags = self.datalist[tag_count])
            self.mainCanvas.tag_bind( _point, '<ButtonPress-1>', self.__showAttriInfo)
            tag_count += 1
        
    def __drawPolylines(self,minX, minY, maxX, maxY,ratio):
        """
        Draw polylines on the canvas
        """     
        tag_count = 0
        # loop through each polyline
        for polyline in self.shapes:
            #define an empty xylist for holding converted coordinates
            xylist = []
            # loops through each point and calculate the window coordinates, put in xylist
            for j in range(len(polyline.x)):
                pointx = int((polyline.x[j]-minX)*ratio)+margin_x/2
                pointy = int((maxY-polyline.y[j])*ratio)+margin_y/2
                xylist.append(pointx)
                xylist.append(pointy)
            # loop through each part of the polyline
            for k in range(polyline.partsNum):
                #get the end sequence number of points in the part
                if (k==polyline.partsNum-1):
                    endPointIndex = len(polyline.x)
                else:
                    endPointIndex = polyline.partsIndex[k+1]
                # define a temporary list for holding the part coordinates
                tempXYlist = []
                #take out points' coordinates for the part and add to the temporary list
                for m in range(polyline.partsIndex[k], endPointIndex):
                    tempXYlist.append(xylist[m*2])
                    tempXYlist.append(xylist[m*2+1])
                # create the line
                _line = self.mainCanvas.create_line(tempXYlist,fill=polyline.color, tags = self.datalist[tag_count])
                self.mainCanvas.tag_bind( _line, '<ButtonPress-1>', self.__showAttriInfo)            
            tag_count += 1
  
    def __drawPolygons(self,minX, minY, maxX, maxY,ratio):
        """
        Draw polygons on the canvas
        """      
        tag_count = 0
        for polygon in self.shapes:
            #define an empty xylist for holding converted coordinates
            xylist = []
            # loops through each point and calculate the window coordinates, put in xylist
            for point in polygon.points:
                pointx = int((point.x -minX)*ratio) + +margin_x/0.5
                pointy = int((maxY- point.y)*ratio) + +margin_y/5
                xylist.append(pointx)
                xylist.append(pointy)
##            print xylist
            """
            polyline.partsIndex is a tuple data type holding the starting points for each
            part. For example, if the polyline.partsIndex of a polyline equals to (0, 4, 9),
            and the total points, which is calcuate by len(polyline.points) equals to 13.
            This means that the polyline has three parts, and the each part would have the points
            as follows.
            
            part 1: p0,p1,p2,p3
            part 2: p4,p5,p6,p7,p8
            part 3: p9,p10,p11,p12
            
            The xylist would be:
            xylist = [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4....x12, y12]
            where 
            xylist[0] = x0
            xylist[1] = y0
            xylist[2] = x1
            xylist[3] = y1
            .....
            
            To draw the first part of polyline, we want to get tempXYlist as
        
            tempXYlist = [x0, y0, x1, y1, x2, y2, x3, y3]
            
            At this time, m is in range(0,4)
            
            xylist[m*2] would be is x0(when m=0), x1(when m=1), x2(when m=2), x3(when m=3)
        
            xylist[m*2+1] would be is y0(when m=0), y1(when m=1), y2(when m=2), y3(when m=3)
            """
            
            for k in range(polygon.partsNum):
                #get the end sequence number of points in the part
                if (k==polygon.partsNum-1):
                    endPointIndex = len(polygon.points)
                else:
                    endPointIndex = polygon.partsIndex[k+1]
         
                #Define a temporary list for holding the part coordinates
                tempXYlist = []
                tempXlist  = []
                tempYlist  = []
                #take out points' coordinates for the part and add to the temporary list
                for m in range(polygon.partsIndex[k], endPointIndex):            
                    tempXYlist.append(xylist[m*2])
                    tempXYlist.append(xylist[m*2+1])
                    tempXlist.append (xylist[m*2])
                    tempYlist.append (xylist[m*2+1])

                xMax = max(tempXlist)
                xMin = min(tempXlist)

                yMax = max(tempYlist)
                yMin = min(tempYlist)

                if xMax == xMin:
                    xMin = xMax - 1

                if yMax == yMin:
                    yMin = yMax - 1

                tempVar = False
                #while not tempVar:
                xPoint = rd.randrange(xMin,xMax)
                yPoint = rd.randrange(yMin,yMax)
                tempVar =  point_inside_polygon(xPoint,yPoint,tempXYlist)
                
                
                startIndex = polygon.partsIndex[k] #start index for our positive polygon.                
                tempPoints = polygon.points[startIndex: endPointIndex]#we get our temppoints to help use create our polygon using positive data
                newPolygon = Polygon(tempPoints) #here we create our polygons using positve data
                area = newPolygon.getArea() # Calculate the area
                
                #Sagar Jha center added to calculate centroid of polygon
                center = newPolygon.getCentroid()
                xCenter = int((center.x -minX)*ratio) + +margin_x/0.5
                yCenter = int((maxY- center.y)*ratio) + +margin_y/5
                
                if area > 0:
                    _polygon = self.mainCanvas.create_polygon(tempXYlist,activefill="blue",fill=polygon.color,outline="blue",tags = self.datalist[tag_count])#creating our polygon outline
                    #print k,_polygon
                    #Michigan Special Condition according to its 2 parts
                    if tag_count == 48:
                        if k==4:
                            _oval    = self.mainCanvas.create_oval(xCenter, yCenter,xCenter +5,yCenter+ 5, outline="red",fill="green", width=2,tags = center)
                            dict1[_oval]=[center.x,center.y]
                    else:
                        if k==0:
                            #print "Tag Count: ",tag_count," ",self.mainCanvas.gettags(_polygon)[0]
                            _oval    = self.mainCanvas.create_oval(xCenter, yCenter,xCenter +5,yCenter+ 5, outline="red",fill="green", width=2,tags = center)
                            dict1[_oval]=[center.x,center.y]
                            #_oval1   = self.mainCanvas.create_oval(xPoint, yPoint,xPoint +5,yPoint+ 5, outline="red",fill="green", width=2)
                else:
                    # If it is a hole, fill with the same color as the canvas background color 
                    _polygon = self.mainCanvas.create_polygon(tempXYlist,fill="black",outline="black", tags = self.datalist[tag_count])
                #self.mainCanvas.tag_bind( _polygon, '<ButtonPress-1>', self.__showAttriInfo)
                #self.mainCanvas.tag_bind( _oval, '<ButtonPress-1>', self.__showAttriInfo)
            tag_count += 1
            
    def __showAttriInfo(self,event):
        """
        Show attribute information of clicked unit
        """        
        widget_id=event.widget.find_closest(event.x, event.y)
        
        if widget_id[0] in dict1.keys():
            print widget_id[0], dict1[widget_id[0]][0],dict1[widget_id[0]][1]
        else:
            print "click!!!!", widget_id
            print self.attributeName+" is: "+self.mainCanvas.gettags(widget_id)[0]
Пример #4
0
class MainCanvas(object):
    """
    The shapefile displaying device based on TKinter Canvas

    Attributes
    ----------

    shapes           : array
                      The spatial units
    bbox             : array
                      The bounding box: minX, minY, maxX, maxY
    shp_type         : integer
                      The shape types: SHP_TYPE_POINT,SHP_TYPE_LINE,SHP_TYPE_POLYGON
    root             : Tk
                      The Tk Object
    attributeName    : string
                      The attribute name
    datalist         : array
                      The attribute data
                      
    """
    def __init__(self, shapes, bbox, shp_type, root, attributeName, datalist):
        self.shapes = shapes
        self.bbox = bbox
        self.shp_type = shp_type
        self.root = root
        self.attributeName = attributeName
        self.datalist = datalist
        self.__createCanvas()

    def __createCanvas(self):
        """
        Create the canvas and draw all the spatial objects
        """
        self.canvasRoot = Toplevel()
        self.canvasRoot.title(self.attributeName)
        self.canvasRoot.lower(belowThis=self.root)
        self.mainCanvas = Canvas(self.canvasRoot,
                                 bg='black',
                                 width=canvasWidth + margin_x,
                                 height=canvasHeight + margin_y,
                                 scrollregion=('-50c', '-50c', "50c", "50c"))

        #Change by Sagar for Full Screen
        self.canvasRoot.state('zoomed')
        self.canvasRoot.geometry = ("1000x900+0+0")
        #Change End

        self.__drawShape()
        self.mainCanvas.pack()

    def __drawShape(self):
        """
        Draw all the spatial objects on the canvas
        """
        minX, minY, maxX, maxY = self.bbox[0], self.bbox[1], self.bbox[
            2], self.bbox[3]
        # calculate ratios of visualization
        ratiox = canvasWidth / (maxX - minX)
        ratioy = canvasHeight / (maxY - minY)
        # take the smaller ratio of window size to geographic distance
        ratio = ratiox
        if ratio > ratioy:
            ratio = ratioy

        if self.shp_type == SHP_TYPE_POINT:
            self.__drawPoints(minX, minY, maxX, maxY, ratio)
        elif self.shp_type == SHP_TYPE_LINE:
            self.__drawPolylines(minX, minY, maxX, maxY, ratio)
        elif self.shp_type == SHP_TYPE_POLYGON:
            self.__drawPolygons(minX, minY, maxX, maxY, ratio)

    def __drawPoints(self, minX, minY, maxX, maxY, ratio):
        """
        Draw points on the canvas
        """
        tag_count = 0
        # loop through each point
        for point in self.shapes:
            #define an empty xylist for holding converted coordinates
            x = int((point.x - minX) * ratio) + margin_x / 2
            y = int((maxY - point.y) * ratio) + margin_y / 2
            _point = self.mainCanvas.create_oval(x - 2,
                                                 y - 2,
                                                 x + 2,
                                                 y + 2,
                                                 outline=point.color,
                                                 fill=point.color,
                                                 width=2,
                                                 tags=self.datalist[tag_count])
            self.mainCanvas.tag_bind(_point, '<ButtonPress-1>',
                                     self.__showAttriInfo)
            tag_count += 1

    def __drawPolylines(self, minX, minY, maxX, maxY, ratio):
        """
        Draw polylines on the canvas
        """
        tag_count = 0
        # loop through each polyline
        for polyline in self.shapes:
            #define an empty xylist for holding converted coordinates
            xylist = []
            # loops through each point and calculate the window coordinates, put in xylist
            for j in range(len(polyline.x)):
                pointx = int((polyline.x[j] - minX) * ratio) + margin_x / 2
                pointy = int((maxY - polyline.y[j]) * ratio) + margin_y / 2
                xylist.append(pointx)
                xylist.append(pointy)
            # loop through each part of the polyline
            for k in range(polyline.partsNum):
                #get the end sequence number of points in the part
                if (k == polyline.partsNum - 1):
                    endPointIndex = len(polyline.x)
                else:
                    endPointIndex = polyline.partsIndex[k + 1]
                # define a temporary list for holding the part coordinates
                tempXYlist = []
                #take out points' coordinates for the part and add to the temporary list
                for m in range(polyline.partsIndex[k], endPointIndex):
                    tempXYlist.append(xylist[m * 2])
                    tempXYlist.append(xylist[m * 2 + 1])
                # create the line
                _line = self.mainCanvas.create_line(
                    tempXYlist,
                    fill=polyline.color,
                    tags=self.datalist[tag_count])
                self.mainCanvas.tag_bind(_line, '<ButtonPress-1>',
                                         self.__showAttriInfo)
            tag_count += 1

    def __drawPolygons(self, minX, minY, maxX, maxY, ratio):
        """
        Draw polygons on the canvas
        """
        tag_count = 0
        for polygon in self.shapes:
            #define an empty xylist for holding converted coordinates
            xylist = []
            # loops through each point and calculate the window coordinates, put in xylist
            for point in polygon.points:
                pointx = int((point.x - minX) * ratio) + +margin_x / 0.5
                pointy = int((maxY - point.y) * ratio) + +margin_y / 5
                xylist.append(pointx)
                xylist.append(pointy)
##            print xylist
            """
            polyline.partsIndex is a tuple data type holding the starting points for each
            part. For example, if the polyline.partsIndex of a polyline equals to (0, 4, 9),
            and the total points, which is calcuate by len(polyline.points) equals to 13.
            This means that the polyline has three parts, and the each part would have the points
            as follows.
            
            part 1: p0,p1,p2,p3
            part 2: p4,p5,p6,p7,p8
            part 3: p9,p10,p11,p12
            
            The xylist would be:
            xylist = [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4....x12, y12]
            where 
            xylist[0] = x0
            xylist[1] = y0
            xylist[2] = x1
            xylist[3] = y1
            .....
            
            To draw the first part of polyline, we want to get tempXYlist as
        
            tempXYlist = [x0, y0, x1, y1, x2, y2, x3, y3]
            
            At this time, m is in range(0,4)
            
            xylist[m*2] would be is x0(when m=0), x1(when m=1), x2(when m=2), x3(when m=3)
        
            xylist[m*2+1] would be is y0(when m=0), y1(when m=1), y2(when m=2), y3(when m=3)
            """

            for k in range(polygon.partsNum):
                #get the end sequence number of points in the part
                if (k == polygon.partsNum - 1):
                    endPointIndex = len(polygon.points)
                else:
                    endPointIndex = polygon.partsIndex[k + 1]

                #Define a temporary list for holding the part coordinates
                tempXYlist = []
                tempXlist = []
                tempYlist = []
                #take out points' coordinates for the part and add to the temporary list
                for m in range(polygon.partsIndex[k], endPointIndex):
                    tempXYlist.append(xylist[m * 2])
                    tempXYlist.append(xylist[m * 2 + 1])
                    tempXlist.append(xylist[m * 2])
                    tempYlist.append(xylist[m * 2 + 1])

                xMax = max(tempXlist)
                xMin = min(tempXlist)

                yMax = max(tempYlist)
                yMin = min(tempYlist)

                if xMax == xMin:
                    xMin = xMax - 1

                if yMax == yMin:
                    yMin = yMax - 1

                tempVar = False
                #while not tempVar:
                xPoint = rd.randrange(xMin, xMax)
                yPoint = rd.randrange(yMin, yMax)
                tempVar = point_inside_polygon(xPoint, yPoint, tempXYlist)

                startIndex = polygon.partsIndex[
                    k]  #start index for our positive polygon.
                tempPoints = polygon.points[
                    startIndex:
                    endPointIndex]  #we get our temppoints to help use create our polygon using positive data
                newPolygon = Polygon(
                    tempPoints
                )  #here we create our polygons using positve data
                area = newPolygon.getArea()  # Calculate the area

                #Sagar Jha center added to calculate centroid of polygon
                center = newPolygon.getCentroid()
                xCenter = int((center.x - minX) * ratio) + +margin_x / 0.5
                yCenter = int((maxY - center.y) * ratio) + +margin_y / 5

                if area > 0:
                    _polygon = self.mainCanvas.create_polygon(
                        tempXYlist,
                        activefill="blue",
                        fill=polygon.color,
                        outline="blue",
                        tags=self.datalist[tag_count]
                    )  #creating our polygon outline
                    #print k,_polygon
                    #Michigan Special Condition according to its 2 parts
                    if tag_count == 48:
                        if k == 4:
                            _oval = self.mainCanvas.create_oval(xCenter,
                                                                yCenter,
                                                                xCenter + 5,
                                                                yCenter + 5,
                                                                outline="red",
                                                                fill="green",
                                                                width=2,
                                                                tags=center)
                            dict1[_oval] = [center.x, center.y]
                    else:
                        if k == 0:
                            #print "Tag Count: ",tag_count," ",self.mainCanvas.gettags(_polygon)[0]
                            _oval = self.mainCanvas.create_oval(xCenter,
                                                                yCenter,
                                                                xCenter + 5,
                                                                yCenter + 5,
                                                                outline="red",
                                                                fill="green",
                                                                width=2,
                                                                tags=center)
                            dict1[_oval] = [center.x, center.y]
                            #_oval1   = self.mainCanvas.create_oval(xPoint, yPoint,xPoint +5,yPoint+ 5, outline="red",fill="green", width=2)
                else:
                    # If it is a hole, fill with the same color as the canvas background color
                    _polygon = self.mainCanvas.create_polygon(
                        tempXYlist,
                        fill="black",
                        outline="black",
                        tags=self.datalist[tag_count])
                #self.mainCanvas.tag_bind( _polygon, '<ButtonPress-1>', self.__showAttriInfo)
                #self.mainCanvas.tag_bind( _oval, '<ButtonPress-1>', self.__showAttriInfo)
            tag_count += 1

    def __showAttriInfo(self, event):
        """
        Show attribute information of clicked unit
        """
        widget_id = event.widget.find_closest(event.x, event.y)

        if widget_id[0] in dict1.keys():
            print widget_id[0], dict1[widget_id[0]][0], dict1[widget_id[0]][1]
        else:
            print "click!!!!", widget_id
            print self.attributeName + " is: " + self.mainCanvas.gettags(
                widget_id)[0]
Пример #5
0
class SimulationCanvas(object):
    """A canvas where blocks can be dragged around and connected up"""

    size = (width, height) = (550, 300)

    def __init__(self, frame):
        # Create the canvas
        self.canvas = Canvas(frame,
                             width=self.width,
                             height=self.height,
                             relief=RIDGE,
                             background=colours["background"],
                             borderwidth=1)
        # Add event handlers for dragable items
        self.canvas.tag_bind("DRAG", "<ButtonPress-1>", self.mouse_down)
        #self.canvas.tag_bind ("DRAG", "<ButtonRelease-1>", self.mouse_release)
        self.canvas.tag_bind("DRAG", "<Enter>", self.enter)
        self.canvas.tag_bind("DRAG", "<Leave>", self.leave)
        self.canvas.pack(side=TOP)

        # Some default locations
        self.PREVIEW_WIDTH = 80
        self.PREVIEW_LOCATION = (self.PREVIEW_X, self.PREVIEW_Y) = (15, 30)

        # Draw a "preview" area
        self.canvas.create_line(self.PREVIEW_WIDTH,
                                0,
                                self.PREVIEW_WIDTH,
                                self.height,
                                dash=True)

        # A dict indexed by unique ID of elements in the canvas.
        self.blocks = {}

    def preview_actor(self, codefile):
        """
        Display a preview of an actor or compisite actor in the canvas,
        it will be dragable into desired position
        """
        logging.debug("Creating a preview of %(name)s on simulation canvas." %
                      {'name': codefile.name})

        logging.debug("Deleting any existing items still tagged 'preview'")
        self.canvas.delete("preview")

        block = CanvasBlock(self.canvas, codefile, *self.PREVIEW_LOCATION)
        self.blocks[block.id] = block

    def mouse_down(self, event):
        logging.debug("The mouse was pressed at (%d, %d)" % (event.x, event.y))
        logging.debug(
            "The mouse went down on a block. Binding mouse release...")
        selected = self.canvas.gettags("current")
        logging.debug("Currently selected items tags are %s" %
                      selected.__repr__())
        self.selected_name = [
            tag for tag in selected if tag.startswith("name:")
        ][0][5:]
        self.selected_id = [tag for tag in selected
                            if tag.startswith("id:")][0][3:]
        self.selected_type = [
            tag for tag in selected if tag.startswith("type:")
        ][0][5:]
        logging.debug("Block selected was %s with id:%s" %
                      (self.selected_name, self.selected_id))

        #self.canvas.addtag( 'Selected', 'withtag', self.selected_id )
        logging.debug("Current blocks are: %s" % self.blocks)
        #self.blocks[block_id].set_colour( colours['selected'] )

        if self.selected_type == "block" or self.selected_type == "text":
            self.blocks[self.selected_id].select(event.x, event.y)
            self.canvas.bind("<ButtonRelease-1>",
                             self.block_move_mouse_release)
        elif self.selected_type.startswith(
                "input") or self.selected_type.startswith("output"):
            self.blocks[self.selected_id].select_port(self.selected_type)
            self.canvas.bind("<ButtonRelease-1>",
                             self.port_connect_mouse_release)
        else:
            logging.info("Tried to select %s" % self.selected_type)

    def block_move_mouse_release(self, event):
        logging.debug("The mouse was released at (%d, %d)" %
                      (event.x, event.y))
        self.canvas.bind("<ButtonRelease-1>", lambda e: None)
        if event.x >= 0 and event.x <= self.canvas.winfo_width() \
            and event.y >= 0 and event.y <= self.canvas.winfo_height():
            logging.debug("Valid move inside canvas. Relocating block.")
            self.blocks[self.selected_id].move_to(event.x, event.y)
            if event.x >= self.PREVIEW_WIDTH:
                if self.blocks[self.selected_id].is_preview():
                    logging.info(
                        "Moved out of preview zone, adding new component to model"
                    )
                    #TODO HERE - add to model compiler or what ever...
                self.blocks[self.selected_id].unselect()
            else:
                self.blocks[self.selected_id].preview()
        else:
            logging.info("Invalid move.")

    def port_connect_mouse_release(self, event):
        logging.debug("The mouse was released at (%d, %d)" %
                      (event.x, event.y))
        self.canvas.bind("<ButtonRelease-1>", lambda e: None)
        if event.x >= 0 and event.x <= self.canvas.winfo_width() \
            and event.y >= 0 and event.y <= self.canvas.winfo_height():
            logging.debug("Valid location inside canvas.")

            event.widget.itemconfigure("Selected", fill="#000000")
            event.widget.itemconfigure("type:text", fill="#000000")

            #block = self.canvas.gettags("Selected")
            #logging.debug("Block moved was made up of these components: %s" % block.__repr__())
            self.canvas.dtag("Selected", "Selected")

        else:
            logging.info("Invalid wiring.")

    def enter(self, event):
        logging.debug("Enter")

    def leave(self, event):
        logging.debug("Leaving")