-
Notifications
You must be signed in to change notification settings - Fork 25
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
plotting across the 180th meridian #126
Comments
Looking closer at the source code, and the using GLMakie, GeoMakie
fig = Figure()
lonlims = (-40, 40)
ga = GeoAxis(fig[1,1],
# coastlines = true,
dest = "+proj=eqc",
lonlims=lonlims,
# latlims = (-40, 40),
title="lonlims = $lonlims",
)
# image!(ga, -180..180, -90..90, rotr90(GeoMakie.earth()); interpolate = false)
image!(ga, -180..180, -90..90, circshift(rotr90(GeoMakie.earth()), (360, 0)); interpolate = false)
## Code adjusted from `GeoAxis` construction:
coast_line = Makie.convert_arguments(PointBased(), GeoMakie.coastlines())[1]
coastline_attributes = (;)
coastplot = lines!(ga, coast_line; color = :black, coastline_attributes...)
translate!(coastplot, -200, 0, 99) # left half of coastlines (0, 180)
coastplot = lines!(ga, coast_line; color = :black, coastline_attributes...)
translate!(coastplot, 200, 0, 99) # right half of coastlines (-180, 0)
fig It's also unclear to me why |
It appears to me you didn't create that plot with julia> using GeoMakie, GLMakie
julia> fig = Figure()
julia> ga = GeoAxis(fig[1, 1];
lonlims=(-360, 0), coastlines = false, # setting lonlims range >360 doesnt work at all, btw. Here I try to "shift" the view to be centered on the 180th meridian (experience so far by adjusting the `dest` projection has been futile...
dest = "+proj=eqc",
)
julia> e1 = rotr90(GeoMakie.earth());
julia> img = image!(-540..180, -90..90, [e1; e1]; interpolate = false) # duplicate earth view "left"
Image{Tuple{Vector{Float32}, Vector{Float32}, Matrix{RGB{Float32}}}}
julia> xlims!(ga, -240, -140) |
In principle, I think something similar could be done with (the split function is from #128) "Translate the coastline, which is just translating each element of the coastline array"
function translate_coastline(coastline::Vector{<:LineString}, offset::Real)
translate_coastline_element.(coastline, offset)
end
"Translate a single element of the coastline, i.e. a LineString"
function translate_coastline_element(celem::LineString, offset::Real = -360.0)
translated_coords = coordinates(celem) .+ Point(offset, 0)
return LineString(translated_coords)
end
getlon(p::Point) = p[1]
"Split a coastline element if it crosses lon0 (thanks to gaelforget for initial work, see #128 for details"
function split_direct(tmp::LineString,lon0=-160.0)::Vector{<:LineString}
linenodes = coordinates(tmp) # get coordinates of line nodes
# Find nodes that are on either side of lon0
cond = getlon.(linenodes) .>= lon0
# Find interval starts and ends
end_cond = diff(cond) # nonzero values denote ends of intervals
end_inds = findall(!=(0), end_cond)
start_inds = [firstindex(linenodes); end_inds .+ 1] # starts of intervals
end_inds = [end_inds; lastindex(linenodes)] # ends of intervals
# do the splitting
split_coords = view.(Ref(linenodes), UnitRange.(start_inds, end_inds)) # For each start-end pair, get those coords
# reconstruct lines from points
split_lines = LineString.(split_coords)
return split_lines
end
"Split the entire coastline, which is just a vector of LineStrings. Return a vector of LineStrings"
function split_direct(ls_vec::Vector{<:LineString},lon0=-160.0)::Vector{<:LineString}
vcat(split_direct.(ls_vec, lon0)...)
end As an example, here I translate the coastlines by -180 degrees: (see geoaxis.jl:123 for reference code): julia> using GeoMakie, GLMakie
julia> fig = Figure()
julia> ga = GeoAxis(fig[1, 1];
coastlines = false, # plot coastlines manually
dest = "+proj=eqc",
)
julia> coast_line = GeoMakie.coastlines();
julia> trans_cl = translate_coastline(coast_line, -180);
julia> left_cl = split_direct(trans_cl, -180); # split along 180th meridian since we are still in (-180, 180) view.
julia> coastplot = lines!(ga, left_cl; color = :black) With this, one can in principle do julia> coast_line = GeoMakie.coastlines();
julia> trans_cl = translate_coastline(coast_line, -360);
julia> combined_coastline = [trans_cl; coast_line];
julia> coastplot = lines!(ga, combined_coastline; color = :black) However, since |
FWIW, maybe there is some useful code at uxarray? They seem to have the tooling to "split" those cells that cross the wrapping longitude. See, e.g., these plots from their docs: (also relevant to MakieOrg/Makie.jl#742) |
Huh, thanks for the link! Will check it out. |
Hi,
I'm having some issues understanding how to plot a localized plot in the range, say, 160E to 160W, i.e. across the 180th meridian. Ideally, I'd like to be able to set a limit like
lonlims=(160, -160)
and letGeoMakie
interpret that instruction correctly.I've made a test script testing various approaches:
I see this post may be related to #122, but the code is a bit convoluted and hard to reproduce.
Inspired by #118, I tried experimenting with
+lon_0=
-180, or 180, but thenGeoMakie.earth()
disappeared entirely, and/or coastlines produced weird horizontal lines. It also appears it's advised against anyways (#7 (comment))The text was updated successfully, but these errors were encountered: