Table Of Contents

Previous topic

Ellipse

Next topic

FloatCanvasError

This Page

phoenix_title FloatCanvas

FloatCanvas.py

This is a high level window for drawing maps and anything else in an arbitrary coordinate system.

The goal is to provide a convenient way to draw stuff on the screen without having to deal with handling OnPaint events, converting to pixel coordinates, knowing about wxWindows brushes, pens, and colors, etc. It also provides virtually unlimited zooming and scrolling

I am using it for two things: 1) general purpose drawing in floating point coordinates 2) displaying map data in Lat-long coordinates

If the projection is set to None, it will draw in general purpose floating point coordinates. If the projection is set to ‘FlatEarth’, it will draw a FlatEarth projection, centered on the part of the map that you are viewing. You can also pass in your own projection function.

It is double buffered, so re-draws after the window is uncovered by something else are very quick.

It relies on NumPy, which is needed for speed (maybe, I havn’t profiled it)

Bugs and Limitations:
Lots: patches, fixes welcome

For Map drawing: It ignores the fact that the world is, in fact, a sphere, so it will do strange things if you are looking at stuff near the poles or the date line. so far I don’t have a need to do that, so I havn’t bothered to add any checks for that yet.

Zooming: I have set no zoom limits. What this means is that if you zoom in really far, you can get integer overflows, and get wierd results. It doesn’t seem to actually cause any problems other than wierd output, at least when I have run it.

Speed: I have done a couple of things to improve speed in this app. The one thing I have done is used NumPy Arrays to store the coordinates of the points of the objects. This allowed me to use array oriented functions when doing transformations, and should provide some speed improvement for objects with a lot of points (big polygons, polylines, pointsets).

The real slowdown comes when you have to draw a lot of objects, because you have to call the wx.DC.DrawSomething call each time. This is plenty fast for tens of objects, OK for hundreds of objects, but pretty darn slow for thousands of objects.

The solution is to be able to pass some sort of object set to the DC directly. I’ve used DC.DrawPointList(Points), and it helped a lot with drawing lots of points. I havn’t got a LineSet type object, so I havn’t used DC.DrawLineList yet. I’d like to get a full set of DrawStuffList() methods implimented, and then I’d also have a full set of Object sets that could take advantage of them. I hope to get to it some day.

Mouse Events:

At this point, there are a full set of custom mouse events. They are just like the regular mouse events, but include an extra attribute: Event.GetCoords(), that returns the (x,y) position in world coordinates, as a length-2 NumPy vector of Floats.

Copyright: Christopher Barker

License: Same as the version of wxPython you are using it with

Please let me know if you’re using this!!!

Contact me at:

Chris.Barker@noaa.gov


class_hierarchy Inheritance Diagram

Inheritance diagram for class FloatCanvas

Inheritance diagram of FloatCanvas


super_classes Known Superclasses

Panel


method_summary Methods Summary

__init__  
AddObject  
AddObjects  
addshape Creates Group and adds its reference to the canvas.
ClearAll ClearAll(ResetBB=True)
ComputeFontScale  
Draw Canvas.Draw(Force=False)
FlatEarthProjection  
GetHitTestColor  
HitTest  
InitAll InitAll() sets everything in the Canvas to default state.
InitializePanel  
KeyDownEvent  
KeyUpEvent  
LeftDoubleClickEvent  
LeftDownEvent  
LeftUpEvent  
MakeHitDict  
MakeNewBuffers  
MakeNewForegroundHTBitmap Off screen Bitmap used for Hit tests on foreground objects
MakeNewHTBitmap Off screen Bitmap used for Hit tests on background objects
MiddleDoubleClickEvent  
MiddleDownEvent  
MiddleUpEvent  
MotionEvent  
MouseOverTest  
MoveImage move the image in the window.
OnPaint  
OnSize  
OnSizeTimer  
PixelToWorld Converts coordinates from Pixel coordinates to world coordinates.
RemoveObject  
RemoveObjects  
RightDoubleCLickEvent  
RightDownEvent  
RightUpEvent  
SaveAsImage Saves the current image as an image file. The default is in the
ScalePixelToWorld This function computes a pair of x.y lengths,
ScaleWorldToPixel This function will get passed to the drawing functions of the objects,
SetMode Set the GUImode to any of the available mode.
SetProjectionFun  
SetToNewScale  
UnBindAll Removes all bindings to Objects
WheelEvent  
WorldToPixel This function will get passed to the drawing functions of the objects,
Zoom Zoom(factor, center) changes the amount of zoom of the image by factor.
ZoomToBB Zooms the image to the bounding box given, or to the bounding

