2

I want to draw a map with TikZ and as a starter this map should be in Lambert Conformal Conical projection. However to make it convenient, I would like to include some geodesic calculations, so that it is easy and transparent for the user, what he is doing, without using an external tool for the conversion and calculation. I did this in the past, this works well, but I want to take it to the next level and look for your input.

A possible input code with explanations in the comments could look like this:

\begin{tikz}
\begin{projection}[type=Lambert conformal conic,stdlat1=2,stdlat2=-2,lon0=0,k=1]

\coordinate(point1) at (1.0,0.5); %1 degree North, 0.5 degree East
\coordinate(point2) at (-1.0,-0.5); %1 degree South, 0.5 degree West

\draw (point1) -- ++ (relative cs:100m,50m); %draw line from point1 to a coordinate 100 meters (in reality) to the east and 50 meters (in reality) to the north relative of point1
\draw (point1) -- (point2); %draw line from point1 to point2 (can be straight, does not have to be a geodesic)
\draw ($(point2) + (relative cs: 45:2nm)$) -- (point1); %draw a line from a point on a 45 degree bearing with a distance of 2 nautical miles from point1 to point2
\draw (point1) arc (relative cs: 60:90:3nm); %draw a circle segment from point1 with starting heading of 060 and end heading of 090 with a 3 nautical mile radius

\end{projection}
\end{tikz}

The nomenclature for the input parameters is taken from the GeodesicLib.

Any ideas, even starting points are highly appreciated, as I couldn't even find something close to this. Possible implementations with LuaTeX or similar are welcome!

TobiBS
  • 5,240
  • Since you are asking for ideas: nonlinear transformations. The so-called \polartransformation of the pgfmanual on p. 1147 comes already somewhat close. –  Dec 04 '19 at 21:19
  • There was once a very similar question, and an answer that worked and did precisely that. Well, the question got closed, and the answer got deleted. (Apparently even many upvotes do not prevent an answer from being deleted... it would be great if the answers could stay preserved, then one would not have to repeat these things....) –  Dec 04 '19 at 21:23
  • That’s too bad, I always thought the whole purpose of Stackexchange is to maintain the good answers. Was the answer deleted by an admin or by an upset user? And why was the question closed, too generic? – TobiBS Dec 04 '19 at 21:38
  • I do not remember any of details, I just know that there was a conformal map implemented via a nonlinear transformation. (This is a recent example of a deleted answer which has a score of 6, but got deleted because the question was not appreciated. You probably cannot see it yet because there is the reputation thingy.) I never understood why one wants to delete an answer even if the question is not optimal.... –  Dec 04 '19 at 21:42
  • 1
    No I didn’t try that, yet. And no I didn’t expect that from the possible answer authors. I just wanted to give one practical example of what I want, theoretically I am looking for a way to just implement my own coordinate interpretation into LaTeX, that works with all possible map projections. This might be multiple questions, starting with: How can I change the interpretation of angles, then how can I introduce new coordinate systems, then how can coordinate systems relative to the coordinate I am currently at, and so on. This is why I mentioned LuaTeX, because then maybe one can reuse A lib. – TobiBS Dec 05 '19 at 03:48
  • There are separate issues one may want to disentangle. You can declare your own coordinate system with \tikzdeclarecoordinatesystem, see the example on p. 140 in pgfmanual v3.1.4. However, if you draw a line in this new coordinate system, it will still be a line. Nonlinear transformations also transform the path. However, they are tricky, e.g. not translation invariant. Finally, one can do a projection by installing a view and then using e.g. the 3d library. Do you have a simple/explicit transformation that one can use to illustrate some of this? –  Dec 05 '19 at 03:58
  • An explicit example is https://tex.stackexchange.com/a/513092. –  Dec 05 '19 at 04:00

1 Answers1

3

Thank you @Schrödinger's cat for your great inputs in the comments. By applying them I was able to come up with a basic structure for what I needed. You can see how I employed this into a working example that plots 4 cities in the USA, the state of Arizona and a grid: enter image description here The code for this (without the boundaries of Arizona, because that makes the file to big), looks like this:

\documentclass{article}
\usepackage[a4paper, landscape, margin=0cm]{geometry}

\usepackage{tikz} \usetikzlibrary{calc}

