'GeoDataFrame is Inverted when I converted from Raster to Vector using RasterIO
I'm currently using this code to convert a raster file to a geodataframe:
import rasterio
from rasterio.features import shapes
mask = None
with rasterio.open(#INSERT TIF FILE HERE) as src:
image = src.read(1) # first band, not sure yet how to do it with multiple bands
results = (
{'properties': {'raster_val': v}, 'geometry': s}
for i, (s, v)
in enumerate(
shapes(image, mask=mask))) geoms = list(results)
import geopandas as gpd
gpd_polygonized_raster = gpd.GeoDataFrame.from_features(geoms)
The problem is, the geodataframe is showing upside down instead of its expected oreintation.
Any help on this would be appreciated. Thank you!
Take note that the TIFF file has a projection already of EPSG:4326.
Solution 1:[1]
- you can use shapely
affine_transform()
- have picked up a sample GEOTIFF* to make this working example
import rasterio
from rasterio.features import shapes
import geopandas as gpd
from shapely.affinity import affine_transform as T
from pathlib import Path
import plotly.express as px
import requests
from pathlib import Path
# https://www.sciencebase.gov/catalog/item/53f5a87ae4b09d12e0e8547b
url = "https://www.sciencebase.gov/catalog/file/get/53f5a87ae4b09d12e0e8547b?f=__disk__7f%2Fe7%2F94%2F7fe7943c77f2c6c4eb4c129153fd4e80f6079091"
f = Path.cwd().joinpath("FAA_UTM18N_NAD83.tif")
r = requests.get(url, stream=True, headers={"User-Agent": "XY"})
with open(f, "wb") as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)
results = []
with rasterio.open(f) as src:
crs = src.crs
for layer in range(1,20):
try:
image = src.read(layer) # use all bands / layers
results += [
{"properties": {"raster_val": v, "layer":layer}, "geometry": s}
for i, (s, v) in enumerate(shapes(image, mask=src.dataset_mask()))
]
except IndexError as e:
print(e)
break
gdf = gpd.GeoDataFrame.from_features(results, crs=crs)
# flip top and bottom using affine transform
gdf["geometry"] = gdf["geometry"].apply(lambda g: T(g, [1, 0, 0, -1, 0, 0]))
# exclude areas where it's white in source TIFF
gdf.to_crs("EPSG:4326").loc[gdf["raster_val"].lt(255)].plot(column="raster_val")
Solution 2:[2]
you could vectorize the tif file using gdal_polygonize and then read the vector file with geopandas
import subprocess
import geopandas as gpd
# execute 'gdal_polygonize.py' in the shell
cmd = ['gdal_polygonize.py', tif_path, vector_path]
subprocess.call(cmd, shell=True)
# read the vector file (.shp, .geojson, etc..)
gpd_polygonized_raster = gpd.read_file(vector_path)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Rob Raymond |
Solution 2 | EOEAGLE |