/[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 967 by jonathan, Wed May 21 17:24:54 2003 UTC revision 1271 by jonathan, Fri Jun 20 16:43:04 2003 UTC
# Line 19  import os.path Line 19  import os.path
19    
20  from math import hypot  from math import hypot
21    
22  from wxPython.wx import wxWindow,\  from wxPython.wx import wxWindow, wxYield,\
23       wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\       wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\
24       EVT_PAINT, EVT_LEFT_DOWN, EVT_LEFT_UP, EVT_MOTION, EVT_LEAVE_WINDOW, \       EVT_PAINT, EVT_LEFT_DOWN, EVT_LEFT_UP, EVT_MOTION, EVT_LEAVE_WINDOW, \
25       wxBITMAP_TYPE_XPM, wxBeginBusyCursor, wxEndBusyCursor, wxCursor, \       wxBITMAP_TYPE_XPM, wxBeginBusyCursor, wxEndBusyCursor, wxCursor, \
# Line 35  from wxPython import wx Line 35  from wxPython import wx
35  from wxproj import point_in_polygon_shape, shape_centroid  from wxproj import point_in_polygon_shape, shape_centroid
36    
37  from Thuban.Model.messages import MAP_PROJECTION_CHANGED, \  from Thuban.Model.messages import MAP_PROJECTION_CHANGED, \
38         LAYER_PROJECTION_CHANGED, \
39       MAP_LAYERS_CHANGED, LAYER_CHANGED, LAYER_VISIBILITY_CHANGED       MAP_LAYERS_CHANGED, LAYER_CHANGED, LAYER_VISIBILITY_CHANGED
40  from Thuban.Model.layer import SHAPETYPE_POLYGON, SHAPETYPE_ARC, \  from Thuban.Model.layer import SHAPETYPE_POLYGON, SHAPETYPE_ARC, \
41       SHAPETYPE_POINT       SHAPETYPE_POINT
# Line 271  class MapPrintout(wx.wxPrintout): Line 272  class MapPrintout(wx.wxPrintout):
272                                  (height/canvas_scale)*scale),                                  (height/canvas_scale)*scale),
273                                  mapregion,                                  mapregion,
274                             self.selected_layer, self.selected_shapes)                             self.selected_layer, self.selected_shapes)
275          return wx.true          return True
   
