# Reprojecting maps

**URL:** https://discourse.julialang.org/t/reprojecting-maps/97101
**Category:** Geo
**Created:** [April 5, 2023, 8:16am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101 "2023-04-05T08:16:33Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)
#### Post date: [April 5, 2023, 8:16am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/1 "2023-04-05T08:16:33Z")

</div>

Dear community,  
does anyone have a recipe/example of how to reproject a map, e.g. from lat/lon to Robinson (for my use case just global is enough)? Please note I do not just want to plot (cf. GeoMakie), but get a Raster or matrix back.

Essentially in the MWE below I would like to avoid `using RCall`:

```julia
using GLMakie
using RCall
using Rasters
import Downloads, Shapefile
@rlibrary terra

function countryRaster(; res=0.5)
    shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
    shapefile_name = "country_borders.shp"
    isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
    countries = Shapefile.Handle(shapefile_name).shapes
    world = Rasters.rasterize(countries; to = Extents.Extent(X = (-180, 180), Y = (-90, 90)), res=res, missingval=0, fill=1, shape=:line)
    return world.data.data
end

function proj(grid, outcrs="+proj=robin +datum=WGS84")# +units=m +no_defs")
    #grid = permutedims(grid, (2,1))
    jras = R"""
        terra::rast($(permutedims(grid, (2,1))), crs = "+proj=longlat +datum=WGS84 +no_defs", extent=ext(rast())) %>% terra::project($outcrs) %>% as.matrix(wide=T) 
    """ |> rcopy
    return permutedims(jras, (2,1))
end

heatmap(countryRaster() |> proj)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/7/a76843f74bef1a5bd3748c0e07785fe992fad82c.jpeg)

Thanks!

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [April 5, 2023, 9:05am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/2 "2023-04-05T09:05:01Z")

</div>

See GMT.jl

---

<div class="post-metadata">

### Author: ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)
#### Post date: [April 5, 2023, 9:12am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/3 "2023-04-05T09:12:49Z")

</div>

Thanks! Could you provide an example? From the docs I see mainly the plotting. Thanks in advance!

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [April 5, 2023, 10:31am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/4 "2023-04-05T10:31:16Z")

</div>

`Rasters.reproject` is the function in Rasters.jl, apologies I dont have time to write an example right now.

But have you tried that? The docs should specify the arguments you need.

---

<div class="post-metadata">

### Author: ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)
#### Post date: [April 5, 2023, 10:55am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/5 "2023-04-05T10:55:51Z")

</div>

Thanks, no had only tried Rasters.resample, but I could not get it to work.

Rasters.reproject gives this

```julia
julia> Rasters.reproject(ProjString("+proj=robin +datum=WGS84"), ras)
ERROR: StackOverflowError:
Stacktrace:
 [1] reproject(source::Nothing, target::ProjString, dim::X{Colon}, vals::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}) (repeats 79984 times)
   @ Rasters C:\Users\<username>\.julia\packages\Rasters\wUuLU\src\methods\reproject.jl:54

```

where `ras` was the return of `world` from the `countryRaster` function above.

Any idea?  
Thanks,  
Markus

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [April 5, 2023, 12:12pm UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/6 "2023-04-05T12:12:22Z")

</div>

Arrg sorry i was away from a computer `resample` is what you want:

```julia
res = 0.5
shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
shapefile_name = "country_borders.shp"
isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
countries = Shapefile.Handle(shapefile_name).shapes
world = Rasters.rasterize(countries; to = Extents.Extent(X = (-180, 180), Y = (-90, 90)), res, missingval=0, fill=1, shape=:line)
crs = ProjString("+proj=robin +datum=WGS84")
wsg84_world = resample(world, res; crs)
Makie.heatmap(wsg84_world)

```

 ![world](https://global.discourse-cdn.com/julialang/original/3X/9/d/9d99e229b0dfb4ccab3ca1d0d4c5c8198e011880.png)

I do want to make the syntax a little easier to understand for resample.

In future it will be better to use ArchGDAL.jl or Proj.jl to reproject the shapefile instead of resampling the raster, but my 2 PRs to make both of those things work on any geometries (like Shapefile.jl objects) are not quite finished.

---

<div class="post-metadata">

### Author: ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)
#### Post date: [April 5, 2023, 12:41pm UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/7 "2023-04-05T12:41:44Z")

</div>

Thanks, yes in the real example I have a raster in the first place. Just used the county borders as a transparent MWE.

Unfortunately, I cannot reproduce, but get the error (Trace cut at [6]). Also I note that your output does not seem to be reprojected to Robinson.

```julia
julia> wsg84_world = Rasters.resample(world, reso; crs)
ERROR: BoundsError: attempt to access 0-element Vector{String} at index [1]
Stacktrace:
  [1] getindex
    @ .\array.jl:924 [inlined]
  [2] first
    @ .\abstractarray.jl:404 [inlined]
  [3] metadata(::ArchGDAL.RasterDataset{Int64, ArchGDAL.Dataset})
    @ Rasters C:\Users\mreichstein\.julia\packages\Rasters\wUuLU\src\sources\gdal.jl:231
  [4] dims(raster::ArchGDAL.RasterDataset{Int64, ArchGDAL.Dataset}, crs::Nothing, mappedcrs::Nothing)
    @ Rasters C:\Users\mreichstein\.julia\packages\Rasters\wUuLU\src\sources\gdal.jl:157
  [5] dims
    @ C:\Users\mreichstein\.julia\packages\Rasters\wUuLU\src\sources\gdal.jl:142 [inlined]
  [6] copyto!(dest::ArchGDAL.RasterDataset{Int64, ArchGDAL.Dataset}, bc::Base.Broadcast.Broadcasted{DimensionalData.DimensionalStyle{Base.Broadcast.DefaultArrayStyle{2}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(identity), Tuple{Raster{Int64, 2, Tuple{X{Projected{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, DimensionalData.Dimensions.LookupArrays.ForwardOrdered, DimensionalData.Dimensions.LookupArrays.Regular{Float64}, 
DimensionalData.Dimensions.LookupArrays.Intervals{DimensionalData.Dimensions.LookupArrays.Start}, DimensionalData.Dimensions.LookupArrays.NoMetadata, Nothing, Nothing, X{Colon}}}, Y{Projected{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, DimensionalData.Dimensions.LookupArrays.ForwardOrdered, DimensionalData.Dimensions.LookupArrays.Regular{Float64}, DimensionalData.Dimensions.LookupArrays.Intervals{DimensionalData.Dimensions.LookupArrays.Start}, DimensionalData.Dimensions.LookupArrays.NoMetadata, Nothing, Nothing, Y{Colon}}}}, Tuple{}, Matrix{Int64}, Nothing, DimensionalData.Dimensions.LookupArrays.NoMetadata, Int64}}})
    @ DimensionalData C:\Users\mreichstein\.julia\packages\DimensionalData\1wSpb\src\array\broadcast.jl:48

```

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [April 5, 2023, 1:36pm UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/8 "2023-04-05T13:36:45Z")

</div>

Sorry I’m not at the computer. But maybe the example in the front page of the GMT.jl site

```julia
coast(region=:global, proj=:Winkel, frame=:g, area=10000,
      land=:burlywood4, water=:wheat1, show=true)

```

![image](https://global.discourse-cdn.com/julialang/original/3X/b/a/babc168745b6bc905a3f29174eab72f9c4989c9e.png)

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [April 5, 2023, 2:40pm UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/9 "2023-04-05T14:40:58Z")

</div>

Yeah, it looks like there may be a bug in `resample` somewhere, but we may also be on different versions of some other package for you to get that error.

Can you make a Github issue? That’s usually the best thing to do when you get an error with Rasters.jl.

I’ll be away for a few days but having the issue there means I will get to it at some point after that.

---

<div class="post-metadata">

### Author: ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)
#### Post date: [September 18, 2024, 5:28pm UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/10 "2024-09-18T17:28:56Z")

</div>

FWIW, with some additional lines/tweaks, this is working now:

```julia
res = 0.5
shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
shapefile_name = "country_borders.shp"
isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
countries = Shapefile.Handle(shapefile_name).shapes
world = Rasters.rasterize(last, countries; to = Extents.Extent(X = (-180, 180), Y = (-90, 90)), res, missingval=0, fill=1, shape=:line)
world=setcrs(world, "+proj=longlat")
bounds = X(-180 .. 180), Y(-89.999 .. 89.999)
world2=crop(world; to=world[bounds...])
crs = ProjString("+proj=robin")
robin_world = resample(world2, 25000; crs, method=:near) # Define output resolution in new coord system (here 25000 m)
# Alternative:
#robin_world = resample(world2; crs, method=:near, size=(1440, 720)) # or define output size
heatmap(robin_world)

```

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [February 10, 2025, 5:54am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/11 "2025-02-10T05:54:45Z")

</div>

Thanks @mreichMPI-BGC for the code! However, I tried to use your code but it did not work for me (I posted [an issue](https://github.com/MakieOrg/Makie.jl/issues/4771) on GitHub). Do you happen to have an up-to-date MWE by any chance? If yes, would you mind posting it to the GitHub issue and/or here?

---

<div class="post-metadata">

### Author: ![Fliks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fliks/32/2494_2.png) [@Fliks](https://discourse.julialang.org/u/Fliks)
#### Post date: [February 10, 2025, 6:23am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/12 "2025-02-10T06:23:29Z")

</div>

@briochemc did you really meant to link to this issue? That seems to be unrelated to this topic and in the issue you link back to a different discourse thread.

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [February 10, 2025, 8:03am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/13 "2025-02-10T08:03:27Z")

</div>

Oops yes I posted in the wrong place!

---

<div class="post-metadata">

### Author: ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)
#### Post date: [February 10, 2025, 8:30am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/14 "2025-02-10T08:30:02Z")

</div>

@briochemc Are we talking about the Taylor plots? Sorry, I have been inactive lately and have no news. I’d also like to see a Makie recipe ;-).

Maybe @lazarusA can comment? At that time we discussed the whole thing a bit.

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [February 10, 2025, 8:47am UTC](https://discourse.julialang.org/t/reprojecting-maps/97101/15 "2025-02-10T08:47:57Z")

</div>

Yes! Sorry I’ll try to move the post when on a computer…

* * *

EDIT: Actually I’m not sure how to do that. Should i copy paste my reply to the correct thread? I don’t want to mess more things up!
