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)
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))
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
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)
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")
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
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)
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}
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
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
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
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
def __call__(self, form, field): from pygeos import from_wkt, GEOSException try: from_wkt(field.data) except GEOSException: raise ValidationError(self.message)
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
def test_from_wkt_all_types(geom): wkt = pygeos.to_wkt(geom) actual = pygeos.from_wkt(wkt) assert pygeos.equals(actual, geom)
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")
def test_from_wkt_none(): # None propagates assert pygeos.from_wkt(None) is None
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")
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")
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)