def test_to_wkt(): point = pygeos.points(1, 1) actual = pygeos.to_wkt(point) assert actual == "POINT (1 1)" actual = pygeos.to_wkt(point, trim=False) assert actual == "POINT (1.000000 1.000000)" actual = pygeos.to_wkt(point, rounding_precision=3, trim=False) assert actual == "POINT (1.000 1.000)"
def test_to_wkt_3D(): # 3D points point_z = pygeos.points(1, 1, 1) actual = pygeos.to_wkt(point_z) assert actual == "POINT Z (1 1 1)" actual = pygeos.to_wkt(point_z, output_dimension=3) assert actual == "POINT Z (1 1 1)" actual = pygeos.to_wkt(point_z, output_dimension=2) assert actual == "POINT (1 1)" actual = pygeos.to_wkt(point_z, old_3d=True) assert actual == "POINT (1 1 1)"
def export_csv(gdf, path, latlon=False, geom=True, lat_name='lat', lon_name='lot', geom_name='geometry', column_names=None, selection=False, virtual=True, chunksize=1000000, **kwargs): """ Writes GeoDataFrame to a CSV spatial file. """ import pandas as pd sep = kwargs.pop('delimiter', ',') column_names = column_names or gdf.get_column_names(virtual=virtual, strings=True) dtypes = gdf[column_names].dtypes fields = column_names[:] if latlon: fields.append(lat_name) fields.append(lon_name) if geom: fields.append(geom_name) geom_arr = gdf.geometry._geometry if selection not in [None, False] or gdf.filtered: mask = gdf.evaluate_selection_mask(selection) geom_arr = geom_arr.filter(mask) for i1, i2, chunks in gdf.evaluate_iterator(column_names, chunk_size=chunksize, selection=selection): if latlon: coordinates = pg.get_coordinates( pg.centroid(pg.from_wkb(geom_arr[i1:i2]))).T chunks.append(coordinates[0]) chunks.append(coordinates[1]) if geom: chunks.append(pg.to_wkt(pg.from_wkb(geom_arr[i1:i2]))) chunk_dict = {col: values for col, values in zip(fields, chunks)} chunk_pdf = pd.DataFrame(chunk_dict) if i1 == 0: # Only the 1st chunk should have a header and the rest will be appended mode = 'w' header = True else: mode = 'a' header = False chunk_pdf.to_csv(path_or_buf=path, mode=mode, header=header, sep=sep, index=False, **kwargs)
def filter_process(session, file, action, wkt, **kwargs): """Wrapper function for the filtering process. Arguments: session (dict): Dictionary with session information. file (str): The full path of the source file. action (str): The filtering operation. wkt (str): Well-Known Text of the input geometry. **kwargs: Additional keyword arguments for the filtering operation. Returns: (tuple): - (str): Request ticket. - (str): Full path of the resulted file(s). - (bool): Whether operation succeeded. - (str): Error message in case of failure. """ try: crs = kwargs.pop('crs', None) read_options = kwargs.pop('read_options', {}) geovaex = GeoVaex(file, session['working_path'], crs=crs, read_options=read_options) if action == 'travel_distance' or action == 'travel_time': valhalla = Valhalla() distance = kwargs.pop('distance', None) time = kwargs.pop('time', None) costing = kwargs.pop('costing', None) if costing == '': costing = None lat, lon = wkt polygon = valhalla.isochrone( lat, lon, distance=distance, costing=costing ) if action == 'travel_distance' else valhalla.isochrone( lat, lon, time=time, costing=costing) if geovaex.gdf.geometry.crs.to_epsg() != 4326: from_ = pyproj.crs.CRS.from_epsg(4326) to_ = geovaex.gdf.geometry.crs transformer = pyproj.Transformer.from_crs(from_, to_, always_xy=True) def transform(coords): x, y = transformer.transform(*coords.T) return np.array([x, y]).T polygon = pg.apply(polygon, transform) wkt = pg.to_wkt(polygon) action = 'within' export = geovaex.filter_(action, wkt, **kwargs) except ResultedEmptyDataFrame as e: return (session['ticket'], None, True, str(e)) except Exception as e: return (session['ticket'], None, False, str(e)) return (session['ticket'], export, True, None)
def _as_table(self, i1, i2, j1=None, j2=None, format='plain', to_wkt=True): import tabulate values_list = [] if i2 - i1 > 0: for i in range(i1, i2): value = self[i] if isinstance(value, (bytes, bytearray)): value = pg.to_wkt(pg.from_wkb(value)) values_list.append([i, value]) if j1 is not None and j2 is not None: values_list.append(['...']) for i in range(j1, j2): value = self[i] if isinstance(value, (bytes, bytearray)): value = pg.to_wkt(pg.from_wkb(value)) values_list.append([i, value]) return str(tabulate.tabulate(values_list, tablefmt=format))
def test_to_wkb_srid(): # hex representation of POINT (0 0) with SRID=4 ewkb = "01010000200400000000000000000000000000000000000000" wkb = "010100000000000000000000000000000000000000" actual = pygeos.from_wkb(ewkb) assert pygeos.to_wkt(actual, trim=True) == "POINT (0 0)" assert pygeos.to_wkb(actual, hex=True, byte_order=1) == wkb assert pygeos.to_wkb(actual, hex=True, include_srid=True, byte_order=1) == ewkb point = pygeos.points(1, 1) point_with_srid = pygeos.set_srid(point, np.int32(4326)) result = pygeos.to_wkb(point_with_srid, include_srid=True, byte_order=1) assert np.frombuffer(result[5:9], "<u4").item() == 4326
def mbr(self): """Returns the Minimum Bounding Rectangle. Returns: (string) The WKT representation of the MBR. """ if not self._has_geometry: warnings.warn('DataFrame is not spatial.') return None total_bounds = self.df.geometry.total_bounds() transformer = pyproj.Transformer.from_crs(self.crs, "EPSG:4326", always_xy=True) coords = pg.get_coordinates(total_bounds) new_coords = transformer.transform(coords[:, 0], coords[:, 1]) transformed = pg.set_coordinates(total_bounds, np.array(new_coords).T) return pg.to_wkt(transformed)
def mbr(self): """Computes the MBR of the dataset. Returns: (string) The WKT representation of the MBR. """ variables = self.dataset.variables.keys() if self._lat_attr not in variables or self._lon_attr not in variables: return None lat_min = self.dataset.variables[self._lat_attr][:].min() lat_max = self.dataset.variables[self._lat_attr][:].max() lon_min = self.dataset.variables[self._lon_attr][:].min() lon_max = self.dataset.variables[self._lon_attr][:].max() if self._short_crs == 'WGS 84' and (lon_min >= 0 and lon_max > 180.): lon_min -= 180. lon_max -= 180. return to_wkt(box(lon_min, lat_min, lon_max, lat_max))
def convex_hull(self, chunksize=50000, max_workers=None): """Returns the convex hull of all geometries in the dataframe. Parameters: chunksize (int): The chunksize (number of features) for each computation. max_workers (int): The number of workers to be used, if None equals to number of available cores. Returns: (string) The WKT representation of convex hull. """ if not self._has_geometry: warnings.warn('DataFrame is not spatial.') return None hull = self.df.geometry.convex_hull_all(chunksize=chunksize, max_workers=max_workers) transformer = pyproj.Transformer.from_crs(self.crs, "EPSG:4326", always_xy=True) coords = pg.get_coordinates(hull) new_coords = transformer.transform(coords[:, 0], coords[:, 1]) transformed = pg.set_coordinates(hull, np.array(new_coords).T) return pg.to_wkt(transformed)
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_to_wkt_multipoint_with_point_empty_errors(): # Test if segfault is prevented geom = pygeos.multipoints([empty_point, point]) with pytest.raises(ValueError): pygeos.to_wkt(geom)
def test_to_wkt_geometrycollection_with_point_empty(): collection = pygeos.geometrycollections([empty_point, point]) # do not check the full value as some GEOS versions give # GEOMETRYCOLLECTION Z (...) and others give GEOMETRYCOLLECTION (...) assert pygeos.to_wkt(collection).endswith("(POINT EMPTY, POINT (2 3))")
def test_to_wkt_point_empty(): assert pygeos.to_wkt(empty_point) == "POINT EMPTY"
def setup(self): self.to_write = pygeos.polygons(np.random.random((10000, 100, 2))) self.to_read_wkt = pygeos.to_wkt(self.to_write) self.to_read_wkb = pygeos.to_wkb(self.to_write)
def verify(g, shp, thorough=False): #--------------------------------------------------------------------- logger.info(' Verify grid against coastline\n') #--------------------------------------------------------------------- lon_min = g.Dataset.SCHISM_hgrid_node_x.values.min() lon_max = g.Dataset.SCHISM_hgrid_node_x.values.max() lat_min = g.Dataset.SCHISM_hgrid_node_y.values.min() lat_max = g.Dataset.SCHISM_hgrid_node_y.values.max() c = shp.cx[lon_min:lon_max, lat_min:lat_max] # ## Test polygons d = g.Dataset x = d.SCHISM_hgrid_node_x.values y = d.SCHISM_hgrid_node_y.values tri = d.SCHISM_hgrid_face_nodes.values nodes = pd.DataFrame({'lon': x, 'lat': y}) elems = pd.DataFrame(tri, columns=['a', 'b', 'c']) bnodes = g.Dataset[['node', 'id', 'type']].to_dataframe() # ### Find the invalid nodes (that cross the coasts) cos = pygeos.from_shapely(c.geometry) cos_ = pygeos.set_operations.union_all(cos) gps = pygeos.points(list(nodes.values)) gtree = pygeos.STRtree(gps) invs = gtree.query(cos_, predicate='contains').tolist() #--------------------------------------------------------------------- logger.info('Number of nodes within the coastlines {}\n'.format(len(invs))) #--------------------------------------------------------------------- nps = len(invs) nels = 1 if thorough: # ### Find invalid elements (that cross land) # cells to polygons ap = nodes.loc[elems.a] bp = nodes.loc[elems.b] cp = nodes.loc[elems.c] elems['ap'] = ap.values.tolist() elems['bp'] = bp.values.tolist() elems['cp'] = cp.values.tolist() n = 2 al = elems.ap + elems.bp + elems.cp + elems.ap coords = [[l[i:i + n] for i in range(0, len(l), n)] for l in al] elems['coordinates'] = coords jig = pygeos.polygons(coords) jtree = pygeos.STRtree(jig) jig_ = pygeos.set_operations.union_all(jig) cross = pygeos.set_operations.intersection(jig_, cos_) # #### convert to dataframe fd = pd.DataFrame({'overlap': pygeos.to_wkt(cross)}, index=[0]) fd['overlap'] = fd['overlap'].apply(shapely.wkt.loads) gover = gp.GeoDataFrame(fd, geometry='overlap') # #### Reject small injuctions ipols = gover.explode().loc[0] ipols.columns = ['geometry'] mask = ipols.area.values == 0. ipols = ipols[~mask].reset_index(drop=True) ipols = gp.GeoDataFrame(ipols) #--------------------------------------------------------------------- logger.info( 'Number of elements intersecting the coastlines {}\n'.format( ipols.shape[0])) #--------------------------------------------------------------------- nels = ipols.shape[0] if nps == 0 and nels == 0: #--------------------------------------------------------------------- logger.info('Grid is verified against the coastline') #--------------------------------------------------------------------- return True elif nps == 0: #--------------------------------------------------------------------- logger.info('Grid is node verified against the coastline') #--------------------------------------------------------------------- return True else: #--------------------------------------------------------------------- logger.warning('Grid is not verified against the coastline') #--------------------------------------------------------------------- return False
def to_wkt(arr, **kwargs): return pg.to_wkt(from_wkb(arr), **kwargs)
def get_linestrings_wkts(self): points = self.x_courant.reshape(-1, 2) lines = LSDisplacer._lines_from_points(points, self.talus_lengths) lines = pygeos.to_wkt(lines, rounding_precision=-1) return lines
def check(g, shp, bad): # ## Read Grid # g = pg.grid(type='tri2d',grid_file='/eos/jeodpp/data/projects/FLOODS-COAST/floods-coast/OPER/grids/eur_fixed.gr3') lon_min = g.Dataset.SCHISM_hgrid_node_x.values.min() lon_max = g.Dataset.SCHISM_hgrid_node_x.values.max() lat_min = g.Dataset.SCHISM_hgrid_node_y.values.min() lat_max = g.Dataset.SCHISM_hgrid_node_y.values.max() c = shp.cx[lon_min:lon_max, lat_min:lat_max] # ## Test polygons d = g.Dataset x = d.SCHISM_hgrid_node_x.values y = d.SCHISM_hgrid_node_y.values tri = d.SCHISM_hgrid_face_nodes.values nodes = pd.DataFrame({'lon': x, 'lat': y}) elems = pd.DataFrame(tri, columns=['a', 'b', 'c']) bnodes = g.Dataset[['node', 'id', 'type']].to_dataframe() # drop bad dpoints = [bad] # get corresponding elements ma = elems.a.isin(dpoints) mb = elems.b.isin(dpoints) mc = elems.c.isin(dpoints) ids1 = elems[ma].index ids2 = elems[mb].index ids3 = elems[mc].index dropels = list( np.hstack([ids1, ids2, ids3]) ) #these are the elements to be dropped - the ones which have dropped nodes dropels = np.unique(dropels) #take care of the boundary nodes dns = np.unique(elems.loc[dropels, ['a', 'b', 'c']].values.flatten()) #get boundary nodes ibs = [x for x in dns if x not in dpoints] maxb = bnodes.id.min() # check if new boundary nodes merge if bnodes.node.isin(ibs).sum() > 0: if bnodes.node.isin(ibs).sum() > 0: ids_ = np.unique(bnodes.loc[bnodes.node.isin(ibs), 'id'].values) ids_.sort() if ids_.shape[0] > 1: itype = bnodes.loc[bnodes.id == ids_[-1], ['type']].values[0] bnodes.loc[bnodes.id.isin(ids_[:-1]), 'id'] = ids_[-1] ibs = pd.DataFrame({ 'node': ibs, 'type': itype, 'id': ids_[-1] }, index=np.arange(len(ibs))) else: itype, iid = bnodes.loc[bnodes.node.isin(ibs), ['type', 'id']].values[0] ibs = pd.DataFrame({ 'node': ibs, 'type': itype, 'id': iid }, index=np.arange(len(ibs))) else: maxb -= 1 ibs = pd.DataFrame({ 'node': ibs, 'type': 1, 'id': maxb }, index=np.arange(len(ibs))) bnodes = pd.concat([bnodes, ibs], ignore_index=True) bnodes = bnodes.drop_duplicates() #remove nodes, elems = nreduce(dpoints, dropels, nodes, elems) bnodes = bnodes.drop(bnodes.loc[bnodes.node.isin(dpoints)].index) sg = nodes.reset_index().set_index('tag') idx = bnodes.node.values, 'index' nvs = sg.loc[idx].values bnodes.node = nvs bnodes = bnodes.reset_index(drop=True) bnodes.index.name = 'bnodes' bnodes = bnodes.drop_duplicates('node') nodes = nodes.drop('tag', axis=1) # #### Check for hanging nodes # Look for hanging nodes tri3 = elems.values[:, :3] q = np.unique(tri3.flatten()) # all the unique nodes in elements dq = list(set(range(nodes.shape[0])) - set(q)) # the ones that are in gcrop but not in elems dq.sort() if len(dq) > 0: nodes, elems, bnodes = drop(nodes, elems, bnodes, dq) # ### Find the invalid nodes (that cross the coasts) cos = pygeos.from_shapely(c.geometry) cos_ = pygeos.set_operations.union_all(cos) gps = pygeos.points(list(nodes.values)) gtree = pygeos.STRtree(gps) invs = gtree.query(cos_, predicate='contains').tolist() # ### Find invalid elements (that cross land) # cells to polygons ap = nodes.loc[elems.a] bp = nodes.loc[elems.b] cp = nodes.loc[elems.c] elems['ap'] = ap.values.tolist() elems['bp'] = bp.values.tolist() elems['cp'] = cp.values.tolist() n = 2 al = elems.ap + elems.bp + elems.cp + elems.ap coords = [[l[i:i + n] for i in range(0, len(l), n)] for l in al] elems['coordinates'] = coords jig = pygeos.polygons(coords) jtree = pygeos.STRtree(jig) jig_ = pygeos.set_operations.union_all(jig) cross = pygeos.set_operations.intersection(jig_, cos_) # #### convert to dataframe fd = pd.DataFrame({'overlap': pygeos.to_wkt(cross)}, index=[0]) fd['overlap'] = fd['overlap'].apply(shapely.wkt.loads) gover = gp.GeoDataFrame(fd, geometry='overlap') # #### Reject small injuctions ipols = gover.explode().loc[0] ipols.columns = ['geometry'] mask = ipols.area.values == 0. ipols = ipols[~mask].reset_index(drop=True) ipols = gp.GeoDataFrame(ipols) # Sometimes the edges cross the coastlines but the nodes not # ## Get overlapping elements for each contour jcos = pygeos.from_shapely(ipols.geometry) maxb = bnodes.id.min() if len(jcos) > 0: m = 0 for l in tqdm(range(len(jcos))): con = jcos[l] m += 1 jig = pygeos.polygons(elems.coordinates.to_list()) jtree = pygeos.STRtree(jig) ci = jtree.query(con, predicate='intersects').tolist() if not ci: continue delems = elems.loc[ci].index.values dnodes = np.unique(elems.loc[ci, ['a', 'b', 'c']].values.flatten()) # print (ci, dnodes, delems) inp = pygeos.points(list(nodes.loc[dnodes].values)) itree = pygeos.STRtree(inp) ipoints = itree.query(cos_, predicate='contains').tolist() ipoints = nodes.loc[dnodes].index[ipoints].values #find elements that use these points ma = elems.a.isin(ipoints) mb = elems.b.isin(ipoints) mc = elems.c.isin(ipoints) ids1 = elems[ma].index ids2 = elems[mb].index ids3 = elems[mc].index dropels = list( np.hstack([ids1, ids2, ids3]) ) #these are the elements to be dropped - the ones which have dropped nodes dropels = np.unique(dropels) dds = np.unique(np.concatenate((delems, dropels), axis=0)) #get all nodes dns = np.unique(elems.loc[dds, ['a', 'b', 'c']].values.flatten()) #get boundary nodes ibs = [x for x in dns if x not in ipoints] # print (ipoints, ibs) # check if new boundary nodes merge if bnodes.node.isin(ibs).sum() > 0: ids_ = np.unique(bnodes.loc[bnodes.node.isin(ibs), 'id'].values) ids_.sort() if ids_.shape[0] > 1: itype = bnodes.loc[bnodes.id == ids_[-1], ['type']].values[0] bnodes.loc[bnodes.id.isin(ids_[:-1]), 'id'] = ids_[-1] ibs = pd.DataFrame( { 'node': ibs, 'type': itype, 'id': ids_[-1] }, index=np.arange(len(ibs))) else: itype, iid = bnodes.loc[bnodes.node.isin(ibs), ['type', 'id']].values[0] ibs = pd.DataFrame({ 'node': ibs, 'type': itype, 'id': iid }, index=np.arange(len(ibs))) else: maxb -= 1 ibs = pd.DataFrame({ 'node': ibs, 'type': 1, 'id': maxb }, index=np.arange(len(ibs))) bnodes = pd.concat([bnodes, ibs], ignore_index=True) bnodes = bnodes.drop_duplicates() nodes, elems = nreduce(ipoints, dds, nodes, elems) # Renumber boundary nodes if ipoints.size > 0: bnodes = bnodes.drop( bnodes.loc[bnodes.node.isin(ipoints)].index) sg = nodes.reset_index().set_index('tag') # print(ipoints.size) idx = bnodes.node.values, 'index' nvs = sg.loc[idx].values bnodes.node = nvs nodes = nodes.drop('tag', axis=1) # #### Check for hanging nodes # Look for hanging nodes tri3 = elems.values[:, :3] q = np.unique(tri3.flatten()) # all the unique nodes in elements dq = list(set(range(nodes.shape[0])) - set(q)) # the ones that are in gcrop but not in elems dq.sort() if len(dq) > 0: nodes, elems, bnodes = drop(nodes, elems, bnodes, dq) # Get the largest continous area jels = pygeos.polygons(elems.coordinates.values.tolist()) wat = pygeos.set_operations.coverage_union_all(jels) w = pd.DataFrame({'overlap': pygeos.to_wkt(wat)}, index=[0]) w['overlap'] = w['overlap'].apply(shapely.wkt.loads) gw = gp.GeoDataFrame(w, geometry='overlap') gw = gw.explode() gw = gw.droplevel(0) gw.columns = ['geometry'] gw['length'] = gw['geometry'][:].length gw = gw.sort_values(by='length', ascending=0) #optional gw = gw.reset_index(drop=True) # indentify the elements of the large polygon cgw = pygeos.from_shapely(gw.loc[1:].geometry) cgw_ = pygeos.set_operations.union_all(cgw) jtree_ = pygeos.STRtree(jels) invs = jtree_.query(cgw_, predicate='intersects').tolist() if len(invs) > 0: #Sort the elements (some shouldn't be there) qnodes = np.unique( [elems.loc[x, ['a', 'b', 'c']].values.astype(int) for x in invs]) nnodes = pygeos.points(list(nodes.loc[qnodes].values)) ntree = pygeos.STRtree(nnodes) nels_ = pygeos.from_shapely(gw.loc[0].geometry.buffer(.00001)) nevs = ntree.query(nels_, predicate='intersects').tolist() pns = qnodes[nevs] dpoints = [x for x in qnodes if x not in pns] #find elements that use these points ma = elems.a.isin(dpoints) mb = elems.b.isin(dpoints) mc = elems.c.isin(dpoints) ids1 = elems[ma].index ids2 = elems[mb].index ids3 = elems[mc].index dropels = list( np.hstack([ids1, ids2, ids3]) ) #these are the elements to be dropped - the ones which have dropped nodes dropels = np.unique(dropels) #Remove the invalid elements nodes, elems = nreduce(dpoints, dropels, nodes, elems) #reindex boundary nodes bnodes = bnodes.drop(bnodes.loc[bnodes.node.isin(dpoints)].index) sg = nodes.reset_index().set_index('tag') idx = bnodes.node.values, 'index' nvs = sg.loc[idx].values bnodes.node = nvs bnodes = bnodes.reset_index(drop=True) bnodes.index.name = 'bnodes' nodes = nodes.drop('tag', axis=1) # Look for hanging nodes tri3 = elems.values[:, :3] q = np.unique(tri3.flatten()) # all the unique nodes in elements dq = list(set(range(nodes.shape[0])) - set(q)) # the ones that are in gcrop but not in elems dq.sort() if len(dq) > 0: nodes, elems, bnodes = drop(nodes, elems, bnodes, dq) # check if empty boundary lk = -1 for k in range(-1, bnodes.id.min().astype(int) - 1, -1): if not bnodes.loc[bnodes.id == k].empty: bnodes.loc[bnodes.id == k, 'id'] = lk lk -= 1 bnodes = bnodes.drop_duplicates('node') # ### create the new dataset nod = nodes.loc[:, ['lon', 'lat']].to_xarray().rename({ 'index': 'nSCHISM_hgrid_node', 'lon': 'SCHISM_hgrid_node_x', 'lat': 'SCHISM_hgrid_node_y' }) nod = nod.drop_vars('nSCHISM_hgrid_node') depx = xr.Dataset({ 'depth': (['nSCHISM_hgrid_node'], np.zeros(nod.nSCHISM_hgrid_node.shape[0])) }) elsx = xr.DataArray( elems.loc[:, ['a', 'b', 'c']].values, dims=['nSCHISM_hgrid_face', 'nMaxSCHISM_hgrid_face_nodes'], name='SCHISM_hgrid_face_nodes') ngr = xr.merge([nod, depx, elsx, bnodes.to_xarray()]) # total return ngr
def to_wkt(data, **kwargs): if compat.USE_PYGEOS: return pygeos.to_wkt(data, **kwargs) else: out = [geom.wkt if geom is not None else None for geom in data] return np.array(out, dtype=object)
def test_to_wkt_none(): # None propagates assert pygeos.to_wkt(None) is None
def time_write_to_wkt(self): pygeos.to_wkt(self.to_write)
def test_to_wkt_exceptions(): with pytest.raises(TypeError): pygeos.to_wkt(1) with pytest.raises(pygeos.GEOSException): pygeos.to_wkt(point, output_dimension=4)