| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- """Points and related utilities."""
- import numpy as np
- import shapely
- from shapely.errors import DimensionError
- from shapely.geometry.base import BaseGeometry
- __all__ = ["Point"]
- class Point(BaseGeometry):
- """A geometry type that represents a single coordinate.
- Each coordinate has x, y and possibly z and/or m values.
- A point is a zero-dimensional feature and has zero length and zero area.
- Parameters
- ----------
- args : float, or sequence of floats
- The coordinates can either be passed as a single parameter, or as
- individual float values using multiple parameters:
- 1) 1 parameter: a sequence or array-like of with 2 or 3 values.
- 2) 2 or 3 parameters (float): x, y, and possibly z.
- Attributes
- ----------
- x, y, z, m : float
- Coordinate values
- Examples
- --------
- Constructing the Point using separate parameters for x and y:
- >>> from shapely import Point
- >>> p = Point(1.0, -1.0)
- Constructing the Point using a list of x, y coordinates:
- >>> p = Point([1.0, -1.0])
- >>> print(p)
- POINT (1 -1)
- >>> p.y
- -1.0
- >>> p.x
- 1.0
- """
- __slots__ = []
- def __new__(self, *args):
- """Create a new Point geometry."""
- if len(args) == 0:
- # empty geometry
- # TODO better constructor
- return shapely.from_wkt("POINT EMPTY")
- elif len(args) > 3:
- raise TypeError(f"Point() takes at most 3 arguments ({len(args)} given)")
- elif len(args) == 1:
- coords = args[0]
- if isinstance(coords, Point):
- return coords
- # Accept either (x, y) or [(x, y)]
- if not hasattr(coords, "__getitem__"): # generators
- coords = list(coords)
- coords = np.asarray(coords).squeeze()
- else:
- # 2 or 3 args
- coords = np.array(args).squeeze()
- if coords.ndim > 1:
- raise ValueError(
- f"Point() takes only scalar or 1-size vector arguments, got {args}"
- )
- if not np.issubdtype(coords.dtype, np.number):
- coords = [float(c) for c in coords]
- geom = shapely.points(coords)
- if not isinstance(geom, Point):
- raise ValueError("Invalid values passed to Point constructor")
- return geom
- # Coordinate getters and setters
- @property
- def x(self):
- """Return x coordinate."""
- return float(shapely.get_x(self))
- @property
- def y(self):
- """Return y coordinate."""
- return float(shapely.get_y(self))
- @property
- def z(self):
- """Return z coordinate."""
- z = shapely.get_z(self)
- if np.isnan(z) and not shapely.has_z(self):
- raise DimensionError("This point has no z coordinate.")
- return float(z)
- @property
- def m(self):
- """Return m coordinate.
- .. versionadded:: 2.1.0
- Also requires GEOS 3.12.0 or later.
- """
- if not shapely.has_m(self):
- raise DimensionError("This point has no m coordinate.")
- return float(shapely.get_m(self))
- @property
- def __geo_interface__(self):
- """Return a GeoJSON-like mapping of the Point geometry."""
- coords = self.coords
- return {"type": "Point", "coordinates": coords[0] if len(coords) > 0 else ()}
- def svg(self, scale_factor=1.0, fill_color=None, opacity=None):
- """Return SVG circle element for the Point geometry.
- Parameters
- ----------
- scale_factor : float
- Multiplication factor for the SVG circle diameter. Default is 1.
- fill_color : str, optional
- Hex string for fill color. Default is to use "#66cc99" if
- geometry is valid, and "#ff3333" if invalid.
- opacity : float
- Float number between 0 and 1 for color opacity. Default value is 0.6
- """
- if self.is_empty:
- return "<g />"
- if fill_color is None:
- fill_color = "#66cc99" if self.is_valid else "#ff3333"
- if opacity is None:
- opacity = 0.6
- return (
- f'<circle cx="{self.x}" cy="{self.y}" r="{3.0 * scale_factor}" '
- f'stroke="#555555" stroke-width="{1.0 * scale_factor}" fill="{fill_color}" '
- f'opacity="{opacity}" />'
- )
- @property
- def xy(self):
- """Separate arrays of X and Y coordinate values.
- Examples
- --------
- >>> from shapely import Point
- >>> x, y = Point(0, 0).xy
- >>> list(x)
- [0.0]
- >>> list(y)
- [0.0]
- """
- return self.coords.xy
- shapely.lib.registry[0] = Point
|