I am trying to convert my .shp file from an EPSG value of 26917 to a EPSG value of 4326. These seems to be an issue with my .shp file not having the EPSG built in. I have tried changing the EPSG using the code below but I receive this error: No CRS found in the GeoDataFrame. Setting to EPSG:4326.
Cannot reproject geometries because no source CRS is defined.
And when I try to plot the geometries later the EPSG value never changes. Any suggestions or advice would be greatly appreciated.
using ArchGDAL
using GeoDataFrames
Load the shapefile into a GeoDataFrame
shapefile_path = ββ¦\Data & Resources for Ivy\Williford_10row_30m_rectangle.shp\Williford_10row_30m_rectangle.shpβ
geo_df = GeoDataFrames.read(shapefile_path)
Check if the CRS exists in the GeoDataFrame
if in(:crs, names(geo_df))
println("Original CRS: ", geo_df.crs)
else
println(βNo CRS found in the GeoDataFrame. Setting to EPSG:4326.β)
# Create a new CRS reference
crs = ArchGDAL.importEPSG(4326) # Adjust EPSG code as necessary
# Assign the CRS to the GeoDataFrame
geo_df[!, :crs] .= [crs] # Use broadcasting to assign CRS as a vector
end
Define the target CRS (e.g., WGS 84)
target_crs = ArchGDAL.importEPSG(4326) # Change to the desired target CRS if different
Extract geometries from the GeoDataFrame
geometries = geo_df.geom
Reproject the geometries if the source CRS is set
if in(:crs, names(geo_df))
source_crs = geo_df.crs
# Reproject the geometries
reprojected_geometries = ArchGDAL.reproject(geometries, source_crs, target_crs)
# Assign the reprojected geometries back to the GeoDataFrame
geo_df.geom .= reprojected_geometries # Use broadcasting to assign
# Output the WKT of the reprojected geometries to verify
println("Reprojected Geometries:")
for geom in geo_df.geom
wkt_geom = ArchGDAL.toWKT(geom)
println(wkt_geom)
end
else
println(βCannot reproject geometries because no source CRS is defined.β)
end
The .shp file doesnβt store the CRS. You need to find the .proj file in the same directory. If you donβt have one, then you need to ask the author of the file for the CRS.
Hi @ivyc, welcome to the community. May I ask where you got the idea to store the crs as a column in the DataFrame?
The CRS in a (Geo)DataFrame can be stored in its metadata and/or in the stored geometries. It can also be hardcoded during writing (crs keyword). I just made a new release of GeoDataFrames (v0.3.11), which enables the following:
using GeoDataFrames # no other imports needed
gdf = GeoDataFrames.read("test.shp")
crs(gdf) # nothing, because no .prj was found
df = reproject(gdf, EPSG(26917), EPSG(4326))
crs(df) # EPSG{1}((4326,))
GeoDataFrames.write("test_reprojected.shp", df)
As pointed out by JΓΊlio, shapefiles requires a separate file for storing their crs. I would suggest to move away from shapefiles, and use something like a geopackage. Just GeoDataFrames.write("test.gpkg", df) would work for that.
Let me know if this works for you, and whether you have any other questions.
To add another option, this how we do that with GMT.jl The test file is a tinny one from the GDAL autotests, renamed to .shp.zip to simplify things. But since .zip files (or .shp) are not accepted here I cannot provide that data file
D = gmtread("poly.shp.zip")
Vector{GMTdataset} with 10 segments
...
PROJ: +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +units=m +no_defs
...
Hi, thank you for your response. Honestly I am picking up this project from some other students and I am just trying to use what they had started, so that is the only reason the crs is stored in the DataFrame.