pygplates.DateLineWrapper

class pygplates.DateLineWrapper

Bases: Boost.Python.instance

Wraps geometries to the dateline.

The motivation for this class is to remove horizontal lines when polylines and polygons are displayed in 2D map projections. The horizontal lines occur when the longitude of two adjacent points change from approximately -180 degrees to 180 degrees (or vice versa) causing the line segment between the adjacent points to take the long path right across the map display instead of the short path.

Date line wrapping avoids this by splitting a polyline/polygon into multiple polylines/polygons at the dateline.

__init__([central_meridian=0])

Create a dateline wrapper with a central meridian (longitude).

Parameters

central_meridian (float) – Longitude of the central meridian. Defaults to zero.

If central_meridian is non-zero then the dateline is essentially shifted such that the longitudes of the wrapped points lie in the range [central_meridian - 180, central_meridian + 180]. If central_meridian is zero then the output range becomes [-180, 180].

To enable wrapping to the ranges [-180, 180] and [-90, 270]:

date_line_wrapper = pygplates.DateLineWrapper()
date_line_wrapper_90 = pygplates.DateLineWrapper(90)

Note

If central_meridian is outside the range [-180, 180] then it will be wrapped to be within that range (eg, -200 becomes 160). This ensures that the range of longitudes of wrapped points, [central_meridian - 180, central_meridian + 180], will always be within the range [-360, 360] which is the valid range for LatLonPoint.

Methods

__init__([central_meridian=0])

Create a dateline wrapper with a central meridian (longitude).

wrap(geometry, [tessellate_degrees])

Wrap a geometry to the range [central_meridian - 180, central_meridian + 180].

wrap(geometry[, tessellate_degrees])

Wrap a geometry to the range [central_meridian - 180, central_meridian + 180].

Parameters
  • geometry (GeometryOnSphere) – the geometry to wrap

  • tessellate_degrees (float or None) – optional tessellation threshold (in degrees)

The following table maps the input geometry type to the return type:

Input Geometry

Returns

Description

PointOnSphere

LatLonPoint

A single wrapped point.

MultiPointOnSphere

DateLineWrapper.LatLonMultiPoint

A single LatLonMultiPoint with the following methods:

  • get_points(): returns a list of LatLonPoint representing the wrapped points.

PolylineOnSphere

list of DateLineWrapper.LatLonPolyline

A list of wrapped polylines.
Each LatLonPolyline has the following methods:
  • get_points(): returns a list of LatLonPoint representing the wrapped points of the LatLonPolyline.

  • get_is_original_point_flags(): returns a list of bool indicating whether each point in get_points() is an original point from the input polyline. Newly added points due to dateline wrapping and tessellation will be False. Note that both lists are the same length.

PolygonOnSphere

list of DateLineWrapper.LatLonPolygon

A list of wrapped polygons.
Each LatLonPolygon has the following methods:
  • get_points(): returns a list of LatLonPoint representing all wrapped points of the LatLonPolygon starting with its exterior ring and followed by all its interior rings if any (ordered by interior ring indices).

  • get_is_original_point_flags(): returns a list of bool indicating whether each point in get_points() is an original point from the input polygon. Newly added points due to dateline wrapping and tessellation will be False. Note that both lists are the same length.

  • get_exterior_points: similar to get_points() but only returns points in the exterior ring.

  • get_is_original_exterior_point_flags(): similar to get_is_original_point_flags() but only for the exterior ring. Note that both get_exterior_points and get_is_original_exterior_point_flags() are the same length.

  • get_number_of_interior_rings(): returns the number of interior rings.

  • get_interior_points(interior_ring_index): similar to get_points() but only returns points in the interior ring at the specified interior ring index (which must be less than get_number_of_interior_rings()).

  • get_is_original_interior_point_flags(interior_ring_index): similar to get_is_original_point_flags() but only for the interior ring at the specified interior ring index. Note that both get_interior_points(interior_ring_index) and get_is_original_interior_point_flags(interior_ring_index) are the same length.

Note

The start and end points in a particular ring (exterior or interior) are generally not the same. This is similar to pygplates.PolygonOnSphere.

Note that, unlike points and multi-points, when wrapping an input polyline (or polygon) you can get more than one wrapped output polyline (or polygon) if it crosses the dateline.

date_line_wrapper = pygplates.DateLineWrapper(90.0)

# Wrap a point to the range [-90, 270].
point = pygplates.PointOnSphere(...)
wrapped_point = date_line_wrapper.wrap(point)
wrapped_point_lat_lon = wrapped_point.get_latitude(), wrapped_point.get_longitude()

