-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve cellsize and switch from Archgdal to Proj #768
Conversation
How do we get rid of ArchGDAL? |
I was thinking we could just make a |
But how do we deal with Proj/Wkt, a lot of different text strings can be wgs84 |
The way we already do it - I don't think this line of code needs ArchGDAL
|
Yeah that's ArchGDAL doing that conversion ;) |
I was thrown off by the GeoFormatTypes wrapper, but makes sense. Let's just leave it as it is, then. |
Yes ArchGDAL actually pirates |
Can we take this opportunity to rename |
There is room for significant speed gains for small small grid spacing: #For lat/lon aligned rasters with small grid spacing, this will be much faster and just as accurate:
# load packages
import Rasters: EPSG
using Rasters
using Rasters.Lookups
using DimensionalData
# define meters to lat/lon function
#"""
meters2lonlat_distance(distance_meters, latitude_degrees)
Returns the decimal degree distance along latitude and longitude lines given a distance in
meters and a latitude in decimal degrees.
# Example usage:
#```julia-repl
julia> distance_meters = 1000.0;
julia> latitude_degrees = 45.0;
julia> lat, lon = Altim.meters2lonlat_distance(distance_meters, latitude_degrees)
(0.008997741566866717, 0.012718328120254203)
#```
#"""
function meters2lonlat_distance(distance_meters, latitude_degrees)
# Radius of the Earth in meters
earth_radius = 6371000
# Calculate the angular distance in radians
angular_distance = distance_meters / earth_radius
# Calculate the longitude distance using the Haversine formula
longitude_distance = angular_distance * (180.0 / π) / cosd(latitude_degrees)
latitude_distance = distance_meters / 111139
return latitude_distance, longitude_distance
end
# build an example raster
dX = 0.1
dY = -0.1
lon = X(Projected(166.:dX:168.; sampling=Intervals(Start()), order=ForwardOrdered(), span=Regular(dX), crs=EPSG(4326)))
lat = Y(Projected(-78.0:dY:-80.; sampling=Intervals(Start()), order=ForwardOrdered(), span=Regular(dY ), crs=EPSG(4326)))
ras = Raster(rand(lon, lat))
# given a lat/lon raster with small grid spacing caclculate area
dlon = dims(ras, :X)
dlat = dims(ras, :Y)
lonlat_per_meter = meters2lonlat_distance.(Ref(1), dlat)
dist_lon = step(dlon) ./ getindex.(lonlat_per_meter, 1)
dist_lat = step(dlat) ./ getindex.(lonlat_per_meter, 2)
area = ones(dlon) * DimArray(dist_lon .* dist_lat, dlat)' |
Let's wait for a complete Unitful extension to add the I'm happy to rename but we should |
given the incorrectness of |
Have you compared to the implementation in this PR? For me it is giving similar speeds. I can see the point of your implementation, but using the haversine formula also has downsides, since it doesn't account for the curvature of the earth. I know this isn't a big deal in most cases, but the error increases with the size of gridcells. So after (dis)aggregating a raster, the total area returned by cellarea would be different, which is not ideal. Maybe we should implement it for other projections than lon-lat, but then we might need to do some more geometry. |
Maybe we should already start returning the result in metres though, to avoid another breaking change down the line. If we add a units keyword later then it would default to m^2. |
Yeah result in metres is fine, just not the units kw |
Your implementation knocks the socks off of my proposal (2x faster) and is more accurate so ignore my recommendation. Excited to see this progressing... fast, useful and intuitive... couldn't ask for anything more |
Is this good to go? |
I think so! Can you or @asinghvi17 just nod at the logic in the line of code that reprojects to |
Happy to report that this solves #764 in web mercator as well! |
Integrate GeometryOpsCore manifold types into `cellarea`
This commit creates a new `reproject` method that uses Proj to transform an array of values in place using `proj_trans_generic`, only allocating a Float64 output array. It also performs the reproject check before actually transforming the array. This decreases runtime on my machine from 4.168 ms (ArchGDAL) to 665.187 μs (Proj), and allocations from 35167 allocs: 1.254 MiB (ArchGDAL) to 108 allocs: 42.859 KiB (Proj).
This is a weakness of this method compared to the old ArchGDAL method. Does this need a fix in Proj?
[WIP] switch cellarea and reproject to use Proj
Full changelog:
|
The test failures are unrelated and already fixed in #780. There is still room for improvement performance-wise but I think we should merge this now. We can make a different PR for further improvements. |
Co-authored-by: Rafael Schouten <[email protected]>
Thanks everyone! |
Woot woot ! Fantastic effort. |
Solves #764 and makes cellsize calculation much faster for lon-lat projections.
I'm considering getting rid of the ArchGDAL requirement for these projections as well.
Any ideas for further improvements @rafaqz @alex-s-gardner?