# How can I get Proj4 to transform multiple locations?

**URL:** <https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098>\
**Category:** Geo\
**Tags:** geodesy\
**Created:** [April 27, 2022, 1:32am UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098 "2022-04-27T01:32:57Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![chadagreene](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chadagreene/32/34924_2.png) [@chadagreene](https://discourse.julialang.org/u/chadagreene)\
**Post date:** [April 27, 2022, 1:32am UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/1 "2022-04-27T01:32:57Z")

</div>

This is probably more of a Julia question than a Proj4 question, but how can I perform coordinate transformations on multiple locations at once? I’m writing a function that would need to handle the following three cases:

### 1: A single location

The [Proj4.jl readme](https://github.com/JuliaGeo/Proj4.jl) provides clear guidance, and I’m able to get it working perfectly:

```julia
using Proj4

# Define the transformation: 
trans = Proj4.Transformation("EPSG:4326", "+proj=utm +zone=32 +datum=WGS84");

# Define a single location: 
lat = 55; 
lon = 12; 

# A single location works perfectly: 
x, y = trans([lat,lon]);
println(x)
println(y)
>691875.632137542
>6.098907825129169e6

```

Perfect. Above, we’ve transformed (55N,12E) into projected coordinates in meters. Great, now try something similar for:

### 2: Multiple arbitrary locations:

Following a similar method to what’s described above, I’d like to transform four arbitrary geographic locations into projected coordinates. So here for `lat` and `lon` I enter four values, and try adding a `.` in the call to `trans()`:

```julia
# Four locations:
lat = [54, 55, 56, 57];
lon = [11, 12, 13, 14];
x, y = trans.([lat, lon]);
println(x)
println(y)
>[3.3824660011659563e6, 7.011981052605791e6, 56.0, 57.0]
>[827871.392810812, 1.217618384382686e6, 13.0, 14.0]

```

Oh no! The location (55N,12E) no longer returns the same projected coordinate values as we got when we only entered it as a single location. And the last two points are just returning the same values we fed into `trans()`.

### 3: A grid of points

I can think of two ways I might transform a grid of points. One way might be to transpose the `lon` variable:

```julia
# Four equally-spaced points in each dimension to creates a grid:  
lat = [54, 55, 56, 57]; 
lon = [11, 12, 13, 14]; 

# Does transposing lon work? (Nope)
x, y = trans.([lat, lon']);
>[3.3824660011659563e6, 7.011981052605791e6, 56.0, 57.0]
>[827871.392810812, 1.217618384382686e6, 13.0, 14.0]

```

How about an array comprehension? Seems like this might be able to create a grid of transformed coordinates:

```julia
x, y = [trans([lati, loni]) for lati=lat, loni=lon]
print(x)
print(y)
> [631090.8762477529, 5.985372985435059e6][627928.1913765112, 6.096620706492608e6]

```

That’s only two locations!

So what’s going on here? How can I get `Proj4` to transform a single point, an arbitrary array of points, and a grid?

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [April 27, 2022, 5:15am UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/2 "2022-04-27T05:15:43Z")

</div>

```julia
julia> [trans([latᵢ, lonᵢ]) for (latᵢ, lonᵢ) ∈ zip(lat, lon)]
4-element Vector{StaticArrays.SVector{2, Float64}}:
 [631090.8762477529, 5.985372985435059e6]
 [691875.632137542, 6.098907825129169e6]
 [749395.3327601748, 6.21330158730825e6]
 [803582.3889876883, 6.328506458168089e6]

```

EDIT: Scratch that, I missed that your issue is the left hand side assignment rather than the construction of your comprehension!

---

<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:** [April 27, 2022, 7:47am UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/3 "2022-04-27T07:47:47Z")

</div>

For the grid case, your solution works, but you are only extracting two positions by assigning x and y.  
If you want to get a matrix for the x and y positions you can do:

```julia
julia> grid = [trans([lati, loni]) for lati=lat, loni=lon]
4×4 Matrix{StaticArrays.SVector{2, Float64}}:
 [6.31091e5, 5.98537e6] [6.96621e5, 5.98769e6] … [827619.0, 5.9951e6]
 [6.27928e5, 6.09662e6] [6.91876e5, 6.09891e6] [8.19704e5, 6.10623e6]
 [6.24726e5, 6.20788e6] [6.87071e5, 6.21014e6] [8.11691e5, 6.21737e6]
 [6.21486e5, 6.31916e6] [6.8221e5, 6.32139e6] [8.03582e5, 6.32851e6]
julia> first.(grid)
4×4 Matrix{Float64}:
 6.31091e5 6.96621e5 7.62132e5 827619.0
 6.27928e5 6.91876e5 755803.0 8.19704e5
 6.24726e5 6.87071e5 7.49395e5 8.11691e5
 6.21486e5 6.8221e5 7.42911e5 8.03582e5

julia> last.(grid)
4×4 Matrix{Float64}:
 5.98537e6 5.98769e6 5.99093e6 5.9951e6
 6.09662e6 6.09891e6 6.10211e6 6.10623e6
 6.20788e6 6.21014e6 6.2133e6 6.21737e6
 6.31916e6 6.32139e6 6.3245e6 6.32851e6

```

---

<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 27, 2022, 3:02pm UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/4 "2022-04-27T15:02:44Z")

</div>

You may consider also using GMT.jl

```julia
using GMT
lat = [54, 55, 56, 57]; lon = [11, 12, 13, 14];

lonlat2xy([lon[:] lat[:]], t_srs="+proj=utm +zone=32 +datum=WGS84")
4×2 Matrix{Float64}:
 6.31091e5 5.98537e6
 6.91876e5 6.09891e6
 7.49395e5 6.2133e6
 8.03582e5 6.32851e6

```

---

<div class="post-metadata">

**Author:** ![chadagreene](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chadagreene/32/34924_2.png) [@chadagreene](https://discourse.julialang.org/u/chadagreene)\
**Post date:** [April 27, 2022, 8:38pm UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/5 "2022-04-27T20:38:50Z")

</div>

@joa-quim I had not considered using GMT. Trying it out, however, I’m running into a this error:

```julia
using GMT
lat = [54, 55, 56, 57]; 
lon = [11, 12, 13, 14];

lonlat2xy([lon[:] lat[:]], t_srs="+proj=utm +zone=32 +datum=WGS84")
UndefVarError: lonlat2xy not defined

Stacktrace:
  [1] top-level scope
    @ ~/Documents/coursework/Untitled-1.ipynb:5
  [2] eval
    @ ./boot.jl:373 [inlined]
  [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:1196
  [4] #invokelatest#2
    @ ./essentials.jl:716 [inlined]
  [5] invokelatest
    @ ./essentials.jl:714 [inlined]
  [6] (::VSCodeServer.var"#164#165"{VSCodeServer.NotebookRunCellArguments, String})()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/serve_notebook.jl:19
  [7] withpath(f::VSCodeServer.var"#164#165"{VSCodeServer.NotebookRunCellArguments, String}, path::String)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/repl.jl:184
  [8] notebook_runcell_request(conn::VSCodeServer.JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::VSCodeServer.NotebookRunCellArguments)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/serve_notebook.jl:13
  [9] dispatch_msg(x::VSCodeServer.JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::VSCodeServer.JSONRPC.MsgDispatcher, msg::Dict{String, Any})
    @ VSCodeServer.JSONRPC ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/JSONRPC/src/typed.jl:67
 [10] serve_notebook(pipename::String, outputchannel_logger::Base.CoreLogging.SimpleLogger; crashreporting_pipename::String)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/serve_notebook.jl:136
 [11] top-level scope
    @ ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/notebook/notebook.jl:32
 [12] include(mod::Module, _path::String)
    @ Base ./Base.jl:418
 [13] exec_options(opts::Base.JLOptions)
    @ Base ./client.jl:292
 [14] _start()
    @ Base ./client.jl:495

```

Any idea what’s going on here? I’ve just updated all my packages.

---

<div class="post-metadata">

**Author:** ![anthonymobile](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anthonymobile/32/32341_2.png) [@anthonymobile](https://discourse.julialang.org/u/anthonymobile)\
**Post date:** [April 27, 2022, 8:54pm UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/6 "2022-04-27T20:54:18Z")

</div>

Did you install GMT itself as well or just GMT.jl wrapper? (It happens to us all)

---

<div class="post-metadata">

**Author:** ![chadagreene](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chadagreene/32/34924_2.png) [@chadagreene](https://discourse.julialang.org/u/chadagreene)\
**Post date:** [April 27, 2022, 10:10pm UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/7 "2022-04-27T22:10:11Z")

</div>

Doh! Didn’t know I needed to install GMT separately from GMT.jl. Thanks for the tip!

---

<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 27, 2022, 11:50pm UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/8 "2022-04-27T23:50:58Z")

</div>

No. Since a couple a couple of years GMT.jl automatically installs GMT via conda.  
When GMT is not installed there are previous error messages.

What does `GMTver` prints? Do the tests run? _e.g._ `] test GMT`

---

<div class="post-metadata">

**Author:** ![chadagreene](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chadagreene/32/34924_2.png) [@chadagreene](https://discourse.julialang.org/u/chadagreene)\
**Post date:** [April 27, 2022, 11:57pm UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/9 "2022-04-27T23:57:56Z")

</div>

Hmm. Here are the outputs from `] test GMT`:

```julia
(@v1.7) pkg> test GMT
     Testing GMT
      Status `/private/var/folders/3q/36tmwvtx50ldmv31f23wfz7w0000gq/T/jl_xVksQB/Project.toml`
  [8f4d0f93] Conda v1.7.0
  [5752ebe1] GMT v0.41.2
  [ade2ca70] Dates `@stdlib/Dates`
  [44cfe95a] Pkg `@stdlib/Pkg`
  [de0858da] Printf `@stdlib/Printf`
  [10745b16] Statistics `@stdlib/Statistics`
  [8dfed614] Test `@stdlib/Test`
      Status `/private/var/folders/3q/36tmwvtx50ldmv31f23wfz7w0000gq/T/jl_xVksQB/Manifest.toml`
  [8f4d0f93] Conda v1.7.0
  [5752ebe1] GMT v0.41.2
  [682c06a0] JSON v0.21.3
  [69de0a69] Parsers v2.3.1
  [81def892] VersionParsing v1.3.0
  [0dad84c5] ArgTools `@stdlib/ArgTools`
  [56f22d72] Artifacts `@stdlib/Artifacts`
  [2a0f44e3] Base64 `@stdlib/Base64`
  [ade2ca70] Dates `@stdlib/Dates`
  [f43a241f] Downloads `@stdlib/Downloads`
  [b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
  [b27032c2] LibCURL `@stdlib/LibCURL`
  [76f85450] LibGit2 `@stdlib/LibGit2`
  [8f399da3] Libdl `@stdlib/Libdl`
  [37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
  [56ddb016] Logging `@stdlib/Logging`
  [d6f4376e] Markdown `@stdlib/Markdown`
  [a63ad114] Mmap `@stdlib/Mmap`
  [ca575930] NetworkOptions `@stdlib/NetworkOptions`
  [44cfe95a] Pkg `@stdlib/Pkg`
  [de0858da] Printf `@stdlib/Printf`
  [3fa0cd96] REPL `@stdlib/REPL`
  [9a3f8284] Random `@stdlib/Random`
  [ea8e919c] SHA `@stdlib/SHA`
  [9e88b42a] Serialization `@stdlib/Serialization`
  [6462fe0b] Sockets `@stdlib/Sockets`
  [2f01184e] SparseArrays `@stdlib/SparseArrays`
  [10745b16] Statistics `@stdlib/Statistics`
  [fa267f1f] TOML `@stdlib/TOML`
  [a4e569a6] Tar `@stdlib/Tar`
  [8dfed614] Test `@stdlib/Test`
  [cf7118a7] UUIDs `@stdlib/UUIDs`
  [4ec0a83e] Unicode `@stdlib/Unicode`
  [e66e0078] CompilerSupportLibraries_jll `@stdlib/CompilerSupportLibraries_jll`
  [deac9b47] LibCURL_jll `@stdlib/LibCURL_jll`
  [29816b5a] LibSSH2_jll `@stdlib/LibSSH2_jll`
  [c8ffd9c3] MbedTLS_jll `@stdlib/MbedTLS_jll`
  [14a3606d] MozillaCACerts_jll `@stdlib/MozillaCACerts_jll`
  [4536629a] OpenBLAS_jll `@stdlib/OpenBLAS_jll`
  [83775a58] Zlib_jll `@stdlib/Zlib_jll`
  [8e850b90] libblastrampoline_jll `@stdlib/libblastrampoline_jll`
  [8e850ede] nghttp2_jll `@stdlib/nghttp2_jll`
  [3f19e933] p7zip_jll `@stdlib/p7zip_jll`
     Testing Running tests...
Test Summary: | Pass Total
GMT | 1 1
     Testing GMT tests passed 

```

---

<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 28, 2022, 12:09am UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/10 "2022-04-28T00:09:32Z")

</div>

So that happened in result of this command had errored

```julia
run(`gmt --version`)

```

Run it and you’ll see the true error message. Now the question is why. Did you have a previous GMT installation? On Linux some distros do not create a `libgmt.so` simlink and the GMT.jl detection code fails to detect GMT (solution is to manually create that simlink). But, again, when no GMT is detected conda should step in and install one for you.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [April 28, 2022, 2:16pm UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/11 "2022-04-28T14:16:31Z")

</div>

You can load the input data as a lat-lon matrix and broadcast over its rows:

```julia
latlon_matrix = [lat lon]
trans.(eachrow(latlon_matrix))

```

Or load the input data as a lat-lon vector of vectors and broadcast over its elements:

```julia
latlon = [[x, y] for (x,y) in zip(lat,lon)]
trans.(latlon)

```

---

<div class="post-metadata">

**Author:** ![anthonymobile](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anthonymobile/32/32341_2.png) [@anthonymobile](https://discourse.julialang.org/u/anthonymobile)\
**Post date:** [April 29, 2022, 12:32am UTC](https://discourse.julialang.org/t/how-can-i-get-proj4-to-transform-multiple-locations/80098/12 "2022-04-29T00:32:20Z")

</div>

sorry for the bad advice!
