/[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 1221 by jonathan, Tue Jun 17 15:24:45 2003 UTC
# 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    
278  class MapCanvas(wxWindow, Publisher):  class MapCanvas(wxWindow, Publisher):
# Line 302  class MapCanvas(wxWindow, Publisher): Line 303  class MapCanvas(wxWindow, Publisher):
303          # the map displayed in this canvas. Set with SetMap()          # the map displayed in this canvas. Set with SetMap()
304          self.map = None          self.map = None
305    
306            # current map projection. should only differ from map.projection
307            # when the map's projection is changing and we need access to the
308            # old projection.
309            self.current_map_proj = None
310    
311          # scale and offset describe the transformation from projected          # scale and offset describe the transformation from projected
312          # coordinates to window coordinates.          # coordinates to window coordinates.
313          self.scale = 1.0          self.scale = 1.0
# Line 378  class MapCanvas(wxWindow, Publisher): Line 384  class MapCanvas(wxWindow, Publisher):
384          clear = self.map is None or not self.map.HasLayers()          clear = self.map is None or not self.map.HasLayers()
385    
386          wxBeginBusyCursor()          wxBeginBusyCursor()
387            try:
388          if not clear:              if not clear:
389              self.do_redraw()                  self.do_redraw()
390              try:                  try:
391                  pass                      pass
392              except:                  except:
393                  print "Error during drawing:", sys.exc_info()[0]                      print "Error during drawing:", sys.exc_info()[0]
394                  clear = True                      clear = True
395    
396          if clear:              if clear:
397              # 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
398              # the screen.                  # the screen.
399    
400              # XXX it's probably possible to get rid of this. The                  # XXX it's probably possible to get rid of this. The
401              # background color of the window is already white and the                  # background color of the window is already white and the
402              # only thing we may have to do is to call self.Refresh()                  # only thing we may have to do is to call self.Refresh()
403              # with a true argument in the right places.                  # with a true argument in the right places.
404              dc.BeginDrawing()                  dc.BeginDrawing()
405              dc.Clear()                  dc.Clear()
406              dc.EndDrawing()                  dc.EndDrawing()
407            finally:
408          wxEndBusyCursor()              wxEndBusyCursor()
409    
410      def do_redraw(self):      def do_redraw(self):
411          # 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 498  class MapCanvas(wxWindow, Publisher):
498                    
499          printout = MapPrintout(self, self.map, (0, 0, width, height),          printout = MapPrintout(self, self.map, (0, 0, width, height),
500                                 selected_layer, selected_shapes)                                 selected_layer, selected_shapes)
501          printer.Print(self, printout, wx.true)          printer.Print(self, printout, True)
502          printout.Destroy()          printout.Destroy()
503    
504      def SetMap(self, map):      def SetMap(self, map):
# Line 502  class MapCanvas(wxWindow, Publisher): Line 508  class MapCanvas(wxWindow, Publisher):
508              for channel in redraw_channels:              for channel in redraw_channels:
509                  self.map.Unsubscribe(channel, self.full_redraw)                  self.map.Unsubscribe(channel, self.full_redraw)
510              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,
511                                   self.projection_changed)                                   self.map_projection_changed)
512                self.map.Unsubscribe(LAYER_PROJECTION_CHANGED,
513                                     self.layer_projection_changed)
514          self.map = map          self.map = map
515            self.current_map_proj = self.map.GetProjection()
516          self.selection.ClearSelection()          self.selection.ClearSelection()
517          if self.map is not None:          if self.map is not None:
518              for channel in redraw_channels:              for channel in redraw_channels:
519                  self.map.Subscribe(channel, self.full_redraw)                  self.map.Subscribe(channel, self.full_redraw)
520              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.projection_changed)              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.map_projection_changed)
521                self.map.Subscribe(LAYER_PROJECTION_CHANGED, self.layer_projection_changed)
522          self.FitMapToWindow()          self.FitMapToWindow()
523          # 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
524          # 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 536  class MapCanvas(wxWindow, Publisher):
536          self.bitmap = None          self.bitmap = None
537          self.redraw()          self.redraw()
538    
539      def projection_changed(self, *args):      def map_projection_changed(self, *args):
540          self.FitMapToWindow()  
541            proj = self.current_map_proj
542            self.current_map_proj = self.map.GetProjection()
543    
544            bbox = None
545    
546            if proj is not None and self.current_map_proj is not None:
547                width, height = self.GetSizeTuple()
548                llx, lly = self.win_to_proj(0, height)
549                urx, ury = self.win_to_proj(width, 0)
550                bbox = proj.Inverse(llx, lly) + proj.Inverse(urx, ury)
551                bbox = self.current_map_proj.ForwardBBox(bbox)
552    
553            if bbox is not None:
554                self.FitRectToWindow(bbox)
555            else:
556                self.FitMapToWindow()
557    
558            self.full_redraw()
559    
560        def layer_projection_changed(self, *args):
561          self.full_redraw()          self.full_redraw()
562    
563      def set_view_transform(self, scale, offset):      def set_view_transform(self, scale, offset):
564            # width/height of the projected bbox
565            llx, lly, urx, ury = bbox = self.map.ProjectedBoundingBox()
566            pwidth = float(urx - llx)
567            pheight = float(ury - lly)
568    
569            # width/height of the window
570            wwidth, wheight = self.GetSizeTuple()
571    
572            # The window's center in projected coordinates assuming the new
573            # scale/offset
574            pcenterx = (wwidth/2 - offset[0]) / scale
575            pcentery = (offset[1] - wheight/2) / scale
576    
577            # The window coordinates used when drawing the shapes must fit
578            # into 16bit signed integers.
579            max_len = max(pwidth, pheight)
580            if max_len:
581                max_scale = 32000.0 / max_len
582            else:
583                # FIXME: What to do in this case? The bbox is effectively
584                # empty so any scale should work.
585                max_scale = scale
586    
587            # The minimal scale is somewhat arbitrarily set to half that of
588            # the bbox fit into the window
589            scales = []
590            if pwidth:
591                scales.append(wwidth / pwidth)
592            if pheight:
593                scales.append(wheight / pheight)
594            if scales:
595                min_scale = 0.5 * min(scales)
596            else:
597                min_scale = scale
598    
599            if scale > max_scale:
600                scale = max_scale
601            elif scale < min_scale:
602                scale = min_scale
603    
604          self.scale = scale          self.scale = scale
605    
606          self.offset = offset          # determine new offset to preserve the center
607            self.offset = (wwidth/2 - scale * pcenterx,
608                           wheight/2 + scale * pcentery)
609          self.full_redraw()          self.full_redraw()
610          self.issue(SCALE_CHANGED, scale)          self.issue(SCALE_CHANGED, scale)
611    
# Line 612  class MapCanvas(wxWindow, Publisher): Line 684  class MapCanvas(wxWindow, Publisher):
684                  bbox = proj.ForwardBBox(bbox)                  bbox = proj.ForwardBBox(bbox)
685    
686              if bbox is not None:              if bbox is not None:
687                  self.FitRectToWindow(bbox)                  if len(shapes) == 1 and layer.ShapeType() == SHAPETYPE_POINT:
688                        self.ZoomFactor(1, self.proj_to_win(bbox[0], bbox[1]))
689                    else:
690                        self.FitRectToWindow(bbox)
691    
692      def ZoomFactor(self, factor, center = None):      def ZoomFactor(self, factor, center = None):
693          """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 975  class MapCanvas(wxWindow, Publisher):
975    
976              if shapetype == SHAPETYPE_POLYGON:              if shapetype == SHAPETYPE_POLYGON:
977                  for i in shape_ids:                  for i in shape_ids:
978                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      shapefile = layer.ShapeStore().Shapefile().cobject()
979                                                      i,                      result = point_in_polygon_shape(shapefile, i,
980                                                      filled, stroked,                                                      filled, stroked,
981                                                      map_proj, layer_proj,                                                      map_proj, layer_proj,
982                                                      scale, -scale, offx, offy,                                                      scale, -scale, offx, offy,
# Line 911  class MapCanvas(wxWindow, Publisher): Line 986  class MapCanvas(wxWindow, Publisher):
986                          break                          break
987              elif shapetype == SHAPETYPE_ARC:              elif shapetype == SHAPETYPE_ARC:
988                  for i in shape_ids:                  for i in shape_ids:
989                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      shapefile = layer.ShapeStore().Shapefile().cobject()
990                        result = point_in_polygon_shape(shapefile,
991                                                      i, 0, 1,                                                      i, 0, 1,
992                                                      map_proj, layer_proj,                                                      map_proj, layer_proj,
993                                                      scale, -scale, offx, offy,                                                      scale, -scale, offx, offy,
# Line 973  class MapCanvas(wxWindow, Publisher): Line 1049  class MapCanvas(wxWindow, Publisher):
1049              # a label was selected              # a label was selected
1050              label_layer.RemoveLabel(shape_index)              label_layer.RemoveLabel(shape_index)
1051          elif layer is not None:          elif layer is not None:
1052              text = labeldialog.run_label_dialog(self, layer.table, shape_index)              text = labeldialog.run_label_dialog(self,
1053                                                    layer.ShapeStore().Table(),
1054                                                    shape_index)
1055              if text:              if text:
1056                  proj = self.map.projection                  proj = self.map.projection
1057                  if proj is not None:                  if proj is not None:
# Line 988  class MapCanvas(wxWindow, Publisher): Line 1066  class MapCanvas(wxWindow, Publisher):
1066    
1067                  shapetype = layer.ShapeType()                  shapetype = layer.ShapeType()
1068                  if shapetype == SHAPETYPE_POLYGON:                  if shapetype == SHAPETYPE_POLYGON:
1069                      x, y = shape_centroid(layer.shapefile.cobject(),                      shapefile = layer.ShapeStore().Shapefile().cobject()
1070                                            shape_index,                      x, y = shape_centroid(shapefile, shape_index,
1071                                            map_proj, layer_proj, 1, 1, 0, 0)                                            map_proj, layer_proj, 1, 1, 0, 0)
1072                      if map_proj is not None:                      if map_proj is not None:
1073                          x, y = map_proj.Inverse(x, y)                          x, y = map_proj.Inverse(x, y)

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26