1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
# Copyright (C) 2003 by Intevation GmbH
# Authors:
# Bernhard Herzog <bh@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with the software for details.
"""Extension to draw polygons
*** Warning: ***
This extension is very experimental and may corrupt your data. Use at
your own peril.
"""
__version__ = "$Revision: 2746 $"
# $Source$
# $Id: drawshape.py 2746 2007-03-17 13:31:31Z dpinte $
import os
import wx
import shapelib
import Thuban
from Thuban import _
from Thuban.Model.data import SHAPETYPE_POLYGON
from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_STRING, \
FIELDTYPE_DOUBLE
from Thuban.UI.command import registry, ToolCommand
from Thuban.UI.mainwindow import main_menu, main_toolbar
from Thuban.UI.viewport import Tool
def write_empty_row(table, row):
"""Write an empty record to the row
The values in the record will be set to suitable default values
depending on the type: 0 for numeric types and the empty string for
strings.
"""
values = {}
for col in table.Columns():
if col.type == FIELDTYPE_INT:
value = 0
elif col.type == FIELDTYPE_DOUBLE:
value = 0.0
elif col.type == FIELDTYPE_STRING:
value = ""
else:
print "write_empty_row: Unhandled col.type", col.type
values[col.name] = value
table.write_record(row, values)
def write_shape(shapestore, points):
"""Addd the points as a new shape to the shapestore
The points argument should be a list of the same structure as that
returned by the shapelib bindings for a polygon. It is passed
directly to the SHPObject constructor.
"""
shapefile = shapelib.ShapeFile(shapestore.FileName(), "r+b")
obj = shapelib.SHPObject(shapelib.SHPT_POLYGON, 1, points)
newid = shapefile.write_object(-1, obj)
write_empty_row(shapestore.Table(), newid)
shapefile.close()
shapestore._open_shapefile()
class ShapeDrawTool(Tool):
def __init__(self, view):
Tool.__init__(self, view)
self.points = []
def Name(self):
return "ShapeDrawTool"
def find_shapestore(self):
"""Return the shapestore into which to write and the projection
If the currently selected layer is a layer with polygons return
a tuple of the shapestore and the layer's projection.
Otherwise return a tuple of Nones.
"""
layer = self.view.SelectedLayer()
if layer is not None and layer.HasShapes() \
and layer.ShapeType() == SHAPETYPE_POLYGON:
return layer.ShapeStore(), layer.GetProjection()
return None, None
def MouseDown(self, event):
Tool.MouseDown(self, event)
if event.RightDown():
map_proj = self.view.Map().GetProjection()
shapestore, proj = self.find_shapestore()
if shapestore is not None and len(self.points) > 2:
points = self.points[:]
if map_proj is not None:
points = [tuple(map_proj.Inverse(*p)) for p in points]
if proj is not None:
points = [tuple(proj.Forward(*p)) for p in points]
points.append(points[0])
write_shape(shapestore, [points])
self.points = []
self.view.full_redraw()
else:
if not self.points:
self.points.append(self.view.win_to_proj(*self.current))
def MouseUp(self, event):
Tool.MouseUp(self, event)
self.points.append(self.view.win_to_proj(*self.current))
def draw(self, dc):
points = [self.view.proj_to_win(*p) for p in self.points] \
+ [self.current]
if len(points) == 2:
dc.DrawLines(points)
else:
dc.DrawPolygon(points)
def DrawPermanent(self, dc):
dc.SetPen(wx.Pen(wx.Color(255, 128, 0), 2))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.DrawPolygon([self.view.proj_to_win(*p) for p in self.points])
def shape_draw_tool(context):
canvas = context.mainwindow.canvas
canvas.SelectTool(ShapeDrawTool(canvas))
def check_shape_draw_tool(context):
return context.mainwindow.canvas.CurrentTool() == "ShapeDrawTool"
iconfile = os.path.join(os.path.abspath(Thuban.__path__[0]),
"..", "Resources", "Bitmaps", "identify")
registry.Add(ToolCommand("shape_draw_tool", "Shape Draw Tool",
shape_draw_tool, icon = iconfile,
helptext = "Draw a shape",
checked = check_shape_draw_tool))
# Add the command to the toolbar
main_toolbar.InsertSeparator()
main_toolbar.InsertItem("shape_draw_tool")
# find the experimental menu (create it anew if not found)
experimental_menu = main_menu.FindOrInsertMenu('experimental',
_('Experimenta&l'))
# finally add the new command to the experimental menu
experimental_menu.InsertItem('shape_draw_tool')
|