# Wrap a multi-point to the range [-90, 270].
multi_point = pygplates.MultiPointOnSphere(...)
wrapped_multi_point = date_line_wrapper.wrap(multi_point)
for wrapped_point in wrapped_multi_point.get_points():
  wrapped_point_lat_lon = wrapped_point.get_latitude(), wrapped_point.get_longitude()

# Wrap a polyline to the range [-90, 270].
polyline = pygplates.PolylineOnSphere(...)
wrapped_polylines = date_line_wrapper.wrap(polyline)
for wrapped_polyline in wrapped_polylines:
  for wrapped_point in wrapped_polyline.get_points():
    wrapped_point_lat_lon = wrapped_point.get_latitude(), wrapped_point.get_longitude()

# Wrap a polygon to the range [-90, 270].
polygon = pygplates.PolygonOnSphere(...)
wrapped_polygons = date_line_wrapper.wrap(polygon)
for wrapped_polygon in wrapped_polygons:
  for wrapped_point in wrapped_polygon.get_points():
    wrapped_point_lat_lon = wrapped_point.get_latitude(), wrapped_point.get_longitude()

And for polygons an equivalent alternative (to the above example) extracts each wrapped polygon’s exterior and interior rings separately (rather than together):

# Wrap a polygon to the range [-90, 270].
polygon = pygplates.PolygonOnSphere(...)
wrapped_polygons = date_line_wrapper.wrap(polygon)
for wrapped_polygon in wrapped_polygons:
  for wrapped_point in wrapped_polygon.get_exterior_points():
    wrapped_point_lat_lon = wrapped_point.get_latitude(), wrapped_point.get_longitude()
  for interior_ring_index in range(wrapped_polygon.get_number_of_interior_rings()):
    for wrapped_point in wrapped_polygon.get_interior_points(interior_ring_index):
      wrapped_point_lat_lon = wrapped_point.get_latitude(), wrapped_point.get_longitude()
If tessellate_degrees is specified then tessellation (of polylines and polygons) is also performed.
Each segment is then tessellated such that adjacent points are separated by no more than tessellate_degrees on the globe.
This is useful both for geometries that cross the dateline and those that don’t. It helps ensure each polyline or polygon does not deviate too much from the true path where each great circle arc segment can be curved in 2D map projection space (rather than a straight line segment).
But it is especially useful for wrapped polygons in 2D map projections where the boundary of the projection is curved (such as Mollweide). Without tessellation the segment of the wrapped polygon along the boundary will be a straight line instead of curved to follow the map boundary.

Wrapping and tessellating a polyline and a polygon to a central meridian of 90 degrees:

date_line_wrapper = pygplates.DateLineWrapper(90.0)

# Wrap a polyline to the range [-90, 270] and tessellate to at least 2 degrees.
polyline = pygplates.PolylineOnSphere(...)
wrapped_and_tessellated_polylines = date_line_wrapper.wrap(polyline, 2.0)
...

# Wrap a polygon to the range [-90, 270] and tessellate to at least 2 degrees.
polygon = pygplates.PolygonOnSphere(...)
wrapped_and_tessellated_polygons = date_line_wrapper.wrap(polygon, 2.0)
...

Note

tessellate_degrees is ignored for points and multi-points.

Wrapping (and tessellating) can introduce new points into the original polyline or polygon.
In some cases it is desirable to know which points are original points and which are not.
For example, if the original points in a polyline are decorated with point symbols in a 2D map rendering. Any newly introduced points (from wrapping/tessellating) should not be decorated.
As such both LatLonPolyline and LatLonPolygon have methods to support this (see the above wrapped geometry table).

Determining whether points in a wrapped polyline are original polyline points:

date_line_wrapper = pygplates.DateLineWrapper()

# Wrap a polyline (and tessellate to at least 2 degrees).
polyline = pygplates.PolylineOnSphere(...)
wrapped_polylines = date_line_wrapper.wrap(polyline, 2.0)
for wrapped_polyline in wrapped_polylines:
  wrapped_points = wrapped_polyline.get_points()
  is_original_point_flags = wrapped_polyline.get_is_original_point_flags()
  for wrapped_point_index in range(len(wrapped_points)):
    if is_original_point_flags[wrapped_point_index]:
      wrapped_point_lat, wrapped_point_lon = wrapped_points[wrapped_point_index].to_lat_lon()

Changed in version 0.36: Added the following to DateLineWrapper.LatLonPolygon:

  • get_points()

  • get_is_original_point_flags()

  • get_number_of_interior_rings()

  • get_interior_points(interior_ring_index)

  • get_is_original_interior_point_flags(interior_ring_index)