api Class API



class FloatCanvas(Panel)

FloatCanvas.py

This is a high level window for drawing maps and anything else in an arbitrary coordinate system.

The goal is to provide a convenient way to draw stuff on the screen without having to deal with handling OnPaint events, converting to pixel coordinates, knowing about wxWindows brushes, pens, and colors, etc. It also provides virtually unlimited zooming and scrolling

I am using it for two things: 1) general purpose drawing in floating point coordinates 2) displaying map data in Lat-long coordinates

If the projection is set to None, it will draw in general purpose floating point coordinates. If the projection is set to ‘FlatEarth’, it will draw a FlatEarth projection, centered on the part of the map that you are viewing. You can also pass in your own projection function.

It is double buffered, so re-draws after the window is uncovered by something else are very quick.

It relies on NumPy, which is needed for speed (maybe, I havn’t profiled it)

Bugs and Limitations:
Lots: patches, fixes welcome

For Map drawing: It ignores the fact that the world is, in fact, a sphere, so it will do strange things if you are looking at stuff near the poles or the date line. so far I don’t have a need to do that, so I havn’t bothered to add any checks for that yet.

Zooming: I have set no zoom limits. What this means is that if you zoom in really far, you can get integer overflows, and get wierd results. It doesn’t seem to actually cause any problems other than wierd output, at least when I have run it.

Speed: I have done a couple of things to improve speed in this app. The one thing I have done is used NumPy Arrays to store the coordinates of the points of the objects. This allowed me to use array oriented functions when doing transformations, and should provide some speed improvement for objects with a lot of points (big polygons, polylines, pointsets).

The real slowdown comes when you have to draw a lot of objects, because you have to call the wx.DC.DrawSomething call each time. This is plenty fast for tens of objects, OK for hundreds of objects, but pretty darn slow for thousands of objects.

The solution is to be able to pass some sort of object set to the DC directly. I’ve used DC.DrawPointList(Points), and it helped a lot with drawing lots of points. I havn’t got a LineSet type object, so I havn’t used DC.DrawLineList yet. I’d like to get a full set of DrawStuffList() methods implimented, and then I’d also have a full set of Object sets that could take advantage of them. I hope to get to it some day.

Mouse Events:

At this point, there are a full set of custom mouse events. They are just like the regular mouse events, but include an extra attribute: Event.GetCoords(), that returns the (x,y) position in world coordinates, as a length-2 NumPy vector of Floats.

Copyright: Christopher Barker

License: Same as the version of wxPython you are using it with

Please let me know if you’re using this!!!

Contact me at:

Chris.Barker@noaa.gov


Methods



__init__(self, parent, id = -1, size = DefaultSize, ProjectionFun = None, BackgroundColor = "WHITE", Debug = False, **kwargs)


AddObject(self, obj)


AddObjects(self, Objects)


addshape(self, *args, **kwargs)

Creates Group and adds its reference to the canvas. Argument protocol same as Group class, whose docstring is:

A group of other FloatCanvas Objects

Not all DrawObject methods may apply here.

Note that if an object is in more than one group, it will get drawn more than once.



ClearAll(self, ResetBB=True)

ClearAll(ResetBB=True)

Removes all DrawObjects from the Canvas

If ResetBB is set to False, the original bounding box will remain



ComputeFontScale(self)


Draw(self, Force=False)

Canvas.Draw(Force=False)

Re-draws the canvas.

Note that the buffer will not be re-drawn unless something has changed. If you change a DrawObject directly, then the canvas will not know anything has changed. In this case, you can force a re-draw by passing int True for the Force flag:

Canvas.Draw(Force=True)

There is a main buffer set up to double buffer the screen, so you can get quick re-draws when the window gets uncovered.

