# pygplates.MultiPointOnSphere¶

class pygplates.MultiPointOnSphere(...)

Represents a multi-point (collection of points) on the surface of the unit length sphere. Multi-points are equality (==, !=) comparable (but not hashable - cannot be used as a key in a dict). See PointOnSphere for an overview of equality in the presence of limited floating-point precision.

A multi-point instance is iterable over its points:

multi_point = pygplates.MultiPointOnSphere(points)
for point in multi_point:
...


The following operations for accessing the points are supported:

Operation Result
len(mp) number of points in mp
for p in mp iterates over the points p of multi-point mp
p in mp True if p is equal to a point in mp
p not in mp False if p is equal to a point in mp
mp[i] the point of mp at index i
mp[i:j] slice of mp from i to j
mp[i:j:k] slice of mp from i to j with step k

Note

Since a MultiPointOnSphere is immutable it contains no operations or methods that modify its state (such as adding or removing points).

There are also methods that return the sequence of points as (latitude,longitude) values and (x,y,z) values contained in lists and numpy arrays (GeometryOnSphere.to_lat_lon_list(), GeometryOnSphere.to_lat_lon_array(), GeometryOnSphere.to_xyz_list() and GeometryOnSphere.to_xyz_array()).

__init__(...)

A MultiPointOnSphere object can be constructed in more than one way...

__init__(points)

Create a multi-point from a sequence of (x,y,z) or (latitude,longitude) points.

param points: A sequence of (x,y,z) points, or (latitude,longitude) points (in degrees). Any sequence of PointOnSphere or LatLonPoint or tuple (float,float,float) or tuple (float,float) InvalidLatLonError if any latitude or longitude is invalid ViolatedUnitVectorInvariantError if any (x,y,z) is not unit magnitude InsufficientPointsForMultiPointConstructionError if point sequence is empty

Note

The sequence must contain at least one point, otherwise InsufficientPointsForMultiPointConstructionError will be raised.

The following example shows a few different ways to create a multi-point:

points = []
points.append(pygplates.PointOnSphere(...))
points.append(pygplates.PointOnSphere(...))
points.append(pygplates.PointOnSphere(...))
multi_point = pygplates.MultiPointOnSphere(points)

points = []
points.append((lat1,lon1))
points.append((lat2,lon2))
points.append((lat3,lon3))
multi_point = pygplates.MultiPointOnSphere(points)

points = []
points.append([x1,y1,z1])
points.append([x2,y2,z2])
points.append([x3,y3,z3])
multi_point = pygplates.MultiPointOnSphere(points)


If you have latitude/longitude values but they are not a sequence of tuples or if the latitude/longitude order is swapped then the following examples demonstrate how you could restructure them:

# Flat lat/lon array.
points = numpy.array([lat1, lon1, lat2, lon2, lat3, lon3])
multi_point = pygplates.MultiPointOnSphere(zip(points[::2],points[1::2]))

# Flat lon/lat list (ie, different latitude/longitude order).
points = [lon1, lat1, lon2, lat2, lon3, lat3]
multi_point = pygplates.MultiPointOnSphere(zip(points[1::2],points[::2]))

# Separate lat/lon arrays.
lats = numpy.array([lat1, lat2, lat3])
lons = numpy.array([lon1, lon2, lon3])
multi_point = pygplates.MultiPointOnSphere(zip(lats,lons))

# Lon/lat list of tuples (ie, different latitude/longitude order).
points = [(lon1, lat1), (lon2, lat2), (lon3, lat3)]
multi_point = pygplates.MultiPointOnSphere([(lat,lon) for lon, lat in points])

__init__(geometry)

Create a multipoint from a GeometryOnSphere.

param geometry: The point, multi-point, polyline or polygon geometry to convert from. GeometryOnSphere

To create a MultiPointOnSphere from any geometry type:

multipoint = pygplates.MultiPointOnSphere(geometry)


Methods

 __init__(...) A MultiPointOnSphere object can be constructed in more than one way... clone() Create a duplicate of this geometry (derived) instance. distance(geometry1, geometry2, ...) [staticmethod] Returns the (minimum) distance between two geometries (in radians). get_centroid() Returns the centroid of this multi-point. get_points() Returns a read-only sequence of points in this geometry. to_lat_lon_array() Returns the sequence of points, in this geometry, as a numpy array of (latitude,longitude) pairs (in degrees). to_lat_lon_list() Returns the sequence of points, in this geometry, as (latitude,longitude) tuples (in degrees). to_lat_lon_point_list() Returns the sequence of points, in this geometry, as lat lon points. to_xyz_array() Returns the sequence of points, in this geometry, as a numpy array of (x,y,z) triplets. to_xyz_list() Returns the sequence of points, in this geometry, as (x,y,z) cartesian coordinate tuples.
clone()

Create a duplicate of this geometry (derived) instance.

Return type: GeometryOnSphere
distance(geometry1, geometry2[, distance_threshold_radians][, return_closest_positions=False][, return_closest_indices=False][, geometry1_is_solid=False][, geometry2_is_solid=False])