\begin{document} Arizona in Lambert Conical projection and the airports PHX, AUS, DTW and JFK

\directlua{lambert = require("lambert")}

\newcommand\addLUADEDplot[8]{% \directlua{lambert.LambertConicalForward(#1,#2,#3,#4,#5,#6,#7,#8)}% }

\newenvironment{ellipsoid}[1][a=6378137,f=0.0033528106647475]{
\setkeys{ellipsoid}{#1}}

\newenvironment{lambertconical}[1][stdlat1=33,stdlat2=45,lon0=-112,k=1]{\setkeys{lambertconicalkeys}{#1}}

\makeatletter
\define@key{latlonkeys}{lat}{\def\mylat{#1}}
\define@key{latlonkeys}{lon}{\def\mylon{#1}}
\define@key{ellipsoid}{a}{\def\ellipsoidA{#1}}
\define@key{ellipsoid}{f}{\def\ellipsoidF{#1}}
\define@key{lambertconicalkeys}{stdlat1}{\def\lambertconicalStdLatONE{#1}}
\define@key{lambertconicalkeys}{stdlat2}{\def\lambertconicalStdLatTWO{#1}}
\define@key{lambertconicalkeys}{lon0}{\def\lambertconicalLonZERO{#1}}
\define@key{lambertconicalkeys}{k}{\def\lambertconicalK{#1}}
\makeatother
\tikzdeclarecoordinatesystem{latlon}%
{%
    \setkeys{latlonkeys}{#1}%
    \addLUADEDplot{\ellipsoidA}{\ellipsoidF}{\lambertconicalStdLatONE}{\lambertconicalStdLatTWO}{\lambertconicalK}{\lambertconicalLonZERO}{\mylat}{\mylon}%
}

\begin{tikzpicture}[scale=0.45]
\begin{ellipsoid}[a=6378137,f=0.0033528106647475]
\begin{lambertconical}[stdlat1=33,stdlat2=45,lon0=-112,k=0.00001]
    %\draw [->] (0,0,0) -- (0,0,350);
    \node at (latlon cs:lat=33.434167,lon=-112.011667){PHX};
    \node at (latlon cs:lat=30.194444,lon=-97.67){AUS};
    \node at (latlon cs:lat=42.2125,lon=-83.353333){DTW};
    \node at (latlon cs:lat=40.639722,lon=-73.778889){JFK};

    \foreach \lon in {-124,-123, ..., -66}
    {
        \foreach \lat in {25,26, ..., 49}
        {
            \draw (latlon cs:lat=\lat,lon=\lon) -- (latlon cs:lat=\lat,lon={\lon+1});
            \draw (latlon cs:lat=\lat,lon=\lon) -- (latlon cs:lat={\lat+1},lon=\lon);
        }
    }

\end{lambertconical}
\end{ellipsoid}
\end{tikzpicture}

\end{document}

The Lua implementation of the Lambert Conformal conic (for a sphere only, complications will follow), looks like that:

local function print_LambertConformalConicForward(a,f,stdlat1,stdlat2,k1,lon0,lat,lon)
lat0 = 40;
n = math.log(math.cos(math.rad(stdlat1))/math.cos(math.rad(stdlat2))) / math.log( math.tan((math.pi/4)+math.rad(stdlat2/2)) / math.tan((math.pi/4)+math.rad(stdlat1/2)))
F = (math.cos(math.rad(stdlat1)) * math.pow(math.tan((math.pi/4)+math.rad(stdlat1/2)), n)) / n
rho = (a * F) / math.pow(math.tan((math.pi/4)+(math.rad(lat)/2)), n)
rho_0 = (a * F) / math.pow(math.tan((math.pi/4)+(math.rad(lat0)/2)), n)
theta = n * (math.rad(lon-lon0))

x = (rho * math.sin(theta)) * k1 y = (rho_0 - (rho * math.cos(theta))) * k1

tex.sprint("\pgfpointxyz{"..x.."}{"..y.."}{0}%") end

return { LambertConicalForward = print_LambertConformalConicForward }


EDIT on 2021-12-10: I am working on another map and it seems I was not the only one looking for drawing maps with TikZ. Now there is a package for this purpose built on map tiles, but it can also be used without a basic map: mercatormap can be found at https://ctan.org/pkg/mercatormap

TobiBS
  • 5,240