예제 #1
0
def test_from_wkt():
    expected = pygeos.points(1, 1)
    actual = pygeos.from_wkt("POINT (1 1)")
    assert pygeos.equals(actual, expected)
    # also accept bytes
    actual = pygeos.from_wkt(b"POINT (1 1)")
    assert pygeos.equals(actual, expected)
예제 #2
0
    def filter_(self, action, wkt, **kwargs):
        """Performs a filtering predicate operation and export to a spatial file.

        Arguments:
            action (str): The filtering action, one of 'nearest', 'within', 'within_buffer'.
            wkt (str): Well-Known Text representation of the geometry.
            **kwargs: Additional keyword arguments for the filtering operation.

        Returns:
            (str): The path of the exported archive.
        """
        gdf = self._gdf
        if action == 'nearest':
            # k = kwargs.pop('k', 1)
            # maximum_distance = kwargs.pop('maximum_distance', None)
            # if maximum_distance is not None:
            #     buffer = pg.buffer(pg.from_wkt(wkt), maximum_distance)
            #     gdf = gdf[gdf.predicates.within(buffer)]
            distance = gdf.measurement.distance(wkt)
            gdf.add_column('distance', distance, dtype=float)
            gdf = gdf.sort('distance', ascending=False)
        elif action == 'within':
            gdf = gdf[gdf.predicates.within(wkt)]
        elif action == 'within_buffer':
            radius = kwargs.pop('radius', 0)
            buffer = pg.buffer(pg.from_wkt(wkt), radius)
            gdf = gdf[gdf.predicates.within(buffer)]
        else:
            raise ValueError("action could be one of 'nearest', 'within', 'within_buffer'.")
        if len(gdf) == 0:
            raise ResultedEmptyDataFrame("The resulted dataframe is empty.")
        export = os.path.join(self._working_dir, "{filename}_{action}{extension}".format(filename=self._filename, action=action, extension=self._extension))
        gdf.export(export, driver=self._driver)

        return self._compress_files(export)
    def _pandas(cls, column, **kwargs):

        shape = kwargs.get("shape")
        shape_format = kwargs.get("shape_format")
        column_shape_format = kwargs.get("column_shape_format")

        # Check that shape is given and given in the correct format
        if shape is not None:
            try:
                if shape_format == "wkt":
                    shape_ref = geos.from_wkt(shape)
                elif shape_format == "wkb":
                    shape_ref = geos.from_wkb(shape)
                elif shape_format == "geojson":
                    shape_ref = geos.from_geojson(shape)
                else:
                    raise NotImplementedError(
                        "Shape constructor method not implemented. Must be in WKT, WKB, or GeoJSON format."
                    )
            except:
                raise Exception("A valid reference shape was not given.")
        else:
            raise Exception("A shape must be provided for this method.")

        # Load the column into a pygeos Geometry vector from numpy array (Series not supported).
        if column_shape_format == "wkt":
            shape_test = geos.from_wkt(column.to_numpy(), on_invalid="ignore")
        elif column_shape_format == "wkb":
            shape_test = geos.from_wkb(column.to_numpy(), on_invalid="ignore")
        else:
            raise NotImplementedError(
                "Column values shape format not implemented.")

        # Allow for an array of reference shapes to be provided. Return a union of all the shapes in the array (Polygon or Multipolygon)
        shape_ref = geos.union_all(shape_ref)

        # Prepare the geometries
        geos.prepare(shape_ref)
        geos.prepare(shape_test)
        column_centroids = geos.centroid(shape_test)

        print(column_centroids)

        return pd.Series(geos.within(column_centroids, shape_ref))
예제 #4
0
def _geom_to_pygeos(geom):
    if isinstance(geom, str):
        geom = pg.from_wkt(geom)
    elif isinstance(geom, bytes):
        geom = pg.from_wkb(geom)
    elif isinstance(geom, pg.lib.Geometry):
        pass
    else:
        raise ValueError("'geom' should be WKT, WKB or pygeos Geometry.")
    return geom
예제 #5
0
def _shapely_to_pygeos(geom):
    if geom is None:
        return None

    if compat.PYGEOS_SHAPELY_COMPAT:
        return pygeos.from_shapely(geom)

    # fallback going through WKB
    if geom.is_empty and geom.geom_type == "Point":
        # empty point does not roundtrip through WKB
        return pygeos.from_wkt("POINT EMPTY")
    else:
        return pygeos.from_wkb(geom.wkb)
