def crop_raster(self, coordinates, src_path, final_path): """ Recorta la imagen a partir de un par de coordenadas (x,y) determinado. VORSICHT: quizás debería agregar el sistema de coordenadas como parámetro. Actualmente no está de esa manera porque todas las coordenadas con las que se trabajan son ws84 pero nunca se sabe... VORSICHT 2: debería controlar que las coordenadas estén dentro del rango de la imagen """ src = self._load_image(src_path) polygon = box(coordinates[0], coordinates[1], coordinates[2], coordinates[3]) geo_dataframe = gpd.GeoDataFrame({'geometry': polygon}, index=[0], crs=from_epsg(4326)) geo_dataframe = geo_dataframe.to_crs(crs=src.crs.data) # ponele polygon_coordinates = [js.loads(geo_dataframe.to_json())['features'][0]['geometry']] epsg_code = int(src.crs.data['init'][5:]) out_img, out_transform = mask(src, shapes=polygon_coordinates, crop=True) metadata = src.meta.copy() cropped_crs = parse.from_epsg_code(epsg_code).to_proj4() metadata.update({"driver": "GTiff", "height": out_img.shape[1], "width": out_img.shape[2], "transform": out_transform, "crs": cropped_crs, "dtype": rasterio.float32}) with rasterio.open(final_path, "w", **metadata) as dest: dest.write(out_img)
def convert_crs(from_crs, crs_type='proj4', pass_str=False): """ Convenience function to convert one crs format to another. Parameters ---------- from_crs: int or str The crs as either an epsg number or a str in a common crs format (e.g. proj4 or wkt). crs_type: str Output format type of the crs ('proj4', 'wkt', 'proj4_dict', or 'netcdf_dict'). pass_str: str If input is a str, should it be passed though without conversion? Returns ------- str or dict """ ### Load in crs if all([pass_str, isinstance(from_crs, str)]): crs2 = from_crs else: if isinstance(from_crs, int): crs1 = parse.from_epsg_code(from_crs) elif isinstance(from_crs, str): crs1 = parse.from_unknown_text(from_crs) else: raise ValueError('from_crs must be an int or str') ### Convert to standard formats if crs_type == 'proj4': crs2 = crs1.to_proj4() elif crs_type == 'wkt': crs2 = crs1.to_ogc_wkt() elif crs_type in ['proj4_dict', 'netcdf_dict']: crs1a = crs1.to_proj4() crs1b = crs1a.replace('+', '').split()[:-1] crs1c = dict(i.split('=') for i in crs1b) crs2 = dict((i, float(crs1c[i])) for i in crs1c) else: raise ValueError( 'Select one of "proj4", "wkt", "proj4_dict", or "netcdf_dict"') if crs_type == 'netcdf_dict': crs3 = {} for i in crs2: if i in proj4_netcdf_var.keys(): t1 = proj4_netcdf_var[i] if isinstance(t1, tuple): crs3.update({j: crs2[i] for j in t1}) else: crs3.update({proj4_netcdf_var[i]: crs2[i]}) if crs3['transform_name'] in proj4_netcdf_name.keys(): gmn = proj4_netcdf_name[crs3['transform_name']] crs3.update({'transform_name': gmn}) else: raise ValueError('No appropriate netcdf projection.') crs2 = crs3 return crs2
def xy_to_gpd(id_col, x_col, y_col, df=None, crs=2193): """ Function to convert a DataFrame with x and y coordinates to a GeoDataFrame. Parameters ---------- df: Dataframe The DataFrame with the location data. id_col: str or list of str The column(s) from the dataframe to be returned. Either a one name string or a list of column names. xcol: str or ndarray Either the column name that has the x values within the df or an array of x values. ycol: str or ndarray Same as xcol except for y. crs: int The projection of the data. Returns ------- GeoDataFrame Of points. """ if isinstance(x_col, str): geometry = [Point(xy) for xy in zip(df[x_col], df[y_col])] else: geometry = [Point(xy) for xy in zip(x_col, y_col)] if isinstance(id_col, str) & (df is not None): id_data = df[id_col] elif isinstance(id_col, list): if df is not None: id_data = df[id_col] else: id_data = id_col elif isinstance(id_col, (np.ndarray, pd.Series, pd.Index)): id_data = id_col else: raise ValueError('id_data could not be determined') if isinstance(crs, int): crs1 = parse.from_epsg_code(crs).to_proj4() elif isinstance(crs, (str, dict)): crs1 = crs else: raise ValueError('crs must be an int, str, or dict') gpd1 = gpd.GeoDataFrame(id_data, geometry=geometry, crs=crs1) return gpd1
def rd_sql_geo(server, database, table, col_stmt, where_lst=None): """ Function to extract the geometry and coordinate system from an SQL geometry field. Returns a shapely geometry object and a proj4 str. Parameters ---------- server : str The server name. e.g.: 'SQL2012PROD03' database : str The specific database within the server. e.g.: 'LowFlows' table : str The specific table within the database. e.g.: 'LowFlowSiteRestrictionDaily' where_lst : list A list of where statements to be passed and added to the final SQL statement. Returns ------- list of shapely geometry objects The main output is a list of shapely geometry objects for all queried rows of the SQL table. str The second output is a proj4 str of the projection system. """ ## Create connection to database engine = create_engine('mssql', server, database) geo_col_stmt = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=" + "\'" + table + "\'" + " AND DATA_TYPE='geometry'" geo_col = str(pd.read_sql(geo_col_stmt, engine).iloc[0, 0]) geo_srid_stmt = "select distinct " + geo_col + ".STSrid from " + table geo_srid = int(pd.read_sql(geo_srid_stmt, engine).iloc[0, 0]) if where_lst is not None: if len(where_lst) > 0: stmt2 = "SELECT " + col_stmt + ", " + geo_col + ".STAsBinary() as geometry" + " FROM " + table + " where " + " and ".join( where_lst) else: stmt2 = "SELECT " + col_stmt + ", " + geo_col + ".STAsBinary() as geometry" + " FROM " + table else: stmt2 = "SELECT " + col_stmt + ", " + geo_col + ".STAsBinary() as geometry" + " FROM " + table df2 = pd.read_sql(stmt2, engine) df2['geometry'] = df2.geometry.apply(lambda x: loads(x)) # proj4 = from_epsg_code(geo_srid).to_proj4() # crs = {'init' :'epsg:' + str(geo_srid)} crs = parse.from_epsg_code(geo_srid).to_proj4() geo_df = GeoDataFrame(df2, geometry='geometry', crs=crs) return geo_df
def crop(self, lat, long, outPath): dimX = 224 dimY = 224 x, y, zN, zL = utm.from_latlon(lat, long) with rio.open(self.filepath, "r") as raster: minx, miny = x - dimX/2, y - dimY/2 maxx, maxy = x + dimX/2, y + dimY/2 square = box(minx, miny, maxx, maxy) #gdf = gpd.GeoDataFrame({'geometry': square}, index = [0], crs=from_epsg(4326)) gdf = gpd.GeoDataFrame({'geometry': square}, index = [0], crs=raster.crs.data) print(raster.crs.data) #gdf = gdf.to_crs(crs = raster.crs.data) #print("no crash") coords = self.__getFeatures(gdf) out_img, out_transform = mask(raster, coords, crop = True) out_meta = raster.meta.copy() epsg_code = int(raster.crs.data['init'][5:]) print(epsg_code) out_meta.update({"driver": "GTiff", "height": out_img.shape[1], "width": out_img.shape[2], "transform": out_transform, "crs": from_epsg_code(epsg_code).to_proj4()}) with rio.open(outPath, "w", **out_meta) as dest: dest.write(out_img)
def clipper(request, indice_requested=None, show_flag=False, base_path=str): """ Clips the raster image to the ROI and saves it. :param request: request number for the downloaded images :type request: str :rtype: None """ print("=======================") print("Clipping indices to ROI") indice_list = ["ndmi", "ndvi", "savi", "msavi", "ndwi"] choice = [] for idx, boolean in enumerate(indice_requested): if boolean == True: choice.append(idx) indices = [indice_list[i] for i in indice_requested] # indices = ["msavi"] for index in indices: fp = glob.glob(f"{base_path}.{request}/**/*{index}*", recursive=True) # for f_name in fp: # print(f_name) length_path_list = len(fp) print(f"length of list : {length_path_list}") out_tif = [None] * length_path_list for i in range(length_path_list): split_path = fp[i].split('/') out_tif[i] = '/'.join(split_path[:-1] + [ f"{split_path[-2]}_clipped_{indices[0]}_{split_path[-1].split('_')[-1]}" ]) # for f_path in fp: # print(f_path) # for out in out_tif: # print(out) data = [None] * length_path_list geo = [None] * length_path_list coords = [None] * length_path_list out_img = [None] * length_path_list out_transform = [None] * length_path_list out_meta = [None] * length_path_list epsg_code = [None] * length_path_list for i, f_path in enumerate(fp): data[i] = rasterio.open(f_path) [minx, miny, maxx, maxy] = csv_crawler(clipper=True) print(minx, miny, maxx, maxy) bbox = box(minx, miny, maxx, maxy) for i in range(length_path_list): geo[i] = gpd.GeoDataFrame({'geometry': bbox}, index=[0], crs=from_epsg(4326)) # noinspection PyUnresolvedReferences geo[i] = geo[i].to_crs(crs=data[i].crs.data) for i in range(length_path_list): # noinspection PyTypeChecker coords[i] = getFeatures(geo[i]) # print(coords[i]) for i in range(length_path_list): # print(i) out_img[i], out_transform[i] = mask(data[i], shapes=coords[i], crop=True) for i in range(length_path_list): out_meta[i] = data[i].meta.copy() # print(out_meta[i]) for i in range(length_path_list): # temp_dict = data[i].crs.data # print(temp_dict['init']) epsg_code[i] = int(data[i].crs.data['init'].split(':')[-1]) # print(i, epsg_code[i]) for i in range(length_path_list): out_meta[i].update({ "driver": "GTiff", "height": out_img[i].shape[1], "width": out_img[i].shape[2], "transform": out_transform[i], "crs": parse.from_epsg_code(epsg_code[i]).to_proj4() }) for i in range(length_path_list): with rasterio.open(out_tif[i], "w", **out_meta[i]) as destination: destination.write(out_img[i]) if show_flag == True: for i in range(length_path_list): clipped = rasterio.open(out_tif[i]) show(clipped, cmap="terrain") # print(clipped.shape) print("Indices clipped sucessfully!!!")