gnome.utilities.geometry.polygons

Polygon module, part of the geometry package

Assorted stuff for working with polygons

FIXME: should this support polygons with holes??? (i.e multiple rings?)

Module Contents

Classes

Polygon

A Polygon class

PolygonSet

A set of polygons (or polylines) stored as a single array of vertex data,

class gnome.utilities.geometry.polygons.Polygon(shape, dtype=float, buffer=None, offset=0, strides=None, order=None)

Bases: numpy.ndarray

A Polygon class

This is a subclass of np.ndarray, so that it can be used in place of a simple array of points, but also can hold extra meta-data in a “metadata” dict.

Takes Points as an array. Data is any python sequence that can be turned into a Nx2 numpy array of floats. The data will be copied unless the copy argument is set to False.

metadata is a dict of meta-data. This can hold anything.

property points

the points as a regular np.ndarray

property bounding_box
__array_finalize__(obj)

ndarray subclass instances can come about in three ways:

  • explicit constructor call. This will call the usual sequence of SubClass.__new__ then (if it exists) SubClass.__init__.

  • View casting (e.g arr.view(SubClass))

  • Creating new from template (e.g. arr[:3])

SubClass.__array_finalize__ gets called for all three methods of object creation, so this is where our object creation housekeeping usually goes.

I got this from:

http://www.scipy.org/Subclasses

which has been deprecated and changed to…

http://docs.scipy.org/doc/numpy/user/basics.subclassing.html

__array_wrap__(out_arr, context=None)
__getitem__(index)

Override __getitem__ to return a ndarray, rather than a Polygon object

__eq__(other)

Return self==value.

__ne__(other)

Return self!=value.

__str__()

Return str(self).

__repr__()

Return repr(self).

static _scaling_fun(arr, scale)

scales and rounds – does it all in place.

thin(scale)

Returns a new Polygon object, with the points thinned.

Parameters:

scale ((x_scale, y_scale): tuple of floats) – The scale to use: it is the ratio of world coords (usually lat-lon degrees) to pixels.

This is an algorithm designed for rendering. What it does is scale the points as you would to draw them (integer pixels). Then it removes any sequential duplicate points. Thus the rendered results should be exactly the same as if you rendered the pre-thinned polygons.

Polygons that are reduced to 1 point are removed.

If the polygon has teh first and last point the same, that property is preserved

NOTE: in a sequence of close points, the first point is retained.

Perhaps it would be better for the mean location of the sequence to be used instead? It should make no difference for rendering, but could make a difference for other purposes

class gnome.utilities.geometry.polygons.PolygonSet(data=None, dtype=np.float64)

Bases: object

A set of polygons (or polylines) stored as a single array of vertex data, and indexes into that array.

##Fixme: maybe this should be a MultiPolygon – maybe just a name change,

but could make for different functionality

create a new PolygonSet object

if no data is passed in, and empty set is created.

if data is passed in, it must a a tuple: (PointsArray, IndexArray, DataList)

bounding_box
total_num_points
__nonzero__
append(polygon, metadata=None)
polygon should be a Polygon object or a NX2 array (or something that

can be turned into one)

So that polygon[n,0] is the x coordinate of the nth point and

polygon[n,1] is the y coordinate of the nth point

_get_bounding_box()
_get_total_num_points()
GetPointsData()

returns a copy of the points and indexes arrays

GetMetaData()

returns a (shallow) copy of the metadata list

SetPointsData(PointData, MetaData=None)

SetPointsData(PointData)

where PointData is a tuple of two NX2 arrays, or objects that can be converted to arrays: PointData = (PointsArray, IndexArray)

Sets the data for a polygon set. Be careful with this one, it destroys all the current data, and doesn’t check for a match between your PointsArray and IndexArray.

The data type is preserved for the points, but it should probably be a float type.

It can be useful for setting the data in one PolygonSet to the same as another set:

set1.SetPointsData(set2.GetPointsData)

A copy is made, so the two sets will be distinct

Copy()
returns a “deep copy” of the PolygonSet Object –

i.e. it does not share any data with the original

TransformData(TransformFunction, args=(), kwargs={})

TransformData(Transform Function, args=(), kwargs={})

Transforms the data for a polygon set. It applies the passed in Transform Function to all the points in the polygon set. The function needs to accept a NX2 NumPy array of Floats, and return a NX2 NumPy array of floats

the optional arguments, args or kwargs are passed through to the TransformFuntion, so it is called as:

NewPoints = TransformFunction(OldPoints, *args, **kwargs)

__len__()
__iter__()
__bool__()
__getitem__(index)

returns a Polygon object

__str__()

Return str(self).

__repr__()

same as __str__ – not good but more informative than nothing

__eq__(other)

Return self==value.

__ne__(other)

Return self!=value.

thin(scale)

Returns a new PolygonSet object, with the points thinned.

Parameters:

scale ((x_scale, y_scale): tuple of floats) – The scale to use: it is the ratio of world coords (usually lat-lon degrees) to pixels.

This is an algorithm designed for rendering. What is does is scale the points as you would to draw them (integer pixels). Then it removes any sequential duplicate points. Thus the rendered results should be exactly the same as if you rendered the pre-thinned polygons.

Polygons that are reduced to 1 point are removed.

NOTE: in a sequence of close points, the first point is retained.

Perhaps it would be better for the mean location of the sequence to be used instead? It should make no difference for rendering, but could make a difference for other purposes