예제 #6
0
def test_from_wkt_exceptions():
    with pytest.raises(TypeError, match="Expected bytes, got int"):
        pygeos.from_wkt(1)

    with pytest.raises(pygeos.GEOSException):
        pygeos.from_wkt("")

    with pytest.raises(pygeos.GEOSException):
        pygeos.from_wkt("NOT A WKT STRING")
예제 #7
0
def test_from_wkt_exceptions():
    with pytest.raises(TypeError, match="Expected bytes, got int"):
        pygeos.from_wkt(1)

    with pytest.raises(
        pygeos.GEOSException, match="Expected word but encountered end of stream"
    ):
        pygeos.from_wkt("")

    with pytest.raises(pygeos.GEOSException, match="Unknown type: 'NOT'"):
        pygeos.from_wkt("NOT A WKT STRING")
    def _pandas(cls, column, **kwargs):

        column_shape_format = kwargs.get("column_shape_format")

        # Load the column into a pygeos Geometry vector from numpy array (Series not supported).
        if column_shape_format == "wkt":
            shape_test = geos.from_wkt(column.to_numpy(), on_invalid="ignore")
        elif column_shape_format == "wkb":
            shape_test = geos.from_wkb(column.to_numpy(), on_invalid="ignore")
        elif column_shape_format == "xy":
            shape_df = pd.DataFrame(column.to_list(), columns=("x", "y"))
            shape_test = geos.points(shape_df.lon, y=shape_df.lat)
        else:
            raise NotImplementedError(
                "Column values shape format not implemented.")

        shape_test = geos.union_all(shape_test)

        radius = geos.minimum_bounding_radius(shape_test)
        return radius
예제 #9
0
 def isochrone(self, lat, lon, distance=None, time=None, costing="auto"):
     contours = [{
         "distance": distance
     }] if distance is not None else [{
         "time": time
     }]
     locations = [{"lat": lat, "lon": lon}]
     request_json = {
         "locations": locations,
         "polygons": True,
         "costing": costing,
         "contours": contours
     }
     request_json = json.dumps(request_json)
     r = requests.get(self.url + '/isochrone?json=' + request_json)
     geom = r.json()
     try:
         wkt = shape(geom['features'][0]['geometry']).to_wkt()
     except KeyError:
         raise ValhallaException(geom['error'])
     return pg.from_wkt(wkt)
예제 #10
0
 def __init__(self,
              points_talus,
              roads_wkts_and_buffers,
              talus_lengths,
              edges,
              edges_dist_min=10,
              edges_dist_max=30):
     self.points_talus = points_talus
     self.roads_shapes = pygeos.from_wkt(
         [r[0] for r in roads_wkts_and_buffers])
     self.buffers = np.array([r[1] for r in roads_wkts_and_buffers])
     self.talus_lengths = talus_lengths
     self.edges = edges
     self.edges_dist_min = edges_dist_min
     self.edges_dist_max = edges_dist_max
     self.x_courant = self.points_talus.copy()
     self.nb_vars = len(self.x_courant)
     self.e_lengths_ori = self._get_edges_lengths(self.edges)
     self.angles_ori = self.angles_crossprod()
     self.P = self.get_P()
     self.meta = {"nb_iters": -1, "time_s": -1, "dx_reached": -1}
예제 #11
0
    def addWKT(self, wkt, epsg):
        """Add WKT in static map.
        Parameters:
            wkt (string) The Well-Known-Text representation of geometry.
            epsg (int) The WKT CRS.
        Returns:
            (obj) The matplotlib plot.
        """
        import pygeos as pg
        from pyproj.transformer import Transformer
        geometry = pg.from_wkt(wkt)
        coords = pg.get_coordinates(geometry)
        try:
            transformer = Transformer.from_crs(epsg, 3857, always_xy=True)
            new_coords = transformer.transform(coords[:, 0], coords[:, 1])
            geometry = pg.set_coordinates(geometry, array(new_coords).T)
        except:
            raise Exception('Transformation to EPSG:3857 failed.')
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            minx, miny, maxx, maxy = self._getBorders(new_coords,
                                                      self.aspect_ratio)

            fig, ax = plt.subplots(figsize=(self._width, self._height),
                                   dpi=self.dpi)
            ax.set_xlim(minx, maxx)
            ax.set_ylim(miny, maxy)
            plt.xticks([], [])
            plt.yticks([], [])
            ax.fill(new_coords[0],
                    new_coords[1],
                    facecolor='#50505050',
                    edgecolor='orange',
                    linewidth=3)
            ctx.add_basemap(ax, source=self.basemap)

            self.map = fig
            plt.close(fig)
        return fig
