/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/view.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/view.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 122 by bh, Mon Apr 29 18:04:54 2002 UTC revision 356 by bh, Mon Dec 9 10:32:15 2002 UTC
# Line 129  class ZoomInTool(RectTool): Line 129  class ZoomInTool(RectTool):
129              Tool.MouseUp(self, event)              Tool.MouseUp(self, event)
130              sx, sy = self.start              sx, sy = self.start
131              cx, cy = self.current              cx, cy = self.current
132              if sx == cx and sy == cy:              if sx == cx or sy == cy:
133                  # Just a mouse click. Simply zoom in by a factor of two                  # Just a mouse click or a degenerate rectangle. Simply
134                    # zoom in by a factor of two
135                    # FIXME: For a click this is the desired behavior but should we
136                    # really do this for degenrate rectagles as well or
137                    # should we ignore them?
138                  self.view.ZoomFactor(2, center = (cx, cy))                  self.view.ZoomFactor(2, center = (cx, cy))
139              else:              else:
140                  # A drag. Zoom in to the rectangle                  # A drag. Zoom in to the rectangle
# Line 140  class ZoomInTool(RectTool): Line 144  class ZoomInTool(RectTool):
144  class ZoomOutTool(RectTool):  class ZoomOutTool(RectTool):
145    
146      """The Zoom-Out Tool"""      """The Zoom-Out Tool"""
147        
148      def Name(self):      def Name(self):
149          return "ZoomOutTool"          return "ZoomOutTool"
150    
# Line 149  class ZoomOutTool(RectTool): Line 153  class ZoomOutTool(RectTool):
153              Tool.MouseUp(self, event)              Tool.MouseUp(self, event)
154              sx, sy = self.start              sx, sy = self.start
155              cx, cy = self.current              cx, cy = self.current
156              if sx == cx and sy == cy:              if sx == cx or sy == cy:
157                  # Just a mouse click. Simply zoom out by a factor of two                  # Just a mouse click or a degenerate rectangle. Simply
158                  self.view.ZoomFactor(0.5, center = (cy, cy))                  # zoom out by a factor of two.
159                    # FIXME: For a click this is the desired behavior but should we
160                    # really do this for degenrate rectagles as well or
161                    # should we ignore them?
162                    self.view.ZoomFactor(0.5, center = (cx, cy))
163              else:              else:
164                  # A drag. Zoom out to the rectangle                  # A drag. Zoom out to the rectangle
165                  self.view.ZoomOutToRect((min(sx, cx), min(sy, cy),                  self.view.ZoomOutToRect((min(sx, cx), min(sy, cy),
# Line 167  class PanTool(Tool): Line 175  class PanTool(Tool):
175    
176      def MouseMove(self, event):      def MouseMove(self, event):
177          if self.dragging:          if self.dragging:
             x0, y0 = self.current  
178              Tool.MouseMove(self, event)              Tool.MouseMove(self, event)
179                sx, sy = self.start
180              x, y = self.current              x, y = self.current
181              width, height = self.view.GetSizeTuple()              width, height = self.view.GetSizeTuple()
182    
183                bitmapdc = wx.wxMemoryDC()
184                bitmapdc.SelectObject(self.view.bitmap)
185    
186              dc = self.view.drag_dc              dc = self.view.drag_dc
187              dc.Blit(0, 0, width, height, dc, x0 - x, y0 - y)              dc.Blit(0, 0, width, height, bitmapdc, sx - x, sy - y)
188    
189      def MouseUp(self, event):      def MouseUp(self, event):
190          if self.dragging:          if self.dragging:
# Line 180  class PanTool(Tool): Line 192  class PanTool(Tool):
192              sx, sy = self.start              sx, sy = self.start
193              cx, cy = self.current              cx, cy = self.current
194              self.view.Translate(cx - sx, cy - sy)              self.view.Translate(cx - sx, cy - sy)
195            
196  class IdentifyTool(Tool):  class IdentifyTool(Tool):
197    
198      """The "Identify" Tool"""      """The "Identify" Tool"""
199        
200      def Name(self):      def Name(self):
201          return "IdentifyTool"          return "IdentifyTool"
202    
# Line 238  class MapPrintout(wx.wxPrintout): Line 250  class MapPrintout(wx.wxPrintout):
250          renderer = PrinterRender(dc, scale, (offx, offy), resolution = resx)          renderer = PrinterRender(dc, scale, (offx, offy), resolution = resx)
251          renderer.RenderMap(self.map)          renderer.RenderMap(self.map)
252          return wx.true          return wx.true
253            
254    
255  class MapCanvas(wxWindow, Publisher):  class MapCanvas(wxWindow, Publisher):
256    
# Line 247  class MapCanvas(wxWindow, Publisher): Line 259  class MapCanvas(wxWindow, Publisher):
259      def __init__(self, parent, winid, interactor):      def __init__(self, parent, winid, interactor):
260          wxWindow.__init__(self, parent, winid)          wxWindow.__init__(self, parent, winid)
261          self.SetBackgroundColour(wxColour(255, 255, 255))          self.SetBackgroundColour(wxColour(255, 255, 255))
262    
263            # the map displayed in this canvas. Set with SetMap()
264          self.map = None          self.map = None
265    
266            # scale and offset describe the transformation from projected
267            # coordinates to window coordinates.
268          self.scale = 1.0          self.scale = 1.0
269          self.offset = (0, 0)          self.offset = (0, 0)
270    
271            # whether the user is currently dragging the mouse, i.e. moving
272            # the mouse while pressing a mouse button
273          self.dragging = 0          self.dragging = 0
274    
275            # the currently active tool
276          self.tool = None          self.tool = None
277          self.redraw_on_idle = 0  
278            # The current mouse position of the last OnMotion event or None
279            # if the mouse is outside the window.
280          self.current_position = None          self.current_position = None
281    
282            # the bitmap serving as backing store
283            self.bitmap = None
284    
285            # the interactor
286            self.interactor = interactor
287            self.interactor.Subscribe(SELECTED_SHAPE, self.shape_selected)
288    
289            # keep track of which layers/shapes are selected to make sure we
290            # only redraw when necessary
291            self.last_selected_layer = None
292            self.last_selected_shape = None
293    
294            # subscribe the WX events we're interested in
295          EVT_PAINT(self, self.OnPaint)          EVT_PAINT(self, self.OnPaint)
296          EVT_LEFT_DOWN(self, self.OnLeftDown)          EVT_LEFT_DOWN(self, self.OnLeftDown)
297          EVT_LEFT_UP(self, self.OnLeftUp)          EVT_LEFT_UP(self, self.OnLeftUp)
298          EVT_MOTION(self, self.OnMotion)          EVT_MOTION(self, self.OnMotion)
299          EVT_LEAVE_WINDOW(self, self.OnLeaveWindow)          EVT_LEAVE_WINDOW(self, self.OnLeaveWindow)
300          wx.EVT_IDLE(self, self.OnIdle)          wx.EVT_SIZE(self, self.OnSize)
         self.interactor = interactor  
         self.interactor.Subscribe(SELECTED_SHAPE, self.shape_selected)  
301    
302      def __del__(self):      def __del__(self):
303          wxWindow.__del__(self)          wxWindow.__del__(self)
# Line 270  class MapCanvas(wxWindow, Publisher): Line 306  class MapCanvas(wxWindow, Publisher):
306      def OnPaint(self, event):      def OnPaint(self, event):
307          dc = wxPaintDC(self)          dc = wxPaintDC(self)
308          if self.map is not None and self.map.HasLayers():          if self.map is not None and self.map.HasLayers():
309              # We have a non-empty map. Redraw it in idle time              self.do_redraw()
             self.redraw_on_idle = 1  
310          else:          else:
311              # If we've got no map or if the map is empty, simply clear              # If we've got no map or if the map is empty, simply clear
312              # the screen.              # the screen.
313                
314              # XXX it's probably possible to get rid of this. The              # XXX it's probably possible to get rid of this. The
315              # background color of the window is already white and the              # background color of the window is already white and the
316              # only thing we may have to do is to call self.Refresh()              # only thing we may have to do is to call self.Refresh()
317              # with a true argument in the right places.              # with a true argument in the right places.
318              dc.BeginDrawing()              dc.BeginDrawing()
319              dc.Clear()                          dc.Clear()
320              dc.EndDrawing()              dc.EndDrawing()
321    
322      def do_redraw(self):      def do_redraw(self):
323          # This should only be called if we have a non-empty map. We draw          # This should only be called if we have a non-empty map.
324          # it into a memory DC and then blit it to the screen.  
325            # Get the window size.
326          width, height = self.GetSizeTuple()          width, height = self.GetSizeTuple()
         bitmap = wx.wxEmptyBitmap(width, height)  
         dc = wx.wxMemoryDC()  
         dc.SelectObject(bitmap)  
         dc.BeginDrawing()  
327    
328          # clear the background          # If self.bitmap's still there, reuse it. Otherwise redraw it
329          dc.SetBrush(wx.wxWHITE_BRUSH)          if self.bitmap is not None:
330          dc.SetPen(wx.wxTRANSPARENT_PEN)              bitmap = self.bitmap
         dc.DrawRectangle(0, 0, width, height)  
   
         if 1: #self.interactor.selected_map is self.map:  
             selected_layer = self.interactor.selected_layer  
             selected_shape = self.interactor.selected_shape  
331          else:          else:
332              selected_layer = None              bitmap = wx.wxEmptyBitmap(width, height)
333              selected_shape = None              dc = wx.wxMemoryDC()
334                dc.SelectObject(bitmap)
335                dc.BeginDrawing()
336    
337          # draw the map into the bitmap              # clear the background
338          renderer = ScreenRenderer(dc, self.scale, self.offset)              dc.SetBrush(wx.wxWHITE_BRUSH)
339          renderer.RenderMap(self.map, selected_layer, selected_shape)              dc.SetPen(wx.wxTRANSPARENT_PEN)
340                dc.DrawRectangle(0, 0, width, height)
341    
342                if 1: #self.interactor.selected_map is self.map:
343                    selected_layer = self.interactor.selected_layer
344                    selected_shape = self.interactor.selected_shape
345                else:
346                    selected_layer = None
347                    selected_shape = None
348    
349          dc.EndDrawing()              # draw the map into the bitmap
350                renderer = ScreenRenderer(dc, self.scale, self.offset)
351    
352                # Pass the entire bitmap as update region to the renderer.
353                # We're redrawing the whole bitmap, after all.
354                renderer.RenderMap(self.map, (0, 0, width, height),
355                                   selected_layer, selected_shape)
356    
357                dc.EndDrawing()
358                dc.SelectObject(wx.wxNullBitmap)
359                self.bitmap = bitmap
360    
361          # blit the bitmap to the screen          # blit the bitmap to the screen
362            dc = wx.wxMemoryDC()
363            dc.SelectObject(bitmap)
364          clientdc = wxClientDC(self)          clientdc = wxClientDC(self)
365          clientdc.BeginDrawing()          clientdc.BeginDrawing()
366          clientdc.Blit(0, 0, width, height, dc, 0, 0)          clientdc.Blit(0, 0, width, height, dc, 0, 0)
# Line 322  class MapCanvas(wxWindow, Publisher): Line 371  class MapCanvas(wxWindow, Publisher):
371          printout = MapPrintout(self.map)          printout = MapPrintout(self.map)
372          printer.Print(self, printout, wx.true)          printer.Print(self, printout, wx.true)
373          printout.Destroy()          printout.Destroy()
374            
375      def SetMap(self, map):      def SetMap(self, map):
376          redraw_channels = (LAYERS_CHANGED, LAYER_LEGEND_CHANGED,          redraw_channels = (LAYERS_CHANGED, LAYER_LEGEND_CHANGED,
377                             LAYER_VISIBILITY_CHANGED)                             LAYER_VISIBILITY_CHANGED)
378          if self.map is not None:          if self.map is not None:
379              for channel in redraw_channels:              for channel in redraw_channels:
380                  self.map.Unsubscribe(channel, self.redraw)                  self.map.Unsubscribe(channel, self.full_redraw)
381              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,
382                                   self.projection_changed)                                   self.projection_changed)
383          self.map = map          self.map = map
384          if self.map is not None:          if self.map is not None:
385              for channel in redraw_channels:              for channel in redraw_channels:
386                  self.map.Subscribe(channel, self.redraw)                  self.map.Subscribe(channel, self.full_redraw)
387              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.projection_changed)              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.projection_changed)
388          self.FitMapToWindow()          self.FitMapToWindow()
389          # force a redraw. If map is not empty, it's already been called          # force a redraw. If map is not empty, it's already been called
390          # by FitMapToWindow but if map is empty it hasn't been called          # by FitMapToWindow but if map is empty it hasn't been called
391          # yet so we have to explicitly call it.          # yet so we have to explicitly call it.
392          self.redraw()          self.full_redraw()
393    
394      def Map(self):      def Map(self):
395            """Return the map displayed by this canvas"""
396          return self.map          return self.map
397    
398      def redraw(self, *args):      def redraw(self, *args):
399          self.Refresh(0)          self.Refresh(0)
400    
401        def full_redraw(self, *args):
402            self.bitmap = None
403            self.redraw()
404    
405      def projection_changed(self, *args):      def projection_changed(self, *args):
406          self.FitMapToWindow()          self.FitMapToWindow()
407          self.redraw()          self.full_redraw()
408    
409      def set_view_transform(self, scale, offset):      def set_view_transform(self, scale, offset):
410          self.scale = scale          self.scale = scale
411          self.offset = offset          self.offset = offset
412          self.redraw()          self.full_redraw()
413    
414      def proj_to_win(self, x, y):      def proj_to_win(self, x, y):
415          """\          """\
# Line 372  class MapCanvas(wxWindow, Publisher): Line 426  class MapCanvas(wxWindow, Publisher):
426          return ((x - offx) / self.scale, (offy - y) / self.scale)          return ((x - offx) / self.scale, (offy - y) / self.scale)
427    
428      def FitRectToWindow(self, rect):      def FitRectToWindow(self, rect):
429            """Fit the rectangular region given by rect into the window.
430            
431            Set scale so that rect (in projected coordinates) just fits into
432            the window and center it.
433            """
434          width, height = self.GetSizeTuple()          width, height = self.GetSizeTuple()
435          llx, lly, urx, ury = rect          llx, lly, urx, ury = rect
436          if llx == urx or lly == ury:          if llx == urx or lly == ury:
# Line 385  class MapCanvas(wxWindow, Publisher): Line 444  class MapCanvas(wxWindow, Publisher):
444          self.set_view_transform(scale, (offx, offy))          self.set_view_transform(scale, (offx, offy))
445    
446      def FitMapToWindow(self):      def FitMapToWindow(self):
447          """\          """Fit the map to the window
448          Set the scale and offset so that the map is centered in the          
449          window          Set the scale so that the map fits exactly into the window and
450            center it in the window.
451          """          """
452          bbox = self.map.ProjectedBoundingBox()          bbox = self.map.ProjectedBoundingBox()
453          if bbox is not None:          if bbox is not None:
# Line 413  class MapCanvas(wxWindow, Publisher): Line 473  class MapCanvas(wxWindow, Publisher):
473          self.set_view_transform(scale, offset)          self.set_view_transform(scale, offset)
474    
475      def ZoomOutToRect(self, rect):      def ZoomOutToRect(self, rect):
476          # rect is given in window coordinates          """Zoom out to fit the currently visible region into rect.
477    
478            The rect parameter is given in window coordinates
479            """
480          # determine the bbox of the displayed region in projected          # determine the bbox of the displayed region in projected
481          # coordinates          # coordinates
482          width, height = self.GetSizeTuple()          width, height = self.GetSizeTuple()
# Line 431  class MapCanvas(wxWindow, Publisher): Line 493  class MapCanvas(wxWindow, Publisher):
493          self.set_view_transform(scale, (offx, offy))          self.set_view_transform(scale, (offx, offy))
494    
495      def Translate(self, dx, dy):      def Translate(self, dx, dy):
496            """Move the map by dx, dy pixels"""
497          offx, offy = self.offset          offx, offy = self.offset
498          self.set_view_transform(self.scale, (offx + dx, offy + dy))          self.set_view_transform(self.scale, (offx + dx, offy + dy))
499    
500        def SelectTool(self, tool):
501            """Make tool the active tool.
502    
503            The parameter should be an instance of Tool or None to indicate
504            that no tool is active.
505            """
506            self.tool = tool
507    
508      def ZoomInTool(self):      def ZoomInTool(self):
509          self.tool = ZoomInTool(self)          """Start the zoom in tool"""
510            self.SelectTool(ZoomInTool(self))
511    
512      def ZoomOutTool(self):      def ZoomOutTool(self):
513          self.tool = ZoomOutTool(self)          """Start the zoom out tool"""
514            self.SelectTool(ZoomOutTool(self))
515    
516      def PanTool(self):      def PanTool(self):
517          self.tool = PanTool(self)          """Start the pan tool"""
518            self.SelectTool(PanTool(self))
519    
520      def IdentifyTool(self):      def IdentifyTool(self):
521          self.tool = IdentifyTool(self)          """Start the identify tool"""
522            self.SelectTool(IdentifyTool(self))
523    
524      def LabelTool(self):      def LabelTool(self):
525          self.tool = LabelTool(self)          """Start the label tool"""
526            self.SelectTool(LabelTool(self))
527    
528      def CurrentTool(self):      def CurrentTool(self):
529            """Return the name of the current tool or None if no tool is active"""
530          return self.tool and self.tool.Name() or None          return self.tool and self.tool.Name() or None
531    
532      def CurrentPosition(self):      def CurrentPosition(self):
# Line 487  class MapCanvas(wxWindow, Publisher): Line 564  class MapCanvas(wxWindow, Publisher):
564              self.tool.MouseDown(event)              self.tool.MouseDown(event)
565              self.tool.Show(self.drag_dc)              self.tool.Show(self.drag_dc)
566              self.dragging = 1              self.dragging = 1
567            
568      def OnLeftUp(self, event):      def OnLeftUp(self, event):
         self.ReleaseMouse()  
569          self.set_current_position(event)          self.set_current_position(event)
570          if self.dragging:          if self.dragging:
571                self.ReleaseMouse()
572              self.tool.Hide(self.drag_dc)              self.tool.Hide(self.drag_dc)
573              self.tool.MouseUp(event)              self.tool.MouseUp(event)
574              self.drag_dc = None              self.drag_dc = None
# Line 507  class MapCanvas(wxWindow, Publisher): Line 584  class MapCanvas(wxWindow, Publisher):
584      def OnLeaveWindow(self, event):      def OnLeaveWindow(self, event):
585          self.set_current_position(None)          self.set_current_position(None)
586    
587      def OnIdle(self, event):      def OnSize(self, event):
588          if self.redraw_on_idle:          # the window's size has changed. We have to get a new bitmap. If
589              self.do_redraw()          # we want to be clever we could try to get by without throwing
590          self.redraw_on_idle = 0          # everything away. E.g. when the window gets smaller, we could
591            # either keep the bitmap or create the new one from the old one.
592            # Even when the window becomes larger some parts of the bitmap
593            # could be reused.
594            self.full_redraw()
595    
596      def shape_selected(self, layer, shape):      def shape_selected(self, layer, shape):
597          self.redraw()          """Redraw the map.
598    
599            Receiver for the SELECTED_SHAPE messages. Try to redraw only
600            when necessary.
601            """
602            # A redraw is necessary when the display has to change, which
603            # means that either the status changes from having no selection
604            # to having a selection shape or vice versa, or when the fact
605            # whether there is a selection at all doesn't change, when the
606            # shape which is selected has changed (which means that layer or
607            # shapeid changes).
608            if ((shape is not None or self.last_selected_shape is not None)
609                and (shape != self.last_selected_shape
610                     or layer != self.last_selected_layer)):
611                self.full_redraw()
612    
613            # remember the selection so we can compare when it changes again.
614            self.last_selected_layer = layer
615            self.last_selected_shape = shape
616    
617        def unprojected_rect_around_point(self, x, y, dist):
618            """return a rect dist pixels around (x, y) in unprojected corrdinates
619    
620            The return value is a tuple (minx, miny, maxx, maxy) suitable a
621            parameter to a layer's ShapesInRegion method.
622            """
623            map_proj = self.map.projection
624            if map_proj is not None:
625                inverse = map_proj.Inverse
626            else:
627                inverse = None
628    
629            xs = []
630            ys = []
631            for dx, dy in ((-1, -1), (1, -1), (1, 1), (-1, 1)):
632                px, py = self.win_to_proj(x + dist * dx, y + dist * dy)
633                if inverse:
634                    px, py = inverse(px, py)
635                xs.append(px)
636                ys.append(py)
637            return (min(xs), min(ys), max(xs), max(ys))
638    
639      def find_shape_at(self, px, py, select_labels = 0, selected_layer = 1):      def find_shape_at(self, px, py, select_labels = 0, searched_layer = None):
640          """Determine the shape at point px, py in window coords          """Determine the shape at point px, py in window coords
641    
642          Return the shape and the corresponding layer as a tuple (layer,          Return the shape and the corresponding layer as a tuple (layer,
# Line 525  class MapCanvas(wxWindow, Publisher): Line 646  class MapCanvas(wxWindow, Publisher):
646          search through the labels. If a label is found return it's index          search through the labels. If a label is found return it's index
647          as the shape and None as the layer.          as the shape and None as the layer.
648    
649          If the optional parameter selected_layer is true (default), only          If the optional parameter searched_layer is given (or not None
650          search in the currently selected layer.          which it defaults to), only search in that layer.
651          """          """
652          map_proj = self.map.projection          map_proj = self.map.projection
653          if map_proj is not None:          if map_proj is not None:
# Line 539  class MapCanvas(wxWindow, Publisher): Line 660  class MapCanvas(wxWindow, Publisher):
660    
661          if select_labels:          if select_labels:
662              labels = self.map.LabelLayer().Labels()              labels = self.map.LabelLayer().Labels()
663                
664              if labels:              if labels:
665                  dc = wxClientDC(self)                  dc = wxClientDC(self)
666                  font = wxFont(10, wx.wxSWISS, wx.wxNORMAL, wx.wxNORMAL)                  font = wxFont(10, wx.wxSWISS, wx.wxNORMAL, wx.wxNORMAL)
# Line 571  class MapCanvas(wxWindow, Publisher): Line 692  class MapCanvas(wxWindow, Publisher):
692                      if x <= px < x + width and y <= py <= y + height:                      if x <= px < x + width and y <= py <= y + height:
693                          return None, i                          return None, i
694    
695          if selected_layer:          if searched_layer:
696              layer = self.interactor.SelectedLayer()              layers = [searched_layer]
             if layer is not None:  
                 layers = [layer]  
             else:  
                 # no layer selected. Use an empty list to effectively  
                 # ignore all layers.  
                 layers = []  
697          else:          else:
698              layers = self.map.Layers()              layers = self.map.Layers()
699    
# Line 591  class MapCanvas(wxWindow, Publisher): Line 706  class MapCanvas(wxWindow, Publisher):
706    
707              filled = layer.fill is not None              filled = layer.fill is not None
708              stroked = layer.stroke is not None              stroked = layer.stroke is not None
709                    
710              layer_proj = layer.projection              layer_proj = layer.projection
711              if layer_proj is not None:              if layer_proj is not None:
712                  inverse = layer_proj.Inverse                  inverse = layer_proj.Inverse
713              else:              else:
714                  inverse = None                  inverse = None
715                    
716              shapetype = layer.ShapeType()              shapetype = layer.ShapeType()
717    
718              select_shape = -1              select_shape = -1
719    
720                # Determine the ids of the shapes that overlap a tiny area
721                # around the point. For layers containing points we have to
722                # choose a larger size of the box we're testing agains so
723                # that we take the size of the markers into account
724                # FIXME: Once the markers are more flexible this part has to
725                # become more flexible too, of course
726                if shapetype == SHAPETYPE_POINT:
727                    box = self.unprojected_rect_around_point(px, py, 5)
728                else:
729                    box = self.unprojected_rect_around_point(px, py, 1)
730                shape_ids = layer.ShapesInRegion(box)
731                shape_ids.reverse()
732    
733              if shapetype == SHAPETYPE_POLYGON:              if shapetype == SHAPETYPE_POLYGON:
734                  for i in range(layer.NumShapes() - 1, -1, -1):                  for i in shape_ids:
735                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      result = point_in_polygon_shape(layer.shapefile.cobject(),
736                                                      i,                                                      i,
737                                                      filled, stroked,                                                      filled, stroked,
# Line 613  class MapCanvas(wxWindow, Publisher): Line 742  class MapCanvas(wxWindow, Publisher):
742                          select_shape = i                          select_shape = i
743                          break                          break
744              elif shapetype == SHAPETYPE_ARC:              elif shapetype == SHAPETYPE_ARC:
745                  for i in range(layer.NumShapes() - 1, -1, -1):                  for i in shape_ids:
746                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      result = point_in_polygon_shape(layer.shapefile.cobject(),
747                                                      i, 0, 1,                                                      i, 0, 1,
748                                                      map_proj, layer_proj,                                                      map_proj, layer_proj,
# Line 623  class MapCanvas(wxWindow, Publisher): Line 752  class MapCanvas(wxWindow, Publisher):
752                          select_shape = i                          select_shape = i
753                          break                          break
754              elif shapetype == SHAPETYPE_POINT:              elif shapetype == SHAPETYPE_POINT:
755                  for i in range(layer.NumShapes() - 1, -1, -1):                  for i in shape_ids:
756                      shape = layer.Shape(i)                      shape = layer.Shape(i)
757                      x, y = shape.Points()[0]                      x, y = shape.Points()[0]
758                      if inverse:                      if inverse:
# Line 640  class MapCanvas(wxWindow, Publisher): Line 769  class MapCanvas(wxWindow, Publisher):
769                  return layer, select_shape                  return layer, select_shape
770          return None, None          return None, None
771    
772      def SelectShapeAt(self, x, y):      def SelectShapeAt(self, x, y, layer = None):
773          layer, shape = self.find_shape_at(x, y, selected_layer = 0)          """\
774            Select and return the shape and its layer at window position (x, y)
775    
776            If layer is given, only search in that layer. If no layer is
777            given, search through all layers.
778    
779            Return a tuple (layer, shapeid). If no shape is found, return
780            (None, None).
781            """
782            layer, shape = result = self.find_shape_at(x, y, searched_layer=layer)
783          # If layer is None, then shape will also be None. We don't want          # If layer is None, then shape will also be None. We don't want
784          # to deselect the currently selected layer, so we simply select          # to deselect the currently selected layer, so we simply select
785          # the already selected layer again.          # the already selected layer again.
786          if layer is None:          if layer is None:
787              layer = self.interactor.SelectedLayer()              layer = self.interactor.SelectedLayer()
788          self.interactor.SelectLayerAndShape(layer, shape)          self.interactor.SelectLayerAndShape(layer, shape)
789            return result
790    
791      def LabelShapeAt(self, x, y):      def LabelShapeAt(self, x, y):
792            """Add or remove a label at window position x, y.
793    
794            If there's a label at the given position, remove it. Otherwise
795            determine the shape at the position, run the label dialog and
796            unless the user cancels the dialog, add a laber.
797            """
798          ox = x; oy = y          ox = x; oy = y
799          label_layer = self.map.LabelLayer()          label_layer = self.map.LabelLayer()
800          layer, shape_index = self.find_shape_at(x, y, select_labels = 1)          layer, shape_index = self.find_shape_at(x, y, select_labels = 1)

Legend:
Removed from v.122  
changed lines
  Added in v.356

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26