[staticmethod] Returns the (minimum) distance between two geometries (in radians).

Parameters: geometry1 (GeometryOnSphere) – the first geometry geometry2 (GeometryOnSphere) – the second geometry distance_threshold_radians (float or None) – optional distance threshold in radians - threshold should be in the range [0,PI] if specified return_closest_positions (bool) – whether to also return the closest point on each geometry - default is False return_closest_indices (bool) – whether to also return the index of the closest point (for multi-points) or the index of the closest segment (for polylines and polygons) - default is False geometry1_is_solid (bool) – whether the interior of geometry1 is solid or not - this parameter is ignored if geometry1 is not a PolygonOnSphere - default is False geometry2_is_solid (bool) – whether the interior of geometry2 is solid or not - this parameter is ignored if geometry2 is not a PolygonOnSphere - default is False distance (in radians), or a tuple containing distance and the closest point on each geometry if return_closest_positions is True, or a tuple containing distance and the indices of the closest point (for multi-points) or segment (for polylines and polygons) on each geometry if return_closest_indices is True, or a tuple containing distance and the closest point on each geometry and the indices of the closest point (for multi-points) or segment (for polylines and polygons) on each geometry if both return_closest_positions and return_closest_indices are True, or None if distance_threshold_radians is specified and exceeded float, or tuple (float, PointOnSphere, PointOnSphere) if return_closest_positions is True, or tuple (float, int, int) if return_closest_indices is True, or tuple (float, PointOnSphere, PointOnSphere, int, int) if both return_closest_positions and return_closest_indices are True, or None

The returned distance is the shortest path between geometry1 and geometry2 along the surface of the sphere (great circle arc path). To convert the distance from radians (distance on a unit radius sphere) to real distance you will need to multiply it by the Earth’s radius (see Earth).

Each geometry (geometry1 and geometry2) can be any of the four geometry types (PointOnSphere, MultiPointOnSphere, PolylineOnSphere and PolygonOnSphere) allowing all combinations of distance calculations:

distance_radians = pygplates.GeometryOnSphere.distance(point1, point2)



If distance_threshold_radians is specified and the (minimum) distance between the two geometries exceeds this threshold then None is returned.

# Perform a region-of-interest query between two geometries to see if
# they are within 1 degree of each other.
#
# Note that we explicitly test against None because a distance of zero is equilavent to False.
if pygplates.GeometryOnSphere.distance(geometry1, geometry2, math.radians(1)) is not None:
...


Note that it is more efficient to specify a distance threshold parameter (as shown in the above example) than it is to explicitly compare the returned distance to a threshold yourself. This is because internally each polyline/polygon geometry has an inbuilt spatial tree that optimises distance queries.

The minimum distance between two geometries is zero (and hence does not exceed any distance threshold) if:

• both geometries are a polyline/polygon and they intersect each other, or
• geometry1_is_solid is True and geometry1 is a PolygonOnSphere and geometry2 overlaps the interior of the polygon (even if it doesn’t intersect the polygon boundary) - similarly for geometry2_is_solid. However note that geometry1_is_solid is ignored if geometry1 is not a PolygonOnSphere - similarly for geometry2_is_solid.

If return_closest_positions is True then the closest point on each geometry is returned (unless the distance threshold is exceeded, if specified). Note that for polygons the closest point is always on the polygon boundary regardless of whether the polygon is solid or not (see geometry1_is_solid and geometry2_is_solid). Also note that the closest position on a polyline/polygon can be anywhere along any of its segments. In other words it’s not the nearest vertex of the polyline/polygon - it’s the nearest point on the polyline/polygon itself. If both geometries are polyline/polygon and they intersect then the intersection point is returned (same point for both geometries). If both geometries are polyline/polygon and they intersect more than once then any intersection point can be returned (but the same point is returned for both geometries). If one geometry is a solid PolygonOnSphere and the other geometry is a MultiPointOnSphere with more than one of its points inside the interior of the polygon then the closest point in the multi-point could be any of those inside points.

distance_radians, closest_point_on_geometry1, closest_point_on_geometry2 = \
pygplates.GeometryOnSphere.distance(geometry1, geometry2, return_closest_positions=True)


If return_closest_indices is True then the index of the closest point (for multi-points) or the index of the closest segment (for polylines and polygons) is returned (unless the threshold is exceeded, if specified). Note that for point geometries the index will always be zero. The point indices can be used to index directly into MultiPointOnSphere and the segment indices can be used with PolylineOnSphere.get_segments() or PolygonOnSphere.get_segments() as shown in the following example:

distance_radians, closest_point_index_on_multipoint, closest_segment_index_on_polyline = \
pygplates.GeometryOnSphere.distance(multipoint, polyline, return_closest_indices=True)

closest_point_on_multipoint = multipoint[closest_point_index_on_multipoint]
closest_segment_on_polyline = polyline.get_segments()[closest_segment_index_on_polyline]
closest_segment_normal_vector = closest_segment_on_polyline.get_great_circle_normal()


