14 |
|
|
15 |
from Thuban import _ |
from Thuban import _ |
16 |
|
|
|
import sys |
|
17 |
import os.path |
import os.path |
18 |
|
|
|
from math import hypot |
|
|
|
|
19 |
from wxPython.wx import wxWindow, \ |
from wxPython.wx import wxWindow, \ |
20 |
wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\ |
wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\ |
21 |
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, \ |
22 |
wxBITMAP_TYPE_XPM, wxCursor, wxPlatform, \ |
wxPlatform, wxBeginBusyCursor, wxEndBusyCursor, wxFileDialog, wxSAVE, \ |
|
wxBeginBusyCursor, wxEndBusyCursor, wxFileDialog, wxSAVE, \ |
|
23 |
wxOVERWRITE_PROMPT, wxID_OK |
wxOVERWRITE_PROMPT, wxID_OK |
24 |
|
|
25 |
# Export related stuff |
# Export related stuff |
28 |
|
|
29 |
from wxPython import wx |
from wxPython import wx |
30 |
|
|
31 |
from wxproj import point_in_polygon_shape, shape_centroid |
from Thuban.Model.messages import MAP_LAYERS_CHANGED, LAYER_CHANGED, \ |
32 |
|
LAYER_VISIBILITY_CHANGED |
|
from Thuban.Model.messages import \ |
|
|
MAP_PROJECTION_CHANGED, MAP_LAYERS_CHANGED, \ |
|
|
LAYER_PROJECTION_CHANGED, LAYER_CHANGED, LAYER_VISIBILITY_CHANGED |
|
33 |
|
|
34 |
from renderer import ScreenRenderer, ExportRenderer, PrinterRenderer |
from renderer import ScreenRenderer, ExportRenderer, PrinterRenderer |
35 |
|
|
36 |
import labeldialog |
import labeldialog |
37 |
|
|
38 |
from viewport import ViewPort, PanTool |
from viewport import ViewPort, PanTool, output_transform |
39 |
|
|
40 |
class CanvasPanTool(PanTool): |
class CanvasPanTool(PanTool): |
41 |
|
|
80 |
|
|
81 |
def draw_on_dc(self, dc): |
def draw_on_dc(self, dc): |
82 |
width, height = self.GetPageSizePixels() |
width, height = self.GetPageSizePixels() |
83 |
scale, offset, mapregion = OutputTransform(self.canvas.scale, |
scale, offset, mapregion = output_transform(self.canvas.scale, |
84 |
self.canvas.offset, |
self.canvas.offset, |
85 |
self.canvas.GetSizeTuple(), |
self.canvas.GetSizeTuple(), |
86 |
self.GetPageSizePixels()) |
self.GetPageSizePixels()) |
87 |
resx, resy = self.GetPPIPrinter() |
resx, resy = self.GetPPIPrinter() |
88 |
renderer = PrinterRenderer(dc, scale, offset, resolution = resy) |
renderer = PrinterRenderer(dc, scale, offset, resolution = resy) |
89 |
x, y, width, height = self.region |
x, y, width, height = self.region |
225 |
self.export_path = os.path.dirname(dlg.GetPath()) |
self.export_path = os.path.dirname(dlg.GetPath()) |
226 |
dc = wxMetaFileDC(dlg.GetPath()) |
dc = wxMetaFileDC(dlg.GetPath()) |
227 |
|
|
228 |
scale, offset, mapregion = OutputTransform(self.scale, |
scale, offset, mapregion = output_transform(self.scale, |
229 |
self.offset, |
self.offset, |
230 |
self.GetSizeTuple(), |
self.GetSizeTuple(), |
231 |
dc.GetSizeTuple()) |
dc.GetSizeTuple()) |
232 |
|
|
233 |
selected_layer = self.selection.SelectedLayer() |
selected_layer = self.selection.SelectedLayer() |
234 |
selected_shapes = self.selection.SelectedShapes() |
selected_shapes = self.selection.SelectedShapes() |
288 |
self.drag_dc.SetLogicalFunction(wxINVERT) |
self.drag_dc.SetLogicalFunction(wxINVERT) |
289 |
self.drag_dc.SetBrush(wxTRANSPARENT_BRUSH) |
self.drag_dc.SetBrush(wxTRANSPARENT_BRUSH) |
290 |
self.tool.Show(self.drag_dc) |
self.tool.Show(self.drag_dc) |
291 |
|
self.CaptureMouse() |
292 |
self.dragging = 1 |
self.dragging = 1 |
293 |
|
|
294 |
def OnLeftUp(self, event): |
def OnLeftUp(self, event): |
341 |
|
|
342 |
def LabelShapeAt(self, x, y, text=None): |
def LabelShapeAt(self, x, y, text=None): |
343 |
"""Add or remove a label at window position x, y. |
"""Add or remove a label at window position x, y. |
344 |
|
|
345 |
If there's a label at the given position, remove it. Otherwise |
If there's a label at the given position, remove it. Otherwise |
346 |
determine the shape at the position, run the label dialog and |
determine the shape at the position, run the label dialog and |
347 |
unless the user cancels the dialog, add a label. |
unless the user cancels the dialog, add a label. |
355 |
layer.ShapeStore().Table(), |
layer.ShapeStore().Table(), |
356 |
shape_index) |
shape_index) |
357 |
ViewPort.LabelShapeAt(self, x, y, text) |
ViewPort.LabelShapeAt(self, x, y, text) |
|
|
|
|
def OutputTransform(canvas_scale, canvas_offset, canvas_size, device_extend): |
|
|
"""Calculate dimensions to transform canvas content to output device.""" |
|
|
width, height = device_extend |
|
|
|
|
|
# Only 80 % of the with are available for the map |
|
|
width = width * 0.8 |
|
|
|
|
|
# Define the distance of the map from DC border |
|
|
distance = 20 |
|
|
|
|
|
if height < width: |
|
|
# landscape |
|
|
map_height = height - 2*distance |
|
|
map_width = map_height |
|
|
else: |
|
|
# portrait, recalibrate width (usually the legend width is too |
|
|
# small |
|
|
width = width * 0.9 |
|
|
map_height = width - 2*distance |
|
|
map_width = map_height |
|
|
|
|
|
mapregion = (distance, distance, |
|
|
distance+map_width, distance+map_height) |
|
|
|
|
|
canvas_width, canvas_height = canvas_size |
|
|
|
|
|
scalex = map_width / (canvas_width/canvas_scale) |
|
|
scaley = map_height / (canvas_height/canvas_scale) |
|
|
scale = min(scalex, scaley) |
|
|
canvas_offx, canvas_offy = canvas_offset |
|
|
offx = scale*canvas_offx/canvas_scale |
|
|
offy = scale*canvas_offy/canvas_scale |
|
|
|
|
|
return scale, (offx, offy), mapregion |
|