If there are any objects in self._ForeDrawList, then the background gets drawn to a new buffer, and the foreground objects get drawn on top of it. The final result if blitted to the screen, and stored for future Paint events. This is done so that you can have a complicated background, but have something changing on the foreground, without having to wait for the background to get re-drawn. This can be used to support simple animation, for instance.



FlatEarthProjection(self, CenterPoint)


GetHitTestColor(self, xy)


HitTest(self, event, HitEvent)


InitAll(self)

InitAll() sets everything in the Canvas to default state.

It can be used to reset the Canvas



InitializePanel(self)


KeyDownEvent(self, event)


KeyUpEvent(self, event)


LeftDoubleClickEvent(self, event)


LeftDownEvent(self, event)


LeftUpEvent(self, event)


MakeHitDict(self)


MakeNewBuffers(self)


MakeNewForegroundHTBitmap(self)

Off screen Bitmap used for Hit tests on foreground objects



MakeNewHTBitmap(self)

Off screen Bitmap used for Hit tests on background objects



MiddleDoubleClickEvent(self, event)


MiddleDownEvent(self, event)


MiddleUpEvent(self, event)


MotionEvent(self, event)


MouseOverTest(self, event)


MoveImage(self, shift, CoordType, ReDraw=True)

move the image in the window.

shift is an (x,y) tuple, specifying the amount to shift in each direction

It can be in any of three coordinates: Panel, Pixel, World, specified by the CoordType parameter

Panel coordinates means you want to shift the image by some fraction of the size of the displaed image

Pixel coordinates means you want to shift the image by some number of pixels

World coordinates mean you want to shift the image by an amount in Floating point world coordinates



OnPaint(self, event)


OnSize(self, event=None)


OnSizeTimer(self, event=None)


PixelToWorld(self, Points)

Converts coordinates from Pixel coordinates to world coordinates.

Points is a tuple of (x,y) coordinates, or a list of such tuples, or a NX2 Numpy array of x,y coordinates.



RemoveObject(self, Object, ResetBB = True)


RemoveObjects(self, Objects)


RightDoubleCLickEvent(self, event)


RightDownEvent(self, event)


RightUpEvent(self, event)


SaveAsImage(self, filename, ImageType=BITMAP_TYPE_PNG)

Saves the current image as an image file. The default is in the PNG format. Other formats can be specified using the wx flags:

wx.BITMAP_TYPE_PNG wx.BITMAP_TYPE_JPG wx.BITMAP_TYPE_BMP wx.BITMAP_TYPE_XBM wx.BITMAP_TYPE_XPM etc. (see the wx docs for the complete list)



ScalePixelToWorld(self, Lengths)

This function computes a pair of x.y lengths, to change then from pixel to world coordinates.

Lengths should be a NX2 array of (x,y) coordinates, or a 2-tuple, or sequence of 2-tuples.



ScaleWorldToPixel(self, Lengths)

This function will get passed to the drawing functions of the objects, to Change a length from world to pixel coordinates.

Lengths should be a NX2 array of (x,y) coordinates, or a 2-tuple, or sequence of 2-tuples.



SetMode(self, Mode)

Set the GUImode to any of the available mode.



SetProjectionFun(self, ProjectionFun)


SetToNewScale(self, DrawFlag=True)


UnBindAll(self)

Removes all bindings to Objects



WheelEvent(self, event)


WorldToPixel(self, Coordinates)

This function will get passed to the drawing functions of the objects, to transform from world to pixel coordinates. Coordinates should be a NX2 array of (x,y) coordinates, or a 2-tuple, or sequence of 2-tuples.



Zoom(self, factor, center = None, centerCoords="world")

Zoom(factor, center) changes the amount of zoom of the image by factor. If factor is greater than one, the image gets larger. If factor is less than one, the image gets smaller.

center is a tuple of (x,y) coordinates of the center of the viewport, after zooming. If center is not given, the center will stay the same.

centerCoords is a flag indicating whether the center given is in pixel or world coords. Options are: “world” or “pixel”



ZoomToBB(self, NewBB=None, DrawFlag=True)

Zooms the image to the bounding box given, or to the bounding box of all the objects on the canvas, if none is given.