If both return_closest_positions and return_closest_indices are True:

# Distance between a polyline and a solid polygon.
distance_radians, polyline_point, polygon_point, polyline_segment_index, polygon_segment_index = \
pygplates.GeometryOnSphere.distance(
polyline,
polygon,
return_closest_positions=True,
return_closest_indices=True,
geometry2_is_solid=True)

get_centroid()

Returns the centroid of this multi-point.

Return type: PointOnSphere

The centroid is calculated as the sum of the points of the multi-point with the result normalized to a vector of unit length.

get_points()

Returns a read-only sequence of points in this geometry.

Return type: a read-only sequence of PointOnSphere

The following operations for accessing the points in the returned read-only sequence are supported:

Operation Result
len(seq) length of seq
for p in seq iterates over the points p of seq
p in seq True if p is equal to a point in seq
p not in seq False if p is equal to a point in seq
seq[i] the point of seq at index i
seq[i:j] slice of seq from i to j
seq[i:j:k] slice of seq from i to j with step k

Note

The returned sequence is read-only and cannot be modified.

Note

If you want a modifiable sequence consider wrapping the returned sequence in a list using something like points = list(geometry.get_points()) but note that modifying the list (eg, inserting a new point) will not modify the original geometry.

If this geometry is a PointOnSphere then the returned sequence has length one. For other geometry types (MultiPointOnSphere, PolylineOnSphere and PolygonOnSphere) the length will equal the number of points contained within.

The following example demonstrates some uses of the above operations:

points = geometry.get_points()
for point in points:
print point
first_point = points
last_point = points[-1]

However if you know you have a MultiPointOnSphere, PolylineOnSphere or PolygonOnSphere (ie, not a PointOnSphere) it’s actually easier to iterate directly over the geometry itself.
For example with a PolylineOnSphere:
for point in polyline:
print point
first_point = polyline
last_point = polyline[-1]


Note

There are also methods that return the sequence of points as (latitude,longitude) values and (x,y,z) values contained in lists and numpy arrays (to_lat_lon_list(), to_lat_lon_array(), to_xyz_list() and to_xyz_array()).

to_lat_lon_array()

Returns the sequence of points, in this geometry, as a numpy array of (latitude,longitude) pairs (in degrees).

Returns: an array of (latitude,longitude) pairs (in degrees) 2D numpy array with number of points as outer dimension and an inner dimension of two

Warning

This method should only be called if the numpy module is available.

If this geometry is a PointOnSphere then the returned sequence has length one. For other geometry types (MultiPointOnSphere, PolylineOnSphere and PolygonOnSphere) the length will equal the number of points contained within.

If you want the latitude/longitude order swapped in the returned tuples then the following is one way to achieve this:

# Convert (latitude,longitude) to (longitude,latitude).
geometry.to_lat_lon_array()[:, (1,0)]


If you need a flat 1D numpy array then you can do something like:

geometry.to_lat_lon_array().flatten()

to_lat_lon_list()

Returns the sequence of points, in this geometry, as (latitude,longitude) tuples (in degrees).

Returns: a list of (latitude,longitude) tuples (in degrees) list of (float,float) tuples

If this geometry is a PointOnSphere then the returned sequence has length one. For other geometry types (MultiPointOnSphere, PolylineOnSphere and PolygonOnSphere) the length will equal the number of points contained within.

If you want the latitude/longitude order swapped in the returned tuples then the following is one way to achieve this:

# Convert (latitude,longitude) to (longitude,latitude).
[(lon,lat) for lat, lon in geometry.to_lat_lon_list()]

to_lat_lon_point_list()

Returns the sequence of points, in this geometry, as lat lon points.

Return type: list of LatLonPoint

If this geometry is a PointOnSphere then the returned sequence has length one. For other geometry types (MultiPointOnSphere, PolylineOnSphere and PolygonOnSphere) the length will equal the number of points contained within.

to_xyz_array()

Returns the sequence of points, in this geometry, as a numpy array of (x,y,z) triplets.

Returns: an array of (x,y,z) triplets 2D numpy array with number of points as outer dimension and an inner dimension of three

Warning

This method should only be called if the numpy module is available.

If you need a flat 1D numpy array then you can do something like:

geometry.to_xyz_array().flatten()


If this geometry is a PointOnSphere then the returned sequence has length one. For other geometry types (MultiPointOnSphere, PolylineOnSphere and PolygonOnSphere) the length will equal the number of points contained within.

to_xyz_list()

Returns the sequence of points, in this geometry, as (x,y,z) cartesian coordinate tuples.

Returns: a list of (x,y,z) tuples list of (float,float,float) tuples

If this geometry is a PointOnSphere then the returned sequence has length one. For other geometry types (MultiPointOnSphere, PolylineOnSphere and PolygonOnSphere) the length will equal the number of points contained within.

#### Previous topic

pygplates.PointOnSphere

#### Next topic

pygplates.PolylineOnSphere