예제 #12
0
def _export_table_from_df(df, geometry_col):
    """Exports a table from a dataframe.
    Parameters:
        df (object): A vaex DataFrame.
        geometry_col (string): The column name containing the geometry.
    Returns:
        (object): An arrow spatial table.
    """
    column_names = df.get_column_names(strings=True)
    arrow_arrays = []

    geometry = pg.from_wkt(df[geometry_col].values)
    geometry = pa.array(pg.to_wkb(geometry))
    arrow_arrays.append(geometry)
    actual_columns = ['geometry']
    for column_name in column_names:
        if column_name == geometry_col:
            continue
        arrow_arrays.append(df[column_name].evaluate())
        actual_columns.append(column_name)
    table = pa.Table.from_arrays(arrow_arrays, actual_columns)
    return table
예제 #13
0
def from_wkt(data):
    """
    Convert a list or array of WKT objects to a np.ndarray[geoms].
    """
    if compat.USE_PYGEOS:
        return pygeos.from_wkt(data)

    import shapely.wkt

    out = []

    for geom in data:
        if geom is not None and len(geom):
            if isinstance(geom, bytes):
                geom = geom.decode("utf-8")
            geom = shapely.wkt.loads(geom)
        else:
            geom = None
        out.append(geom)

    aout = np.empty(len(data), dtype=object)
    aout[:] = out
    return aout
예제 #14
0
def _geometry_from_wkt(table, geom, crs):
    """Transforms an arrow to table to spatial arrow table, using geometry information.
    Extracts the geometry information from an arrow table, creates the WKB geometry
    and writes the geometry information to the arrow table.
    Parameters:
        table (object): The arrow table.
        geom (string): The geometry field name.
        crs (string): The lat, lon CRS.
    Returns:
        (object): The arrow spatial table.
    """
    if geom == 'geometry':
        column_names = table.column_names
        column_names[column_names.index('geometry')] = 'geometry_'
        table = table.rename_columns(column_names)
        geom = 'geometry_'
    geometry = pg.to_wkb(pg.from_wkt(table.column(geom)))
    if crs is None:
        crs = 'EPSG:4326'
    field = pa.field('geometry', 'binary', metadata={'crs': crs})
    table = table.append_column(field, [geometry])
    table = table.drop([geom])
    return table
예제 #15
0
 def __call__(self, form, field):
     from pygeos import from_wkt, GEOSException
     try:
         from_wkt(field.data)
     except GEOSException:
         raise ValidationError(self.message)
예제 #16
0
def test_from_wkt_empty(wkt):
    geom = pygeos.from_wkt(wkt)
    assert pygeos.is_geometry(geom).all()
    assert pygeos.is_empty(geom).all()
    assert pygeos.to_wkt(geom) == wkt
예제 #17
0
def test_from_wkt_all_types(geom):
    wkt = pygeos.to_wkt(geom)
    actual = pygeos.from_wkt(wkt)
    assert pygeos.equals(actual, geom)
예제 #18
0
def test_from_wkb_ignore_on_invalid():
    with pytest.warns(None):
        pygeos.from_wkt("", on_invalid="ignore")

    with pytest.warns(None):
        pygeos.from_wkt("NOT A WKT STRING", on_invalid="ignore")
예제 #19
0
def test_from_wkt_none():
    # None propagates
    assert pygeos.from_wkt(None) is None
예제 #20
0
def test_from_wkt_on_invalid_unsupported_option():
    with pytest.raises(ValueError, match="not a valid option"):
        pygeos.from_wkt(b"\x01\x01\x00\x00\x00\x00", on_invalid="unsupported_option")
예제 #21
0
def test_from_wkt_warn_on_invalid():
    with pytest.warns(Warning, match="Invalid WKT"):
        pygeos.from_wkt("", on_invalid="warn")

    with pytest.warns(Warning, match="Invalid WKT"):
        pygeos.from_wkt("NOT A WKT STRING", on_invalid="warn")