276    
277  class MapCanvas(wxWindow, Publisher):  class MapCanvas(wxWindow, Publisher):
278    
# Line 302  class MapCanvas(wxWindow, Publisher): Line 302  class MapCanvas(wxWindow, Publisher):
302          # the map displayed in this canvas. Set with SetMap()          # the map displayed in this canvas. Set with SetMap()
303          self.map = None          self.map = None
304    
305            # current map projection. should only differ from map.projection
306            # when the map's projection is changing and we need access to the
307            # old projection.
308            self.current_map_proj = None
309    
310          # scale and offset describe the transformation from projected          # scale and offset describe the transformation from projected
311          # coordinates to window coordinates.          # coordinates to window coordinates.
312          self.scale = 1.0          self.scale = 1.0
# Line 378  class MapCanvas(wxWindow, Publisher): Line 383  class MapCanvas(wxWindow, Publisher):
383          clear = self.map is None or not self.map.HasLayers()          clear = self.map is None or not self.map.HasLayers()
384    
385          wxBeginBusyCursor()          wxBeginBusyCursor()
386            wxYield()
387    
388          if not clear:          try:
389              self.do_redraw()              if not clear:
390              try:                  self.do_redraw()
391                  pass                  try:
392              except:                      pass
393                  print "Error during drawing:", sys.exc_info()[0]                  except:
394                  clear = True                      print "Error during drawing:", sys.exc_info()[0]
395                        clear = True
396          if clear:  
397              # If we've got no map or if the map is empty, simply clear              if clear:
398              # the screen.                  # If we've got no map or if the map is empty, simply clear
399                    # the screen.
400              # XXX it's probably possible to get rid of this. The  
401              # background color of the window is already white and the                  # XXX it's probably possible to get rid of this. The
402              # only thing we may have to do is to call self.Refresh()                  # background color of the window is already white and the
403              # with a true argument in the right places.                  # only thing we may have to do is to call self.Refresh()
404              dc.BeginDrawing()                  # with a true argument in the right places.
405              dc.Clear()                  dc.BeginDrawing()
406              dc.EndDrawing()                  dc.Clear()
407                    dc.EndDrawing()
408          wxEndBusyCursor()          finally:
409                wxEndBusyCursor()
410    
411      def do_redraw(self):      def do_redraw(self):
412          # This should only be called if we have a non-empty map.          # This should only be called if we have a non-empty map.
# Line 492  class MapCanvas(wxWindow, Publisher): Line 499  class MapCanvas(wxWindow, Publisher):
499                    
500          printout = MapPrintout(self, self.map, (0, 0, width, height),          printout = MapPrintout(self, self.map, (0, 0, width, height),
501                                 selected_layer, selected_shapes)                                 selected_layer, selected_shapes)
502          printer.Print(self, printout, wx.true)          printer.Print(self, printout, True)
503          printout.Destroy()          printout.Destroy()
504    
505      def SetMap(self, map):      def SetMap(self, map):
# Line 502  class MapCanvas(wxWindow, Publisher): Line 509  class MapCanvas(wxWindow, Publisher):
509              for channel in redraw_channels:              for channel in redraw_channels:
510                  self.map.Unsubscribe(channel, self.full_redraw)                  self.map.Unsubscribe(channel, self.full_redraw)
511              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,
512                                   self.projection_changed)                                   self.map_projection_changed)
513                self.map.Unsubscribe(LAYER_PROJECTION_CHANGED,
514                                     self.layer_projection_changed)
515          self.map = map          self.map = map
516            self.current_map_proj = self.map.GetProjection()
517          self.selection.ClearSelection()          self.selection.ClearSelection()
518          if self.map is not None:          if self.map is not None:
519              for channel in redraw_channels:              for channel in redraw_channels:
520                  self.map.Subscribe(channel, self.full_redraw)                  self.map.Subscribe(channel, self.full_redraw)
521              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.projection_changed)              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.map_projection_changed)
522                self.map.Subscribe(LAYER_PROJECTION_CHANGED, self.layer_projection_changed)
523          self.FitMapToWindow()          self.FitMapToWindow()
524          # 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
525          # by FitMapToWindow but if map is empty it hasn't been called          # by FitMapToWindow but if map is empty it hasn't been called
# Line 526  class MapCanvas(wxWindow, Publisher): Line 537  class MapCanvas(wxWindow, Publisher):
537          self.bitmap = None          self.bitmap = None
538          self.redraw()          self.redraw()
539    
540      def projection_changed(self, *args):      def map_projection_changed(self, *args):
541          self.FitMapToWindow()  
542            proj = self.current_map_proj
543            self.current_map_proj = self.map.GetProjection()
544    
545            bbox = None
546    
547            if proj is not None and self.current_map_proj is not None:
548                width, height = self.GetSizeTuple()
549                llx, lly = self.win_to_proj(0, height)
550                urx, ury = self.win_to_proj(width, 0)
551                bbox = proj.Inverse(llx, lly) + proj.Inverse(urx, ury)
552                bbox = self.current_map_proj.ForwardBBox(bbox)
553    
554            if bbox is not None:
555                self.FitRectToWindow(bbox)
556            else:
557                self.FitMapToWindow()
558    
559            self.full_redraw()
560    
561        def layer_projection_changed(self, *args):
562          self.full_redraw()          self.full_redraw()
563    
564      def set_view_transform(self, scale, offset):      def set_view_transform(self, scale, offset):
565            # width/height of the projected bbox
566            llx, lly, urx, ury = bbox = self.map.ProjectedBoundingBox()
567            pwidth = float(urx - llx)
568            pheight = float(ury - lly)
569    
570            # width/height of the window
571            wwidth, wheight = self.GetSizeTuple()
572    
573            # The window's center in projected coordinates assuming the new
574            # scale/offset
575            pcenterx = (wwidth/2 - offset[0]) / scale
576            pcentery = (offset[1] - wheight/2) / scale
577    
578            # The window coordinates used when drawing the shapes must fit
579            # into 16bit signed integers.
580            max_len = max(pwidth, pheight)
581            if max_len:
582                max_scale = 32000.0 / max_len
583            else:
584                # FIXME: What to do in this case? The bbox is effectively
585                # empty so any scale should work.
586                max_scale = scale
587    
588            # The minimal scale is somewhat arbitrarily set to half that of
589            # the bbox fit into the window
590            scales = []
591            if pwidth:
592                scales.append(wwidth / pwidth)
593            if pheight:
594                scales.append(wheight / pheight)
595            if scales:
596                min_scale = 0.5 * min(scales)
597            else:
598                min_scale = scale
599    
600            if scale > max_scale:
601                scale = max_scale
602            elif scale < min_scale:
603                scale = min_scale
604    
605          self.scale = scale          self.scale = scale
606    
607          self.offset = offset          # determine new offset to preserve the center
608            self.offset = (wwidth/2 - scale * pcenterx,
609                           wheight/2 + scale * pcentery)
610          self.full_redraw()          self.full_redraw()
611          self.issue(SCALE_CHANGED, scale)          self.issue(SCALE_CHANGED, scale)
612    
# Line 581  class MapCanvas(wxWindow, Publisher): Line 654  class MapCanvas(wxWindow, Publisher):
654          Set the scale so that the map fits exactly into the window and          Set the scale so that the map fits exactly into the window and
655          center it in the window.          center it in the window.
656          """          """
657          bbox = self.map.ProjectedBoundingBox()          if self.map is not None:
658          if bbox is not None:              bbox = self.map.ProjectedBoundingBox()
659              self.FitRectToWindow(bbox)              if bbox is not None:
660                    self.FitRectToWindow(bbox)
661    
662      def FitLayerToWindow(self, layer):      def FitLayerToWindow(self, layer):
663          """Fit the given layer to the window.          """Fit the given layer to the window.
# Line 612  class MapCanvas(wxWindow, Publisher): Line 686  class MapCanvas(wxWindow, Publisher):
686                  bbox = proj.ForwardBBox(bbox)                  bbox = proj.ForwardBBox(bbox)
687    
688              if bbox is not None:              if bbox is not None:
689                  self.FitRectToWindow(bbox)                  if len(shapes) == 1 and layer.ShapeType() == SHAPETYPE_POINT:
690                        self.ZoomFactor(1, self.proj_to_win(bbox[0], bbox[1]))
691                    else:
692                        self.FitRectToWindow(bbox)
693    
694      def ZoomFactor(self, factor, center = None):      def ZoomFactor(self, factor, center = None):
695          """Multiply the zoom by factor and center on center.          """Multiply the zoom by factor and center on center.
# Line 900  class MapCanvas(wxWindow, Publisher): Line 977  class MapCanvas(wxWindow, Publisher):
977    
978              if shapetype == SHAPETYPE_POLYGON:              if shapetype == SHAPETYPE_POLYGON:
979                  for i in shape_ids:                  for i in shape_ids:
980                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      shapefile = layer.ShapeStore().Shapefile().cobject()
981                                                      i,                      result = point_in_polygon_shape(shapefile, i,
982                                                      filled, stroked,                                                      filled, stroked,
983                                                      map_proj, layer_proj,                                                      map_proj, layer_proj,
984                                                      scale, -scale, offx, offy,                                                      scale, -scale, offx, offy,
# Line 911  class MapCanvas(wxWindow, Publisher): Line 988  class MapCanvas(wxWindow, Publisher):
988                          break                          break
989              elif shapetype == SHAPETYPE_ARC:              elif shapetype == SHAPETYPE_ARC:
990                  for i in shape_ids:                  for i in shape_ids:
991                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      shapefile = layer.ShapeStore().Shapefile().cobject()
992                        result = point_in_polygon_shape(shapefile,
993                                                      i, 0, 1,                                                      i, 0, 1,
994                                                      map_proj, layer_proj,                                                      map_proj, layer_proj,
995                                                      scale, -scale, offx, offy,                                                      scale, -scale, offx, offy,
# Line 973  class MapCanvas(wxWindow, Publisher): Line 1051  class MapCanvas(wxWindow, Publisher):
1051              # a label was selected              # a label was selected
1052              label_layer.RemoveLabel(shape_index)              label_layer.RemoveLabel(shape_index)
1053          elif layer is not None:          elif layer is not None:
1054              text = labeldialog.run_label_dialog(self, layer.table, shape_index)              text = labeldialog.run_label_dialog(self,
1055                                                    layer.ShapeStore().Table(),
1056                                                    shape_index)
1057              if text:              if text:
1058                  proj = self.map.projection                  proj = self.map.projection
1059                  if proj is not None:                  if proj is not None:
# Line 988  class MapCanvas(wxWindow, Publisher): Line 1068  class MapCanvas(wxWindow, Publisher):
1068    
1069                  shapetype = layer.ShapeType()                  shapetype = layer.ShapeType()
1070                  if shapetype == SHAPETYPE_POLYGON:                  if shapetype == SHAPETYPE_POLYGON:
1071                      x, y = shape_centroid(layer.shapefile.cobject(),                      shapefile = layer.ShapeStore().Shapefile().cobject()
1072                                            shape_index,                      x, y = shape_centroid(shapefile, shape_index,
1073                                            map_proj, layer_proj, 1, 1, 0, 0)                                            map_proj, layer_proj, 1, 1, 0, 0)
1074                      if map_proj is not None:                      if map_proj is not None:
1075                          x, y = map_proj.Inverse(x, y)                          x, y = map_proj.Inverse(x, y)

Legend:
Removed from v.967  
changed lines
  Added in v.1271

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26