`Geometry`

subclasses¶

Creating a new `plpygis`

geometry from a WKB, GeoJSON or Shapely instance, will produce a new subclass of the base `Geometry`

class:

## Creation¶

New instances of the three base shapes (points, lines and polygons) may be created by passing in coordinates:

```
>>> point = Point((0, 0))
>>> line = LineString([(0, 0), (0, 1)])
>>> poly = Polygon([[(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)], [(4, 4), (4, 6), (6, 6), (6, 4), (4, 4)]])
```

## Editing¶

Coordinates may be accessed and modified after creation.

```
>>> point = Point((0, 0))
>>> print(point.x)
0
>>> point.x = 10
>>> print(point.x)
10
```

## Composition¶

Individual `LineString`

instances are composed of a list of `Point`

instances that each represent a vertex in the line. Similarly, `Polygon`

instances are composed of a list of `LineString`

instances that each represent linear rings.

The lists of vertices or linear rings can be modified, for example by adding a new `Point`

to the end of a `LineString`

.

Note

The first linear ring in a polygon should represent the exterior ring, while subsequent linear rings are internal boundaries. `plpygis`

will not validate geometries when they are created.

The four collection types, `MultiPoint`

, `LineString`

, `MultiPolygon`

and `GeometryCollection`

, are each composed of a list of other geometries of the appropriate type. At creation time, the collection types are created by passing in a list of existing instances:

```
>>> p1 = Point((0, 0))
>>> p2 = Point((1, 1))
>>> mp = MultiPoint([p1, p2])
```

## SRIDs¶

An SRID may be added at creation time with an optional `SRID`

parameter:

```
>>> point = Point((0, 0), srid=4326)
```

`plpygis`

will detect conflicts when multigeometries or collections are created with mixed SRIDs.

Warning

Changing the SRID of an instance that is part of another geometry (such as a `Point`

that is a vertex in a `LineString`

or a vertex in the linear ring of a `Polygon`

) will *not* be detected. When converted to a WKB or Shapely instance, only the SRID of the “parent” geometry will be used.

## Dimensionality¶

The `dimz`

and `dimm`

boolean parameters will indicate whether the geometry will have Z and M dimensions. `plpygis`

will attempt to match provided coordinates with the requested dimensions or will set them to an initial value of `0`

if they have not been provided:

```
>>> p1 = Point((0, 0, 1), dimz=True, dimm=True)
>>> print("p1", p1.x, p1.y, p1.z, p1.m)
p1 0 0 1 0
>>> p2 = Point((0, 0, 1), dimm=True)
>>> print("p2", p2.x, p2.y, p2.z, p2.m)
p2 0 0 None 1
>>> p3 = Point((0, 0, 1, 2))
>>> print("p3", p3.x, p3.y, p3.z, p3.m)
p3 0 0 1 2
```

The dimensionality of an existing instance may be altered after creation, by setting `dimz`

or `dimm`

. Adding a dimension will add a Z or M coordinate with an initial value of `0`

to the geometry and all geometries encompassed within it (*e.g.*, each vertex in a `LineString`

or each `Point`

in a `MultiPoint`

will gain the new dimension).

A new dimension may also be added to a single `Point`

by assigning to the `z`

or `m`

properties.

Adding a new dimension to a `Point`

that is a vertex in a `LineString`

or a vertex in the linear ring of a `Polygon`

will *not* change the dimensionality of the `LineString`

or the `Polygon`

. The dimensionality of “parent” instance *must* also be changed for the new coordinates to be reflected when converting to other representations.

```
>>> p1 = Point((0, 0))
>>> p2 = Point((1, 1))
>>> mp = MultiPoint([p1, p2])
>>> print(mp.dimz)
False
>>> p1.z = 2
>>> print(p1.miz)
True
>>> print(mp.dimz)
False
>>> mp.dimz = True
>>> print(mp.dimz)
True
>>> print("p1.z", p1.z, "p2.z", p2.z)
p1.z 2 p2.z 0
```

## Performance considerations¶

### Lazy evaluation¶

`plpygis`

uses native WKB parsing to extract header information that indicates the geometry type, SRID and the presence of a Z or M dimension. Full parsing of the entire geometry only occurs when needed. It is therefore possible to test the type and dimensionality of a `Geometry`

with only the first few bytes of data having been read. Perform these checks before performing any action that will require reading the remainder of the WKB.

### Caching¶

`plpygis`

will cache the initial WKB it was created from. As soon as any coordinates or composite geometries are referenced, the cached WKB is lost and a subsequent request that requires the WKB will necessitate it being generated from scratch. For sets of large geometries, this can have a noticeable affect on performance. Therefore, if doing a conversion to a Shapely geometry - an action which relies on the availability of the WKB - it is recommended that this conversion be done before any other operations on the `plpygis`

geometry.

Note

Getting `type`

, `srid`

, `dimz`

and `dimm`

are considered “safe” operations. However writing a new SRID or changing the dimensionality will also result in the cached WKB being lost. A geometry’s type may never be changed.

As a summary, getting the following properties will not affect performance:

Setting the following properties will cause any cached WKB to be cleared:

`srid`

`dimz`

`dimm`

Getting the following property relies on the presence of the WKB (cached or generated):

If the `Geometry`

was created from a WKB, the follwing actions will trigger a full parse and will clear the cached copy of the WKB:

- getting
`geojson`

and`__geo_interface__`

- getting
`shapely`

- getting any
`Point`

coordinate - getting
`bounds`

- getting
`vertices`

,`rings`

- getting any component geometry from
`MultiPoint`

,`MultiLineString`

,`MultiPolygon`

or`GeometryCollection`