예제 #22
0
 def time_read_from_wkt(self):
     pygeos.from_wkt(self.to_read_wkt)
    def _pandas(cls, column, **kwargs):

        column_shape_format = kwargs.get("column_shape_format")
        place = kwargs.get("place")
        geocoder = kwargs.get("geocoder")
        geocoder_config = kwargs.get("geocoder_config")
        min_value = kwargs.get("min_value")
        max_value = kwargs.get("max_value")
        strict_min = kwargs.get("strict_min")
        strict_max = kwargs.get("strict_max")
        units = kwargs.get("units")

        if min_value is None and max_value is None:
            raise ValueError("min_value and max_value cannot both be None")
        if min_value is not None and max_value is not None and min_value > max_value:
            raise ValueError("min_value cannot be greater than max_value")

        if geocoder not in ["nominatim", "pickpoint", "openmapquest"]:
            raise NotImplementedError(
                "The geocoder is not implemented for this method.")

        # find the reference shape with the geocoder.
        if geocoder is not None:
            try:
                # Specify the default parameters for Nominatim and run query. User is responsible for config and query params otherwise.
                query_params = dict(exactly_one=True, geometry="wkt")
                location = cls.geocode(geocoder, geocoder_config, place,
                                       query_params)
            except:
                raise Exception(
                    "Geocoding configuration and query failed to produce a valid result."
                )
        else:
            raise Exception(
                "A valid geocoder must be provided for this method. See GeoPy for reference."
            )

        # Load the column into a pygeos Geometry vector from numpy array (Series not supported).
        if column_shape_format == "wkt":
            shape_test = geos.from_wkt(column.to_numpy(), on_invalid="ignore")
        elif column_shape_format == "wkb":
            shape_test = geos.from_wkb(column.to_numpy(), on_invalid="ignore")
        elif column_shape_format == "lonlat":
            shape_df = pd.DataFrame(column.to_list(), columns=("lon", "lat"))
            shape_test = geos.points(shape_df.lon, y=shape_df.lat)
        elif column_shape_format == "latlon":
            shape_df = pd.DataFrame(column.to_list(), columns=("lat", "lon"))
            shape_test = geos.points(shape_df.lon, y=shape_df.lat)
        else:
            raise NotImplementedError(
                "Column values shape format not implemented.")

        # verify that all shapes are points and if not, convert to centroid point.
        points_test = pd.Series(shape_test)
        if not points_test.apply(lambda x: geos.get_type_id(x) == 0).all():
            points_test = points_test.map(geos.centroid)

        # convert the geos point to a geopy point.
        points_test = points_test.apply(
            lambda x: lonlat(geos.get_x(x), geos.get_y(x)))

        if location is None:
            raise Exception("Geocoding failed to return a result.")
        else:
            point_ref = lonlat(location.longitude, location.latitude)

        # calculate the distance between the points using geopy
        if units in [
                "km", "kilometers", "kilometres", "kilometer", "kilometre"
        ]:
            column_dist = points_test.apply(
                lambda p: distance(p, point_ref).km)
        elif units in ["m", "meters", "metres", "meter", "metre"]:
            column_dist = points_test.apply(lambda p: distance(p, point_ref).m)
        elif units in ["mi", "miles", "mile"]:
            column_dist = points_test.apply(
                lambda p: distance(p, point_ref).mi)
        elif units in ["ft", "feet", "foot"]:
            column_dist = points_test.apply(
                lambda p: distance(p, point_ref).ft)
        else:
            raise NotImplementedError(
                "Unit conversion has not yet been implemented. Please use one of km, m, mi, ft"
            )

        # Evaluate the between statement (from column_values_between.py)
        if min_value is None:
            if strict_max:
                return column_dist < max_value
            else:
                return column_dist <= max_value

        elif max_value is None:
            if strict_min:
                return min_value < column_dist
            else:
                return min_value <= column_dist

        else:
            if strict_min and strict_max:
                return (min_value < column_dist) & (column_dist < max_value)
            elif strict_min:
                return (min_value < column_dist) & (column_dist <= max_value)
            elif strict_max:
                return (min_value <= column_dist) & (column_dist < max_value)
            else:
                return (min_value <= column_dist) & (column_dist <= max_value)