diff options
author | Karl Berry <karl@freefriends.org> | 2020-04-20 21:10:20 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-04-20 21:10:20 +0000 |
commit | 36db81e567665da0b8e92831b69d2a71971312f3 (patch) | |
tree | c543aa6948c99b1ecb316c4386ee34dfeed4d384 /Master | |
parent | c01e3cc67bce910fad535c50c41da044fc23e882 (diff) |
mercatormap (20apr20)
git-svn-id: svn://tug.org/texlive/trunk@54812 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
24 files changed, 7413 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/mercatormap/README b/Master/texmf-dist/doc/latex/mercatormap/README new file mode 100644 index 00000000000..eb1212c1aca --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/README @@ -0,0 +1,43 @@ +%% The LaTeX package mercatormap - version 1.00 (2020/04/20) +%% +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2020 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de> +%% ------------------------------------------------------------------------------------------- +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This work consists of all files listed in README +%% + +The package ... + +Contents of the package +======================= + 'README' this file + 'mercatormap.sty' LaTeX package file (style file) + 'mercatorsupplier.def' LaTeX package file (include file for style) + 'mercatorpy.def' LaTeX package file (Python generator) + 'mercatormap.pdf' Documentation + 'mercatormap.tex' Source code of the documentation (main file) + '*.doc.*' Source code of the documentation (include files) + 'mercatormap-example.tex' Source code of an example + 'mercatormap.bib' Bibliography of the documentation + +Installation +============ +Copy the contents of the 'mercatormap.tds.zip' from CTAN to your local TeX file tree. + +Alternatively, put the files to their respective locations within the TeX installation: + 'mercatormap.sty' -> /tex/latex/mercatormap + 'mercatorpy.def' -> /tex/latex/mercatormap + 'mercatorsupplier.def' -> /tex/latex/mercatormap + + all other files -> /doc/latex/mercatormap diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap-example.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap-example.tex new file mode 100644 index 00000000000..196906fc852 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap-example.tex @@ -0,0 +1,91 @@ +% \LaTeX-Main\ +% !TeX encoding=UTF-8 +%% +%% The LaTeX package mercatormap - version 1.00 (2020/04/20) +%% mercatormap-example.tex: Example document with a map +%% +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2020 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de> +%% ------------------------------------------------------------------------------------------- +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This work consists of all files listed in README +%% +% arara: pdflatex: { shell: yes } +% +\def\mrcpkgprefix{} +\documentclass{article} + +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage[bookmarks,raiselinks,pageanchor,colorlinks]{hyperref} +\usepackage[a4paper,margin=15mm,noheadfoot]{geometry} +\usepackage{mercatormap} + +\pagestyle{empty} + +\mrcactivatescript% activates Python script + +\begin{document} + +\vspace*{\fill} +\noindent +\begin{tikzpicture} + \mrcNPdef{bbox-SW}{47.270111}{8.976350} + \mrcNPdef{bbox-NE}{50.564714}{13.839637} + \mrcmap + [ + area = {bbox-SW, bbox-NE}, + area to reference, + type = reference, + flex reference scale = 2000000, + tex width = \linewidth, + tex height = 22cm, + source = topplusopen web, + ]{mercatormap-example} + \mrcdrawmap + \mrcdrawnetwork + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + + \draw[thick] (mrcmap.south west) rectangle (mrcmap.north east); + + \mermapsetmarker{type=drop, draw=red, fill=red!20!white, + font=\sffamily\bfseries} + \mrcmarker{position=48.137222:11.575556, contents={M}} + \mrcmarker{position=48.537222:12.152222, contents={LA}} + \mrcmarker{position=49.017222:12.096944, contents={R}} + \mrcmarker{position=48.371667:10.898333, contents={A}} + \mrcmarker{position=49.300833:10.571667, contents={AN}} + \mrcmarker{position=49.948056:11.578333, contents={BT}} + \mrcmarker{position=49.948056:11.578333, contents={BT}} + \mrcmarker{position=49.794444:9.929444, contents={W\"U}} + + \node[below left=2mm,align=center,fill=white,draw=black,fill opacity=0.9, + text opacity=1,inner sep=2mm] at (mrcmap.north east) + { + \textbf{\Large Bayern}\\[1mm] + \mrcprettymapscale\\[1mm] + \begin{tikzpicture} + \mrcdrawscalebar[width-in-km=100] + \path[every node/.style={above,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.north west) -- (mrcscalebar.north east) + node[pos=0]{0} node[pos=0.2]{20} node[pos=0.4]{40} node[pos=0.6]{60} + node[pos=0.8]{80} node[pos=1]{100} node[pos=1,right,yshift=-1mm]{km}; + \end{tikzpicture} + }; + +\end{tikzpicture} +\vspace*{\fill} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.bib b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.bib new file mode 100644 index 00000000000..ef2e9b62131 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.bib @@ -0,0 +1,48 @@ +% Encoding: UTF-8 +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) + +@Report{Sturm:2020, + author = {Thomas F. Sturm}, + title = {Some Principles of Web Mercator Maps and their Computation}, + type = {Monograph}, + institution = {Universit\"{a}t der Bundeswehr M\"{u}nchen}, + date = {2020-03-05}, + language = {english}, + location = {Neubiberg}, + pagetotal = {44}, + doi = {10.18726/2020_3}, +} + + +@manual{package:tikz, + author = {Till Tantau}, + title = {The TikZ and PGF Packages}, + subtitle = {Manual for version 3.1.5b}, + url = {http://mirrors.ctan.org/graphics/pgf/base/doc/pgfmanual.pdf}, + date = {2020-01-08}, +} + + +@manual{package:xparse, + author = {{The \LaTeX3 Project}}, + title = {The xparse package}, + subtitle = {Document command parser}, + url = {http://mirrors.ctan.org/macros/latex/contrib/l3packages/xparse.pdf}, + date = {2020-03-06}, +} + + +@manual{package:siunitx, + author = {Joseph Wright}, + title = {siunitx -- A comprehensive (SI) units package}, + url = {http://mirrors.ctan.org/macros/latex/contrib/siunitx/siunitx.pdf}, + date = {2020-02-25}, +} + + +@manual{package:expl3, + author = {{The \LaTeX3 Project}}, + title = {The expl3 package and \LaTeX3 programming}, + url = {http://mirrors.ctan.org/macros/latex/contrib/l3kernel/expl3.pdf}, + date = {2020-04-06}, +} diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.abstract.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.abstract.tex new file mode 100644 index 00000000000..0013fd5ff90 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.abstract.tex @@ -0,0 +1,106 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) + +\thispagestyle{empty} +\begin{tcboutputlisting} +\begin{tcolorbox}[spread,blankest] +\mermapset{flex tile size=40mm} +\begin{tikzpicture} +\mrcmap[type=areafit,west=5,east=15,south=46,north=54, + source = opentopomap, + flex area scale=4 000 000, + tex width=\tcbtextwidth, + tex height=\tcbtextheight, + ]{title} +\mrcclipmap +\ExplSyntaxOn +\sys_gset_rand_seed:n {15} +\int_set:Nn \l_tmpa_int {1} +\int_until_do:nNnn \l_tmpa_int > {77} + { + \fp_set:Nn \l_tmpa_fp {\tcbtextwidth/2 + + \l_tmpa_int*2.5mm*cosd(18*\l_tmpa_int)} + \fp_set:Nn \l_tmpb_fp {\tcbtextheight/2 + + \l_tmpa_int*2.5mm*sind(18*\l_tmpa_int)} + \node[inner~sep=0pt,draw=blue!50!gray,line~width=1mm, + at={(\fp_to_dim:N\l_tmpa_fp,\fp_to_dim:N\l_tmpb_fp)}, + rotate=\fp_eval:n{18*\l_tmpa_int+10*rand()} ] + {\includegraphics[width=55mm,height=55mm] + {tiles/opentopomap_ + \int_use:N \l__mermap_tile_zoom_int _ + \fp_eval:n { randint(\l__mermap_tile_xmin_int,\l__mermap_tile_xmax_int) }_ + \fp_eval:n { randint(\l__mermap_tile_ymin_int,\l__mermap_tile_ymax_int) }.png + } + }; + \int_incr:N\l_tmpa_int + } +\ExplSyntaxOff +\node[font=\small\footnotesize,fill=white,opacity=0.75,text opacity=1] + at (\tcbtextwidth/2,1cm) {\mrcmapattribution}; +\node at (\tcbtextwidth/2,\tcbtextheight*0.667) + {\begin{tcolorbox}[ + center upper, fontupper=\bfseries,boxsep=15mm, boxrule=4mm, + sharp corners, oversize=5mm, + colback=white, colframe=blue!50!gray, + enhanced jigsaw, opacityback=0.8, opacityframe=0.9 ] + {\Huge The mercatormap package\par} + \vspace{1cm} + Manual for version \version\ (\datum)\par + \vspace{5mm} + Thomas F.~Sturm + \end{tcolorbox}}; +\end{tikzpicture} +\end{tcolorbox} +\end{tcboutputlisting} +\tcbuselistingtext +\tcbinputlisting{docexample, + listing options={style=mydocumentation,basicstyle=\ttfamily\scriptsize}, + listing only, + title=Cover code} + + +\clearpage +\begin{center} +\begin{tcolorbox}[enhanced,hbox,tikznode,left=8mm,right=8mm,boxrule=0.4pt, + colback=white,colframe=Blue_Gray, + drop lifted shadow=Blue_Gray!50,arc is angular, + before=\par\vspace*{5mm},after=\par\bigskip] +{\bfseries\LARGE The mercatormap package}\\[3mm] +{\large Manual for version \version\ (\datum)} +\end{tcolorbox} +{\large Thomas F.~Sturm% + \footnote{Prof.~Dr.~Dr.~Thomas F.~Sturm, Institut f\"{u}r Mathematik und Informatik, + Universit\"{a}t der Bundeswehr M\"{u}nchen, D-85577 Neubiberg, Germany; + email: \href{mailto:thomas.sturm@unibw.de}{thomas.sturm@unibw.de}}\par\medskip +\normalsize\url{http://www.ctan.org/pkg/mercatormap}\par +\url{https://github.com/T-F-S/mercatormap} +} +\end{center} +\bigskip +\begin{absquote} + \begin{center}\bfseries Abstract\end{center} + The \texttt{mercatormap} package extends \tikzname\ with tools to + create map graphics. The provided coordinate system relies on the + Web Mercator projection used on the Web by OpenStreetMap and others. + The package supports the seamless integration of graphics + from public map tile servers by a Python script. Also, common map + elements like markers, geodetic networks, bar scales, routes, orthodrome + pieces, and more are part of the package. +\end{absquote} + +\begin{tcolorbox}[breakable,enhanced jigsaw,before=\par\bigskip\noindent, + title={Contents},fonttitle=\bfseries\Large,center title, + colback=Blue_Gray!2!white, + colframe=Blue_Gray, + colbacktitle=Blue_Gray!5!white, + coltitle=black, + boxrule=0.4pt,arc is angular, + enlargepage flexible=\baselineskip,pad at break*=3mm, + %drop fuzzy shadow + ] +\makeatletter +\@starttoc{toc} +\makeatother +\end{tcolorbox} diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.definition.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.definition.tex new file mode 100644 index 00000000000..5b53178e4ac --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.definition.tex @@ -0,0 +1,529 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Map Definition and Map Coordinates}\label{sec:map_definition}% + +\tikzsetnextfilename{def_mrcdefinemap}% +\begin{dispExample} +\begin{tikzpicture} +\mrcdefinemap{west=11,east=13,north=49,south=48} +\mrcdrawmap[draw=path] +\mrcdrawnetwork +\draw (mrc cs:latitude=48.53475,longitude=12.15087) circle (2mm); +\draw[red] (mrc cs:lat=48.53475,lon=12.15087) circle (3mm); +\draw[blue] (mrcq cs:48.53475:12.15087) circle (4mm); +\ifmrcinmap{48.53475}{12.15087}{ \draw[yellow] (mrcpos) circle (5mm);}{} +\ifmrcinvicinity{48.53475}{12.15087}{\draw[cyan] (mrcpos) circle (6mm);}{} +\end{tikzpicture} +\end{dispExample} + +%------------------------------------------------------------------------------- +\subsection{Option Setting} +\begin{docCommand}{mermapset}{\marg{options}} + Sets \meta{options} for all following maps inside the current \TeX\ group. + All options share the common prefix |/mermap/|, e.g. for setting + \refKey{/mermap/vicinity} use + \begin{dispListing} + \mermapset{vicinity=3cm} + \end{dispListing} + Also see \refCom{mrcdefinemap}, \refCom{mermapsetsupply}, + and \refCom{mermapsetmarker}.\par + Note that the options by \refCom{mermapset} are |expl3| \cite{package:expl3} + keys while \tikzname\ \cite{package:tikz} uses its own key management. +\end{docCommand} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Manual Map Definition} +The following map definition is only relevant, if no script setup is used +and maps are generated completely manually. +See \Fullref{sec:automated_map} for script aided map definitions. + +\begin{docCommand}{mrcdefinemap}{\marg{options}} + Establishes a map inside a |tikzpicture| environment following + and applying the given \meta{options}. + All options share the common prefix |/mermap/mapdef/|. + After \refCom{mrcdefinemap} is applied, map drawing and map coordinates + can be used. + \begin{itemize} + \item\refCom{mrcdefinemap} can be used directly, if no tile download + and no script setup is intended. + \item\refCom{mrcdefinemap} is implicitly used with + \refCom{mrcapplymap} and \refCom{mrcmap}. In this case, all options are + also set implicitly. + \end{itemize} +\end{docCommand} + + +\begin{docMrcKey}{mapdef/north}{=\meta{map north latitude}}{no default, initially 50} + Northern latitude degree of the visible map, possibly negative for the southern hemisphere, + lower than $90$ but always larger than \refKey{/mermap/mapdef/south}. + It is accessible as \docAuxCommand{mrcmapnorth} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/south}{=\meta{map south latitude}}{no default, initially 48} + Southern latitude degree of the visible map, possibly negative for the southern hemisphere, + larger than $-90$ but always lower than \refKey{/mermap/mapdef/north}. + It is accessible as \docAuxCommand{mrcmapsouth} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/west}{=\meta{map west longitude}}{no default, initially 11} + Western longitude degree of the visible map, possibly negative for the western hemisphere, + possibly shifted periodically, but always lower than \refKey{/mermap/mapdef/east}. + It is accessible as \docAuxCommand{mrcmapwest} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/east}{=\meta{map east longitude}}{no default, initially 13} + Eastern longitude degree of the visible map, possibly negative for the western hemisphere, + possibly shifted periodically, but always larger than \refKey{/mermap/mapdef/west}. + It is accessible as \docAuxCommand{mrcmapeast} (use read-only). +\end{docMrcKey} + + +%------------------------------------------------------------------------------- +\subsection{Further Map Definition Options} + + +The following options are typically implicitly set by \refCom{mrcapplymap} +and not manually by \refCom{mrcdefinemap}. However, some values are +computationally used in all cases. They can be ignored as pure technical +information. + +\begin{docMrcKey}{mapdef/xmin}{=\meta{map tile x minimum}}{no default, initially 271} + Minimal $x$ coordinate of the map tiles. +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/xmax}{=\meta{map tile x maximum}}{no default, initially 275} + Maximal $x$ coordinate of the map tiles. +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/ymin}{=\meta{map tile y minimum}}{no default, initially 173} + Minimal $y$ coordinate of the map tiles. +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/ymax}{=\meta{map tile y maximum}}{no default, initially 177} + Maximal $y$ coordinate of the map tiles. +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/zoom}{=\meta{map zoom}}{no default, initially 9} + Map tile zoom factor alias $z$ coordinate of the map tiles. +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/pixelwidth}{=\meta{map width in pixels}}{no default, initially 100} + Width of the visible map expressed in pixels of the source file(s). + It is accessible as \docAuxCommand{mrcpixelwidth} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/pixelheight}{=\meta{map height in tiles}}{no default, initially 100} + Height of the visible map expressed in pixels of the source file(s). + It is accessible as \docAuxCommand{mrcpixelheight} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/westoffset}{=\meta{map tile offset (west)}}{no default, initially 0} + Distance of the visible map from the western edge of the most western tile + expressed in tiles (range from 0 to 1). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/northoffset}{=\meta{map tile offset (north)}}{no default, initially 0} + Distance of the visible map from the northern edge of the most northern tile + expressed in tiles (range from 0 to 1). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/southoffset}{=\meta{map tile offset (south)}}{no default, initially 0} + Distance of the visible map from the southern edge of the most southern tile + expressed in tiles (range from 0 to 1). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/basename}{=\meta{map tile base name}}{no default, initially \texttt{tiles/tile}} + File base name for the tiles. +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/attribution}{=\meta{attribution text}}{no default, initially empty} + Attribution text for the map source. Typically, it acknowledges the copyright + of the map data provider. It may contain hyperlinks. + It is accessible as \docAuxCommand{mrcmapattribution} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/attribution print}{=\meta{attribution text}}{no default, initially empty} + Attribution text for the map source. + In contrast to \refKey{/mermap/mapdef/attribution} it is intended for media + that does not support hyperlinks like printed posters, books, etc. + It is accessible as \docAuxCommand{mrcmapattributionprint} (use read-only). +\end{docMrcKey} + + +\begin{docMrcKey}{mapdef/resource}{=\meta{map resource}}{no default, initially |none|} + Available map resource with following feasible values: + \begin{itemize} + \item\docValue{none}: No tiles and no merged map. + \item\docValue{tiles}: Map tiles locally available. + \item\docValue{mergedmap}: Single map picture file merged from tiles locally available. + \item\docValue{wmsmap}: Single map picture file locally available. + \end{itemize} +\end{docMrcKey} + +\begin{docMrcKey}{mapdef/tile size}{=\meta{length}}{no default, initially |32.512mm|} + Typically set computationally. It is identical to \refKey{/mermap/tile size} + which is the recommended user option for manual setup. +\end{docMrcKey} + + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Map Coordinate System} +After a map is defined inside a |tikzpicture| environment +by \refCom{mrcdefinemap}, \refCom{mrcapplymap}, or \refCom{mrcmap}, +a Mercator map coordinate system can be used. +The border of the visible map is denoted by a \tikzname\ node \docNode{mrcmap}. + +\tikzsetnextfilename{def_coordinate_system}% +\begin{dispExample} +\begin{tikzpicture} + \mrcNPdef{nuremberg}{49.45522}{11.07631} + \mermapset{tile size=2cm} + \mrcdefinemap{west=5,east=15,south=47,north=55,zoom=7} + \path[draw,fill=green!10] (mrcmap.south west) rectangle (mrcmap.north east); + \mrcdrawnetwork + \fill (mrc cs:latitude=48.137222,longitude=11.575556) circle (2pt) + node[below] {M\"unchen}; + \fill (mrc cs:lat=53.550556,lon=9.993333) circle (2pt) + node[above] {Hamburg}; + \fill (mrcq cs:52.518611:13.408333) circle (2pt) + node[left] {Berlin}; + \fill (\mrcNPcs{nuremberg}) circle (2pt) node[above] {N\"urnberg}; + \ifmrcinmap{50.938056}{6.956944}{ + \fill (mrcpos) circle (2pt) node[right] {K\"oln};}{} + \ifmrcNPinmap{nuremberg}{\draw[red] (mrcpos) circle (1cm);}{} +\end{tikzpicture} +\end{dispExample} + + +\medskip +The |mrc cs| coordinate system defines a map point by +\refKey{/mermap/cs/latitude} and \refKey{/mermap/cs/longitude} + +\begin{docMrcKey}{cs/latitude}{=\meta{latitude}}{no default} + Sets the \meta{latitude} of a map point. +\end{docMrcKey} + +\begin{docMrcKey}{cs/longitude}{=\meta{longitude}}{no default} + Sets the \meta{longitude} of a map point. +\end{docMrcKey} + +\begin{dispListing} + \fill (mrc cs:latitude=48.137222,longitude=11.575556) circle (2pt); +\end{dispListing} + +\medskip +A map point can also be defined by shorter variants +\refKey{/mermap/cs/lat} and \refKey{/mermap/cs/lon} + +\begin{docMrcKey}{cs/lat}{=\meta{latitude}}{no default} + Sets the \meta{latitude} of a map point. +\end{docMrcKey} + +\begin{docMrcKey}{cs/lon}{=\meta{longitude}}{no default} + Sets the \meta{longitude} of a map point. +\end{docMrcKey} + +\begin{dispListing} + \fill (mrc cs:lat=48.137222,lon=11.575556) circle (2pt); +\end{dispListing} + +\medskip +A map point can be defined even quicker by +|(mrcq cs:|\meta{latitude}|:|\meta{longitude}|)|. + +\begin{dispListing} + \fill (mrcq cs:48.137222:11.575556) circle (2pt); +\end{dispListing} + +\medskip + +\begin{docCommand}{mrcpgfpoint}{\marg{latitude}\marg{longitude}} + Yields a low level |pgf| point location given by + \meta{latitude} and \meta{longitude}. + This can be used like |\pgfpoint|. + \begin{dispListing} + \pgfpathcircle{\mrcpgfpoint{49.45522}{11.07631}}{2pt} + \pgfusepath{fill} + \end{dispListing} +\end{docCommand} + + + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Named Positions}\label{sec:names_positions} + + +\begin{docCommand}{mrcNPdef}{\marg{name}\marg{latitude}\marg{longitude}} + A coordinate pair of \meta{latitude} and \meta{longitude} + can be saved as \emph{named position} (NP) to a \meta{name} for later use. + The \emph{named position} just stores the given values as evaluated + floating points but without coordinate system processing. + Therefore, a named position can be used outside a map definition + or |tikzpicture| environment, even as a preset for the whole document. + Note that this saving is not global but only effective inside the + current \TeX\ group. + \begin{dispListing} + \mrcNPdef{nuremberg}{49.45522}{11.07631} + \end{dispListing} +\end{docCommand} + + +\begin{docCommand}{mrcNPfrompoint}{\marg{name}\marg{\tikzname\ point}} + \emph{Latitude} and \emph{longitude} of a given \meta{\tikzname\ point} are + calculated and saved as \emph{named position} (NP) with given \meta{name}. + \refCom{mrcNPfrompoint} can only be used after a valid a map definition + inside a |tikzpicture| environment. + \begin{dispListing} + \mrcNPfrompoint{mapcenter}{mrcmap.center} + \mrcNPfrompoint{mytest}{[xshift=1cm,yshift=1cm]mrcmap.south west} + \end{dispListing} +\end{docCommand} + + +\begin{docCommand}{mrcNPcs}{\marg{name}} + A map point definition from the \meta{name} of a previously saved + \emph{named position} (NP). + \begin{dispListing} + \fill (\mrcNPcs{nuremberg}) circle (2pt) node[above] {N\"urnberg}; + \end{dispListing} +\end{docCommand} + + +\begin{docCommand}{mrcNPlat}{\marg{name}} + Inserts the \emph{latitude} of a \emph{named position} with given \meta{name}. + \refCom{mrcNPlat} is expandable and may be used in floating point expressions. + \begin{dispExample} + \mrcNPdef{nuremberg}{49.45522}{11.07631} + Latitude: \mrcNPlat{nuremberg}\\ + Longitude: \mrcNPlon{nuremberg} + \end{dispExample} +\end{docCommand} + + +\begin{docCommand}{mrcNPlon}{\marg{name}} + Inserts the \emph{longitude} of a \emph{named position} with given \meta{name}. + \refCom{mrcNPlon} is expandable and may be used in floating point expressions. +\end{docCommand} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Tests for Points to be inside or outside a Map} + +When a map is drawn, \refCom{mrcclipmap} can be used to set up a +\tikzname\ clip environment which automatically removes all content which +is not inside the defined map. However, the \tikzname\ position of a geographic +point has to be computed first to decide, if this point is to be drawn. +Since \TeX\ length registers do not allow large dimensions, compiler errors +are possible to happen. + +The following tests check given geographic coordinates before they are +transformed to \TeX\ dimensions and avoid such compiler errors. + +\begin{docCommand}{ifmrcinmap}{\marg{latitude}\marg{longitude}\marg{true}\marg{false}} + If the given \meta{latitude} and \meta{longitude} describes a point + inside the visible map, the \meta{true} code is executed, otherwise + the \meta{false} code.\par + Inside the \meta{true} code a \tikzname\ coordinate \docNode{mrcpos} + describes the given point. Also, \docNode{mrclastpos} denotes the + \emph{last} position before. + \begin{dispListing} + \ifmrcinmap{48.137222}{11.575556}{\fill (mrcpos) circle (2pt);}{} + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{ifmrcNPinmap}{\marg{name}\marg{true}\marg{false}} + If the given \emph{named position} (NP) \meta{name} describes a point + inside the visible map, the \meta{true} code is executed, otherwise + the \meta{false} code. + \begin{dispListing} + \mrcNPdef{munich}{48.137222}{11.575556} + \ifmrcNPinmap{munich}{\fill (mrcpos) circle (2pt);}{} + \end{dispListing} +\end{docCommand} + + +Very similar to \refCom{ifmrcinmap} is \refCom{ifmrcinvicinity}. + +\begin{docCommand}{ifmrcinvicinity}{\marg{latitude}\marg{longitude}\marg{true}\marg{false}} + If the given \meta{latitude} and \meta{longitude} describes a point + inside a vicinity of the visible map, i.e. the map \emph{plus} a margin of \refKey{/mermap/vicinity}, + the \meta{true} code is executed, otherwise + the \meta{false} code.\par + Inside the \meta{true} code a \tikzname\ coordinate \docNode{mrcpos} + describes the given point. Also, \docNode{mrclastpos} denotes the + \emph{last} position before.\par + \refCom{ifmrcinvicinity} may be used for objects of a certain size like + markers which could be partly visible even when their reference point + is outside the visible map (but nearby). +\begin{dispListing} + \ifmrcinvicinity{48.137222}{11.575556}{\fill (mrcpos) circle (2pt);}{} +\end{dispListing} +\end{docCommand} + + +\begin{docCommand}{ifmrcNPinvicinity}{\marg{name}\marg{true}\marg{false}} + If the given \emph{named position} (NP) \meta{name} describes a point + inside a vicinity of the visible map, the \meta{true} code is executed, otherwise + the \meta{false} code, see \refCom{ifmrcinvicinity}. +\begin{dispListing} + \mrcNPdef{munich}{48.137222}{11.575556} + \ifmrcNPinvicinity{munich}{\fill (mrcpos) circle (2pt);}{} +\end{dispListing} +\end{docCommand} + + +\begin{docMrcKey}{vicinity}{=\meta{width}}{no default, initially |2cm|} + The vicinity of the map is the given map plus a border in all directions + with the given \meta{width}. +\end{docMrcKey} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Formatted Coordinate Output} + +\begin{docCommand}{mrcformlat}{\oarg{options}\marg{latitude}} + Formatted output for a given \meta{latitude} following given \meta{options}. + Formatting \meta{options} are described in the following. + \begin{dispExample} + Latitude from \mrcformlat{-24.29} to \mrcformlat{12.3456789}. + \end{dispExample} +\end{docCommand} + +\begin{docCommand}{mrcformlon}{\oarg{options}\marg{longitude}} + Formatted output for a given \meta{longitude} following given \meta{options}. + Formatting \meta{options} are described in the following. + \begin{dispExample} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} +\end{docCommand} + + +\begin{docMrcKey}{format angle}{=\meta{type}}{no default, initially |decimal-4|} + The \meta{type} defines some formatting settings for + \refCom{mrcformlat} and \refCom{mrcformlon}. Internally, the |\ang| macro + from package |siunitx| \cite{package:siunitx} is used which can be controlled by further settings + of |siunitx| like digit grouping or changing the decimal marker.\par + Feasible values for \meta{type} are + \begin{itemize} + \item\docValue{decimal}: decimal output without rounding. + \begin{dispExample} + \mermapset{format angle=decimal} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \item\docValue{decimal-0}: decimal output with rounding to full degrees. + \begin{dispExample} + \mermapset{format angle=decimal-0} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \item\docValue{decimal-1}: decimal output with rounding to one place. + \begin{dispExample} + \mermapset{format angle=decimal-1} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \item\docValue{decimal-2}: decimal output with rounding to two places. + \begin{dispExample} + \mermapset{format angle=decimal-2} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \pagebreak + \item\docValue{decimal-3}: decimal output with rounding to three places. + \begin{dispExample} + \mermapset{format angle=decimal-3} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \item\docValue{decimal-4}: decimal output with rounding to four places. + \begin{dispExample} + \mermapset{format angle=decimal-4} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \item\docValue{degree}: output with rounding to full degrees. + This is an alias for \docValue{decimal-0}. + \begin{dispExample} + \mermapset{format angle=degree} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \item\docValue{minute}: output with rounding to degrees and full minutes. + \begin{dispExample} + \mermapset{format angle=minute} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \item\docValue{second}: output with rounding to degrees, minutes, and full seconds. + \begin{dispExample} + \mermapset{format angle=second} + Longitude from \mrcformlon{-24.29} to \mrcformlon{12.3456789}. + \end{dispExample} + \end{itemize} +\end{docMrcKey} + + +\begin{docMrcKey}{format south}{=\meta{code}}{no default, initially \texttt{\#1\textbackslash,S}} + Defines the format \meta{code} for a negative latitude. + Use \texttt{\#1} to place the number (without sign). + \begin{dispExample} + \mermapset{format south={$-#1$}} + Latitude \mrcformlat{-24.29}. + \end{dispExample} +\end{docMrcKey} + +\begin{docMrcKey}{format north}{=\meta{code}}{no default, initially \texttt{\#1\textbackslash,N}} + Defines the format \meta{code} for a non-negative latitude. + Use \texttt{\#1} to place the number. + \begin{dispExample} + \mermapset{format north={#1 North}} + Latitude \mrcformlat{12.3456789}. + \end{dispExample} +\end{docMrcKey} + +\pagebreak +\begin{docMrcKey}{format east}{=\meta{code}}{no default, initially \texttt{\#1\textbackslash,E}} + Defines the format \meta{code} for a positive longitude. + Use \texttt{\#1} to place the number (without sign). + \begin{dispExample} + \mermapset{format east={#1\,O}} + \sisetup{output-decimal-marker={,}} + L\"angengrad \mrcformlon{12.3456789}. + \end{dispExample} +\end{docMrcKey} + +\begin{docMrcKey}{format west}{=\meta{code}}{no default, initially \texttt{\#1\textbackslash,W}} + Defines the format \meta{code} for a negative longitude. + Use \texttt{\#1} to place the number. + \begin{dispExample} + \mermapset{format west={West: #1}} + Longitude \mrcformlon{-24.29}. + \end{dispExample} +\end{docMrcKey} + + +\begin{docMrcKey}{format NEWS numeric}{}{no value} + Defines the format for north, east, west, and south as numeric value + without N, E, W, S. + \begin{dispExample} + \mermapset{format NEWS numeric} + Longitude \mrcformlon{-24.29} and \mrcformlon{12.3456789}.\\ + Latitude \mrcformlat{-24.29} and \mrcformlat{12.3456789}. + \end{dispExample} +\end{docMrcKey} + + +\begin{docMrcKey}{format NEWS absolute}{}{no value} + Defines the format for north, east, west, and south as absolute value + without N, E, W, S and without algebraic sign. + \begin{dispExample} + \mermapset{format NEWS absolute} + Longitude \mrcformlon{-24.29} and \mrcformlon{12.3456789}.\\ + Latitude \mrcformlat{-24.29} and \mrcformlat{12.3456789}. + \end{dispExample} +\end{docMrcKey} + diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.drawing.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.drawing.tex new file mode 100644 index 00000000000..a40131381f9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.drawing.tex @@ -0,0 +1,253 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Map Drawing} + +%------------------------------------------------------------------------------- +\subsection{Principal Drawing} + +\begin{docCommand}{mrcdrawmap}{\oarg{options}} + Inside a |tikzpicture| environment, \refCom{mrcdrawmap} draws a map + prepared by \refCom{mrcdefinemap}, \refCom{mrcapplymap}, or \refCom{mrcmap}. + All \meta{options} share the common prefix |/mermap/|. + This is the principal macro to draw a prepared map respectively + the background of the map. The background consists of downloaded map tiles + or just a color rectangle. +\end{docCommand} + +\begin{docMrcKey}{draw}{=\meta{tile draw}}{no default, initially |auto|} + \begin{itemize} + \item\docValue{auto}: Draws the map according to \refKey{/mermap/mapdef/resource}, + i.e. downloaded maps or tiles are used, if available. + \item\docValue{path}: Draws the map according to the style given by + \refKey{/mermap/map path}. Existing map tiles or merged maps are ignored + \item\docValue{tiles}: Draws the map with downloaded map tiles, if + available. + \item\docValue{mergedmap}: Draws the map with a merged picture, if + available. + \item\docValue{wmsmap}: Draws the map with a downloaded WMS picture, if + available. + \end{itemize} +\end{docMrcKey} + +\begin{docMrcKey}{map path}{=\meta{options}}{no default, initially |upper left=green!50,|\\|upper right=green!25, lower left=green!50!black!50, lower right=green!25|} + Defines a \tikzname\ style for drawing the map without tiles. + \meta{options} are feasible \tikzname\ path options. +\end{docMrcKey} + +\begin{docMrcKey}{map clip}{=\meta{code}}{no default, initially \refCom{mrcclipmap}} + Clipping options for the map. By default, the defined map is + clipped with the full map rectangle. Use this option only, if you not want to clip + the map to its specified size. \meta{code} is some \tikzname\ clipping code. +\end{docMrcKey} + +\begin{docMrcKey}{map scope}{=\meta{options}}{no default, initially empty} + \refCom{mrcdrawmap} uses a |scope| environment inside which takes + the given \tikzname\ \meta{options}. +\end{docMrcKey} + + +\begin{docCommand}{mrcclipmap}{} + Clips all subsequent drawings against the applied map.\\ + This is a shortcut macro identical to + \begin{dispListing} + \path[clip] (mrcmap.south west) rectangle (mrcmap.north east); + \end{dispListing} +\end{docCommand} + + +\begin{docCommand}{mrcboundmap}{} + Sets the picture bounding box according to the applied map.\\ + This is a shortcut macro identical to + \begin{dispListing} + \path[use as bounding box] + (mrcmap.south west) rectangle (mrcmap.north east); + \end{dispListing} +\end{docCommand} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Flexible Tile Size}\label{sec:flexible_tile_size} + +Typically, the pixel size of a map tile is fixed and a map tile is a +pixel graphics file. The actual size of such an included picture inside +the document is freely selectable. Note that a very small +\refKey{/mermap/tile size} results in very small map lettering, +while a very large \refKey{/mermap/tile size} results results in +very blurred images. + +The general idea of a \emph{flexible} tile size is to specify an aspired +tile size called \refKey{/mermap/flex tile size} and to give \LaTeX\ +the freedom to select \refKey{/mermap/tile size} in \emph{about the same size} +as \refKey{/mermap/flex tile size}. +This freedom is used to achieve a \emph{pseudo zoom} called +\refKey{/mermap/flex zoom} which is a nearly arbitrary rational number instead +of \refKey{/mermap/supply/zoom} which is a natural number. + +This \emph{pseudo zoom} is applied by several options which share \emph{flex} +in their names, e.g. +\refKey{/mermap/flex scale}, \refKey{/mermap/named flex scale}, +\refKey{/mermap/supply/flex reference scale}, +\refKey{/mermap/supply/flex area scale}, +\refKey{/mermap/supply/flex area fit}. + + + +\begin{docMrcKey}{tile size}{=\meta{length}}{no default, initially |32.512mm|} + Width and height of a drawn tile picture are set to \meta{length}. + For standard tiles with 256 times 256 pixels a tile size of + \SI{32.512}{mm} = \SI{1.28}{in} results in an approximate + \SI{200}{dpi} output for the document. + For a |beamer| document, consider to use a \refKey{/mermap/tile size} of + \SI{21.333333}{mm} to get approximate 1:1 pixel input and output (depending on |beamer| settings + and used hardware). Also see \refKey{/mermap/mapdef/tile size}. +\end{docMrcKey} + +\begin{docMrcKey}{flex tile size}{=\meta{length}}{no default, initially |32.512mm|} + Aspired width and height of a tile picture are set to \meta{length}. + This value is used while applying \refKey{/mermap/flex zoom}. +\end{docMrcKey} + + +\begin{docMrcKey}{flex zoom}{=\meta{pseudo zoom}}{style, no default} + This style sets \refKey{/mermap/supply/zoom} and \refKey{/mermap/tile size} in combination. + \begin{itemize} + \item + If \meta{pseudo zoom} is a natural number, + \refKey{/mermap/supply/zoom} is set to \meta{pseudo zoom} and + \refKey{/mermap/tile size} is set to \refKey{/mermap/flex tile size}. + \item Otherwise, \refKey{/mermap/supply/zoom} is set to the natural number + closest to \meta{pseudo zoom} and \refKey{/mermap/tile size} is such + enlarged or reduced that the \meta{pseudo zoom} value is simulated, + i.e. the \emph{impression} of a rational zoom factor is given. + \end{itemize} + Note that \refKey{/mermap/flex zoom} has to be used \emph{before} + \refCom{mrcsupplymap} or \refCom{mrcmap}, because the zoom setup is + adapted. +\end{docMrcKey} + + +\clearpage +\begin{docMrcKey}{flex scale}{=\meta{scale denominator}:\meta{latitude}}{style, no default} + For different latitude scopes, an identical zoom factor produces maps of + different scale. With \refKey{/mermap/flex scale}, a \refKey{/mermap/flex zoom} + is computed to achieve the given \meta{scale denominator} at a given \meta{latitude}. + Note that this only applies to the center of a map. If the produced + map is not centered at \meta{latitude}, the produced scale may + differ from the intended one. + Also see \refKey{/mermap/supply/flex reference scale}. + +\tikzsetnextfilename{drawing_flex_scale}% +\begin{dispExample} +\begin{tikzpicture} + \mermapset{flex scale=250000:48.14} + \mrcmap[type=reference,latitude=48.14,longitude=11.57, + source=opentopomap, + tex width=\linewidth,tex height=5cm]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \node[below left=2mm, align=right, fill=white, fill opacity=0.5, + text opacity=1] + at (mrcmap.north east) {scale \mrcprettymapscale}; +\end{tikzpicture} +\end{dispExample} +\end{docMrcKey} + + + +\begin{docMrcKey}{named flex scale}{=\meta{scale denominator}:\meta{name}}{style, no default} + Identical to \refKey{/mermap/flex scale}, but used the \emph{named position} + \meta{name} to provide a \emph{latitude}, see \Fullref{sec:names_positions}. + \begin{dispListing} + \mrcNPdef{munich}{48.137222}{11.575556} + \mermapset{named flex scale=250000:munich} % identical to the following + \mermapset{flex scale=250000:\mrcNPlat{munich}} + \end{dispListing} +\end{docMrcKey} + + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Geodetic Network} + +\begin{docCommand}{mrcdrawnetwork}{\oarg{options}} + Draws a geodetic network with meridians and parallels. + All \meta{options} share the common prefix |/mermap/|. + The displayed lines are selected automatically according to some tuning + parameters. + The map is sliced in \emph{about} maximal \refKey{/mermap/network pieces} in each + direction. Meridians and parallels share a minimal distance of + \emph{about} \refKey{/mermap/network distance}. The algorithm is + allowed to violate these conditions \emph{somewhat}. + + Note that oversized maps are not supported, i.e. maps which are wider + than \ang{360} in longitude. Here, meridians are expected to be missing + or misplaced. + +\tikzsetnextfilename{drawing_network}% +\begin{dispExample*}{center lower} +% \mrcsetapikey{openrouteservice}{YOUR-API-KEY} % registered key +\begin{tikzpicture} + \mrcmap[ type = boundaries, + west = -20, east = 40, south = 36, north = 65, + source=openrouteservice mapsurfer, + flex area scale=40 000 000 ]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \mrcdrawnetwork + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); +\end{tikzpicture} +\end{dispExample*} +\end{docCommand} + + +\begin{docMrcKey}{network pieces}{=\meta{number}}{no default, initially |8|} + The map is sliced in \emph{about} maximal \meta{number} pieces in each + direction. \meta{number} may be exceeded \emph{somewhat}. + It is underrun to comply with \refKey{/mermap/network distance}. +\end{docMrcKey} + + +\begin{docMrcKey}{network distance}{=\meta{mesh width}}{no default, initially |2cm|} + Meridians and parallels share a minimal distance of + \emph{about} \meta{mesh width}. + \meta{mesh width} may be underrun \emph{somewhat}. + It is exceeded to comply with \refKey{/mermap/network pieces}. + For parallels on small scale maps, it refers to an averaged mesh width. +\end{docMrcKey} + +\begin{docMrcKey}{network font}{=\meta{text}}{no default, initially + |\textbackslash fontsize\brackets{4pt}\brackets{4pt}\textbackslash sffamily|} + \meta{text} is some font setting for the latitude and longitude display. +\end{docMrcKey} + + + +\subsection{Graphical Debug Overlay} + +\begin{docCommand}{mrcdrawinfo}{} + Draws some map information overlay for debugging purposes only. + \tikzsetnextfilename{drawing_mrcdrawinfo}% + \begin{dispExample} + \begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcmap[type=reference, named position=munich, source=opentopomap, + flex reference scale=50000, + tex width=\linewidth,tex height=10cm]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \mrcdrawinfo + \end{tikzpicture} + \end{dispExample} +\end{docCommand} diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.examples.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.examples.tex new file mode 100644 index 00000000000..f2630fef152 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.examples.tex @@ -0,0 +1,373 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Examples}\label{sec:examples}% + +The following map examples may be used as tutorials and +starting point for own applications. +Also see |mercatormap-example.tex| for a compilable full example. +Note to do all preparations documented in \Fullref{sec:python}. + + +%------------------------------------------------------------------------------- +\subsection{Reference Position} + +With \refKey{/mermap/supply/type}|=|\docValue{reference} a map with a +\emph{reference position} is constructed. Here, Munich is taken as +reference position and center of the map. Since the position is used +more than once, it is stored with \refCom{mrcNPdef} for further reference. +With \refKey{/mermap/supply/flex reference scale} the scale +is set to 1:6\,000\,000. For the background map tiles, a +\refKey{/mermap/supply/source} is selected for download. +This setup is done by \refCom{mrcmap} while \refCom{mrcdrawmap} draws +the downloaded map tiles. + +\tikzsetnextfilename{examples_reference}% +\begin{dispExample*}{center lower, breakable} +\begin{tikzpicture} + \sffamily + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{vienna}{48.208333}{16.373056} + \mrcNPdef{cologne}{50.938056}{6.956944} + \mrcNPdef{milano}{45.4625}{9.186389} + \mrcmap[type=reference, + named position=munich, + flex reference scale=6 000 000, + source=topplusopen web, + tex width=14cm, + tex height=14cm]{examples_reference} + \path[draw=yellow!50!gray,fill=yellow!20] + ([xshift=-2mm,yshift=-5mm]mrcmap.south west) rectangle + ([xshift=2mm,yshift=15mm]mrcmap.north east); + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \path[draw=yellow!50!gray] (mrcmap.south west) rectangle (mrcmap.north east); + + \mrcNPdraworthodrome[red,very thick]{munich}{milano} + \path[blue,very thick] (\mrcNPcs{munich}) -- + node[red,fill=white,sloped,below] {\mrcNPprettyloxodistance{munich}{milano}} + (\mrcNPcs{milano}); + + \mermapsetmarker{type=pin, draw=red, fill=red!10, font=\sffamily\small} + \mrcmarker{named position=munich, contents={M\"unchen}} + \mrcmarker{named position=vienna, contents={Wien}} + \mrcmarker{named position=cologne, contents={K\"oln}} + \mrcmarker{named position=milano, contents={Milano}} + + \node[above left=5mm,font=\Large\bfseries] at (mrcmap.north east) {Munich}; + + \node[above right] at ([yshift=10mm]mrcmap.north west) + {Scale \mrcprettymapscale}; + + \mrcdrawscalebar[width-in-km=300,partitions=6,north-west-outside=0mm;5mm, + single, height=1mm, major style={yellow!50!gray!50!black}] + \path[every node/.style={above,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.north west) -- (mrcscalebar.north east) + node[pos=0]{0} node[pos=0.3333]{100} node[pos=0.6667]{200} + node[pos=1]{300\,km}; + + \mrcdrawscalebar[width-in-mile=200,partitions=8, + at={(mrcscalebar.south west)},placement=below right, + single, height=1mm, major style={yellow!50!gray!50!black}] + \path[every node/.style={below,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.south west) -- (mrcscalebar.south east) + node[pos=0]{0} node[pos=0.25]{50} node[pos=0.5]{100} node[pos=0.75]{150} + node[pos=1]{200\,miles}; +\end{tikzpicture} +\end{dispExample*} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Fitting Area} + +With \refKey{/mermap/supply/type}|=|\docValue{areafit} a map is constructed +where a given area is fitted in. The following example lists some +US-American cities and constructs an \refKey{/mermap/supply/area} which +contains all of them. With \refKey{/mermap/supply/flex area fit}|=15mm| a +border region is added. + + +\tikzsetnextfilename{examples_fitting_area}% +\begin{dispExample*}{center lower} +\begin{tikzpicture} + \mrcNPdef{honolulu}{21.305225}{-157.867} + \mrcNPdef{fairbanks}{64.8379435}{-147.7192214} + \mrcNPdef{sandiego}{32.7146781}{-117.1640995} + \mrcNPdef{miami}{25.7599333}{-80.1951257} + \mrcNPdef{boston}{42.359744}{-71.061322} + \mrcNPdef{denver}{39.7372435}{-104.997378} + \mrcmap[type=areafit, + area={honolulu,fairbanks,sandiego,miami,boston,denver}, + source=stamen terrain, + tex width=15cm, tex height=11cm, + flex area fit=15mm, + ]{examples_fitting_area} + \mrcdrawmap \mrcdrawnetwork + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \node[below left,fill=white,opacity=0.8,text opacity=1] at (mrcmap.north east) + {Scale \mrcprettymapscale}; + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \foreach \city in {honolulu,fairbanks,sandiego,miami,boston,denver} + {\mrcmarker{type=ringx, draw=red, fill=red!20, named position=\city}} +\end{tikzpicture} +\end{dispExample*} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Fixed Boundaries} + +With \refKey{/mermap/supply/type}|=|\docValue{boundaries} a map is constructed +with fixed boundaries. In contrast to the other map types, the document +map size cannot be given directly but derives from the map setup. This bears +the risk of too large maps. The following example is a map with exact +boundaries \mrcformlat{-45} to \mrcformlat{-10} +and \mrcformlon{110} to \mrcformlon{155}. A decent \refKey{/mermap/supply/zoom} +is 5 (every zoom step doubles the map size in each direction). + +\tikzsetnextfilename{examples_boundaries}% +\begin{dispExample*}{center lower,breakable} +% \mrcsetapikey{openrouteservice}{YOUR-API-KEY} % registered key +\begin{tikzpicture} + \mrcmap[type=boundaries, + west=110,east=155,south=-45,north=-10, + zoom=5, + source=openrouteservice mapsurfer, + ]{examples_boundaries} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcdrawnetwork + \mrcdrawscalebar[width-in-km=1000,partitions=4,south-west-inside=5mm, + major style={blue!50!gray!50!black}] + \path[every node/.style={below,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.south west) -- (mrcscalebar.south east) + node[pos=0]{0} node[pos=0.5]{500} + node[pos=1]{1000} node[pos=1,right,yshift=1mm]{km}; + \mrcmarker{lat=-35.3,lon=149.116667,type=pictodropring, + draw=red,fill=red!10} +\end{tikzpicture} +\end{dispExample*} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Map Without Map Tiles} + +There is no coercion to use downloaded map tiles, if they are not needed or +wanted. With \refKey{/mermap/supply/target}|=none| no map tiles are downloaded. +The following example draws a rough polygon shape of Germany using +\refEnv{mrcroute*}. + +\tikzsetnextfilename{examples_routemap}% +\begin{dispExample*}{center lower,breakable} +\begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{cologne}{50.938056}{6.956944} + \mrcNPdef{hamburg}{53.550556}{9.993333} + \mrcNPdef{berlin}{52.518611}{13.408333} + \mrcmap[type=areafit, + west=5,east=15,south=47,north=55, + target=none, + tex width=14cm, tex height=14cm, + flex area fit=5mm + ]{examples_routemap} + \mrcclipmap + \path[draw,fill=yellow!5] (mrcmap.south west) rectangle (mrcmap.north east); + \begin{mrcroute*}[ + preaction={fill=black,opacity=.5, + transform canvas={xshift=1mm,yshift=-1mm}}, + draw = green!50!black, + top color = green!50!gray!5, + bottom color = green!50!gray!15] + \mrcpoint{47.57268069220318}{8.07968771809688} + \mrcpoint{47.55206513030159}{8.458302263852103} + \mrcpoint{47.60652271644701}{8.58564576447632} + \mrcpoint{47.65002478441761}{8.475977737743394} + \mrcpoint{47.8129149100372}{8.621611270810012} + \mrcpoint{47.70405949548734}{8.824753417980977} + \mrcpoint{47.57118357939037}{9.373387060586875} + \mrcpoint{47.57763968687206}{9.783024034250792} + \mrcpoint{47.46598581489455}{10.09335967295321} + \mrcpoint{47.28014625489598}{10.22678291669482} + \mrcpoint{47.32098723021947}{10.40092026792467} + \mrcpoint{47.52413897927237}{10.53589647271817} + \mrcpoint{47.5130331145614}{10.94403341747166} + \mrcpoint{47.39097338968944}{11.04734763681045} + \mrcpoint{47.42252867275465}{11.44170163808758} + \mrcpoint{47.57832219946236}{11.64025530020549} + \mrcpoint{47.65203740659043}{12.2451260343467} + \mrcpoint{47.64005851006706}{12.78135708694006} + \mrcpoint{47.42189293170733}{13.06242166895717} + \mrcpoint{47.68727761120528}{13.13421507093485} + \mrcpoint{47.70570852317097}{12.97737528172392} + \mrcpoint{47.86836520373472}{12.94442906710615} + \mrcpoint{48.06063312315187}{12.76937524145701} + \mrcpoint{48.33220372303314}{13.38497370385176} + \mrcpoint{48.57060635511297}{13.55281830406328} + \mrcpoint{48.51465473490364}{13.78916086481733} + \mrcpoint{48.74889509826911}{13.84448153318651} + \mrcpoint{48.95974762545411}{13.50952525317658} + \mrcpoint{49.37838143356481}{12.77000417129028} + \mrcpoint{49.78495654813383}{12.44617209199484} + \mrcpoint{49.93155217044134}{12.49159565814237} + \mrcpoint{50.13144236663469}{12.24546848540114} + \mrcpoint{50.28771270517358}{12.30810150664619} + \mrcpoint{50.40989390494432}{12.94903619964524} + \mrcpoint{50.65841629251407}{13.3075062965852} + \mrcpoint{50.76329878585482}{13.97452403458363} + \mrcpoint{51.02604511746936}{14.41278607347103} + \mrcpoint{50.79185062876172}{14.80477069337384} + \mrcpoint{51.15202957355457}{14.99270251686064} + \mrcpoint{51.34128169635556}{15.02098384386006} + \mrcpoint{51.53750266315752}{14.74120138252564} + \mrcpoint{51.81924062442433}{14.62724686001225} + \mrcpoint{52.11180711219343}{14.70514397703483} + \mrcpoint{52.39266284958671}{14.60756306378661} + \mrcpoint{52.60597277515545}{14.58725108586684} + \mrcpoint{52.88134471470577}{14.16977248675916} + \mrcpoint{53.14560306739344}{14.4215985570986} + \mrcpoint{53.43447627332744}{14.39440456086107} + \mrcpoint{53.76080228279986}{14.26477636730856} + \mrcpoint{54.07894830697219}{13.84113247149844} + \mrcpoint{54.34144910466647}{13.71477685386829} + \mrcpoint{54.57879841452108}{13.41784866398943} + \mrcpoint{54.38430816973541}{12.55218424463898} + \mrcpoint{54.16285895583508}{12.11170524536321} + \mrcpoint{54.11909611435144}{11.78253136604545} + \mrcpoint{53.9629318241985}{11.23001765303107} + \mrcpoint{54.02548042559235}{10.82100535035693} + \mrcpoint{54.20942342601608}{11.17572026938692} + \mrcpoint{54.42622022041155}{11.04601054827628} + \mrcpoint{54.31534430886417}{10.73027571352005} + \mrcpoint{54.4430955768925}{10.19233706975044} + \mrcpoint{54.8317448735389}{10.00757468096804} + \mrcpoint{54.87986478845961}{9.659528688958062} + \mrcpoint{54.8308224503691}{9.271730840012292} + \mrcpoint{54.92302453288877}{8.571394535898566} + \mrcpoint{54.49119535498197}{8.900730234661252} + \mrcpoint{54.34335254823343}{8.645116397508792} + \mrcpoint{54.22420563732749}{8.880431477246834} + \mrcpoint{53.87404422621243}{8.679945700393079} + \mrcpoint{53.54658560722722}{8.286556227539295} + \mrcpoint{53.7066272365128}{8.034813408953866} + \mrcpoint{53.78031118673399}{7.387421106389351} + \mrcpoint{53.51218238635882}{6.930006752473437} + \mrcpoint{53.25894778199789}{7.171145313101468} + \mrcpoint{52.64374200661974}{6.997019504055286} + \mrcpoint{52.55662475372522}{6.719778263650637} + \mrcpoint{52.38988292317155}{6.970320972580792} + \mrcpoint{51.92299983362206}{6.742905287863996} + \mrcpoint{51.88316670940459}{6.156741607019097} + \mrcpoint{51.79567780329431}{5.98801954642294} + \mrcpoint{51.43928428452571}{6.159613225461791} + \mrcpoint{51.0215877919207}{5.887936542477828} + \mrcpoint{50.79077378475993}{5.983374968822379} + \mrcpoint{50.59470107381249}{6.228393825507839} + \mrcpoint{50.33147032961352}{6.304617231833176} + \mrcpoint{50.15747573005454}{6.092865298740861} + \mrcpoint{49.97845765993797}{6.16527138749146} + \mrcpoint{49.78369815200002}{6.535162836379246} + \mrcpoint{49.45067080157749}{6.378063336429978} + \mrcpoint{49.11701097547841}{6.794068795882435} + \mrcpoint{49.14800972775451}{7.494253217695865} + \mrcpoint{49.03198382192998}{7.640486837553122} + \mrcpoint{48.92859396692077}{8.238456398546767} + \mrcpoint{48.61606185482966}{7.832853167339047} + \mrcpoint{48.05389084062409}{7.510556381211842} + \mrcpoint{47.56795313962416}{7.588782160556193} + \mrcpoint{47.57268069220318}{8.07968771809688} + \end{mrcroute*} + \foreach \city / \name in {munich/M\"unchen, cologne/K\"oln, + hamburg/Hamburg, berlin/Berlin} + { + \mrcmarker{named position=\city,type=knob,fill=red!20,draw=red, + radius=2mm} + \mrcmarker{named position=\city,type=pin,fill=blue!10,draw=blue, + contents=\name} + } +\end{tikzpicture} +\end{dispExample*} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Alignment of the Reference Position} + +With \refKey{/mermap/supply/align} the reference position can be aligned +at different map positions. + +\tikzsetnextfilename{examples_alignment}% +\begin{dispExample*}{center lower} +\mrcNPdef{munich}{48.137222}{11.575556} +\foreach \a in {east,center,west,north} { +\begin{tikzpicture} + \mrcmap[type=reference, + named position=munich, + flex reference scale=1 000 000, + source=opentopomap, + tex width=\linewidth,tex height=3cm, + align=\a]{examples_alignment_\a} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; \mrcclipmap + \tikzset{every node/.style={fill=white,fill opacity=0.8,text opacity=1}} + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \ifmrcNPinvicinity{munich}{ + \fill[red] (mrcpos) circle (4pt) node[below] {M\"unchen};}{} + \node[text=red,above left] at (mrcmap.south east) {align=\a}; +\end{tikzpicture} +\par} +\end{dispExample*} + + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Flexible Zoom} + +Map tiles are only provided at fixed zoom levels with natural numbers, +but the package allows a \refKey{/mermap/flex zoom} with rational numbers. +The flexible zoom is realized by combining a suitable fixed zoom with +an adapted document tile scaling, see \Fullref{sec:flexible_tile_size}. +The following example shows a more or less smooth zoom increase. +The same technique is used by all options starting with |flex|, e.g. +\refKey{/mermap/supply/flex reference scale} +or \refKey{/mermap/supply/flex area fit} +as seen in the examples before. + +\tikzexternaldisable +\tikzsetnextfilename{examples_flex_zoom}% +\begin{dispExample*}{center lower,breakable} +% \mrcsetapikey{thunderforest}{YOUR-API-KEY} % registered key +\mrcNPdef{munich}{48.137222}{11.575556} +\foreach \zz in {7.0,7.2,...,9.0} { +\edef\z{\fpeval{round(\zz,1)}} +\begin{tikzpicture} + \mermapset{flex zoom=\z} + \mrcmap[type=reference, + named position=munich, + source=thunderforest outdoors, + tex width=\linewidth, + tex height=3cm + ]{examples_flex_zoom_\z} + \mrcdrawmap + \mrcclipmap + \tikzset{every node/.style={fill=white,fill opacity=0.5,text opacity=1}} + \node[above,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \node[below left=2mm,align=right] at (mrcmap.north east) + {flex zoom=\fpeval{round(\z,1)}\\ scale \mrcprettymapscale}; + \ifmrcNPinvicinity{munich}{ + \fill (mrcpos) circle (2pt) node[below] {M\"unchen};}{} +\end{tikzpicture}\par} +\end{dispExample*} + + + diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.intro.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.intro.tex new file mode 100644 index 00000000000..294f5e278fc --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.intro.tex @@ -0,0 +1,150 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Introduction}% + +The \texttt{mercatormap} package enables map drawing with the +Web Mercator projection. This is done as an extension to +\tikzname\ \cite{package:tikz} with is complemented by a map +coordinate system and many additional commands and options to add elements +like markers, geodetic networks, bar scales, routes, orthodrome +pieces, distance calculations, etc. Also, the seamless integration of graphics +from public map tile servers is provided through a Python script. + +If you are interested in the mathematical background of the Web Mercator projection +and the algorithms of this packages, you are invited to read +\enquote{\fullcite{Sturm:2020}}. + +With very few exceptions, the package is programmed with the +|expl3| \cite{package:expl3} programming interface for \LaTeX3 +and loads the packages +|xparse| \cite{package:xparse} and |siunitx| \cite{package:siunitx}. + +\medskip + + +\tikzsetnextfilename{intro_example}% +\begin{tikzpicture} + \mrcmap[ + type=reference, + position=48.1579577:11.4980376, + align=west, + flex reference scale=20000, + tex width=\linewidth, + tex height=5cm, + source=topplusopen web + ]{intro_example} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) {\mrcmapattribution}; + \node[above right, font=\sffamily\footnotesize] at (mrcmap.north west) {\mrcprettymapscale}; + \mrcdrawscalebar[width-in-meter=800,partitions=8,north-east-outside=5mm;1.5mm, + major style={black!75}] + \path[every node/.style={above,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.north west) -- (mrcscalebar.north east) + node[pos=0]{0} node[pos=0.25]{200} node[pos=0.5]{400} node[pos=0.75]{600} + node[pos=1]{800} node[pos=1,right,yshift=-1mm]{m}; + \mrcdrawnetwork + \mrcmarker{type=pin, draw=Blue_Gray, fill=Blue_Gray!10, font=\sffamily\footnotesize, + position=48.1582513:11.5032997, contents={Nymphenburg}} + \mrcclipmap + \draw (mrcmap.south west) rectangle (mrcmap.north east); +\end{tikzpicture} + + + +%------------------------------------------------------------------------------- +\subsection{Quick Start} + +The package is accompanied with a Python script. You should read +\Fullref{sec:python} for the Python preparations. +The package can be used in three ways: +\begin{itemize} +\item Completely without the Python script. + This is not recommended, because the usage will be quite restricted. +\item With Python script, but without map tile download. + There is no usage restriction, but you have to create all content yourself. + To prevent map tile download, set + \begin{dispListing} + \mermapset{supply/target=none} + \end{dispListing} +\item With Python script and map tile download. + You need permission and access to a map tile server. + \Fullref{sec:maptileserver} lists a selection of servers with free + access (some require registration of an API key). +\end{itemize} + +After Python is prepared, you may try to compile +|mercatormap-example.tex| (found in the documentation directory) +which contains a map of Bavaria with map tile download. +\Fullref{sec:examples} exhibits further examples which may serve as +tutorials what can be done. After the examples you find the reference +manual for the package. + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Installation of Python and Packages}\label{sec:python} + +A Python~3 script is part of the |mercatormap| package. +The main purpose of this script is to download selected map tiles for +the maps of the document. Also, some coordinate system computation is +done by this script. + +\subsubsection{Python 3} +Python 3 is a required prerequisite and can be downloaded from\\ +\url{https://www.python.org/downloads/}\\ +On systems like Linux Python is typically already installed.\par +To test your installation, type into a command or terminal window: +\begin{dispListing} + python --version +\end{dispListing} +This should give a version number starting with 3. Otherwise, try +\begin{dispListing} + python3 --version +\end{dispListing} +If this is successful, \refKey{/mermap/python} has to be adapted to |python3| + +\subsubsection{Python Packages} +The Python packages |Pillow| (\url{https://pypi.org/project/Pillow/}) +and |requests| (\url{https://pypi.org/project/requests/}) have to be present. +With some luck, they are already installed. With +\begin{dispListing} + pip3 list +\end{dispListing} +and/or +\begin{dispListing} + pip3 list --user +\end{dispListing} +the installed packages are listed. If |Pillow| and |requests| are not +among these package, they have to be added by +\begin{dispListing} + pip3 install --user Pillow + pip3 install --user requests +\end{dispListing} +or +\begin{dispListing} + pip3 install Pillow + pip3 install requests +\end{dispListing} +The second choice needs administrative rights and may give conflicts +with package managers. Pythonians know furthers installation methods. + +\subsubsection{Document Setup} +For your map document you need the following: +\begin{itemize} +\item Add \refCom{mrcactivatescript} to the document preamble. + Without this command, the script is not active. +\item Compile the map document with the |--shell-escape| compiler option. + This allows to execute external programs like the Python script.\\ + \textbf{Be aware that |-||-shell-escape| should only be used + with trusted documents. Note that external programs can do anything!} +\end{itemize} + + + + +%\subsection{Tutorial: Map without external Graphics} + + +%\subsection{Tutorial: Map with downloaded Map Tiles} diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.limitations.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.limitations.tex new file mode 100644 index 00000000000..7529f8db199 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.limitations.tex @@ -0,0 +1,300 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Limitations and Caveats}% + +%------------------------------------------------------------------------------- +\subsection{No Polar Regions} + The standard Mercator projection is not suited for north or south polar + regions. + The Web Mercator projections only covers + positions between \mrcformlat{-85.0511} and \mrcformlat{85.0511} + with map tiles. Equally, the |mercatormap| package does only provide support for + this area. + + If your map overlaps to south of \mrcformlat{-85.0511} or to north of \mrcformlat{85.0511}, + compiler errors are possible because of internal computation limitations. + In any case, there are no map tiles. + + \tikzsetnextfilename{limit_polar}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[type=reference,latitude=-85.0511,longitude=0,zoom=3, + source=opentopomap, + tex width=\linewidth, tex height=8cm]{} + \mrcdrawmap + \node[above=4mm,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \mrcdrawnetwork[network pieces=10,network distance=10mm] + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \mrcmarker{type=pin,position=-85.0511:0, + contents={End of the mapped world}} + \end{tikzpicture} + \end{dispExample} + +%------------------------------------------------------------------------------- +\clearpage +\subsection{International Dateline (180th Meridian)}\label{sec:dateline} + If your map includes the 180th meridian (more or less the international dateline), + remember that the eastern hemisphere lies \emph{west} and + the western hemisphere lies \emph{east} for your map. + Consider the following example displaying Vladivostok and Anchorage. + Here, \refKey{/mermap/supply/west} is set to \ang{130}\,E (|130|) + and \refKey{/mermap/supply/east} is set to \ang{149}\,W (|211| instead of |-149|). + + There is some automatic correction for positions to fit inside the + defined map (see Anchorage in the example below), but + \emph{west} should be lower than \emph{east}. + + \tikzsetnextfilename{limit_dateline}% + \begin{dispExample} + % \mrcsetapikey{openrouteservice}{YOUR-API-KEY} % registered key + \begin{tikzpicture} + \mrcmap[type=areafit,tex width=\linewidth,tex height=8cm, + source=openrouteservice mapsurfer, + south=42,north=62,west=130,east=-149+360]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \draw (mrcmap.south west) rectangle (mrcmap.north east); + \draw (mrc cs:lat=\mrcmapsouth,lon=180) + -- node[sloped,above] {180th meridian} + node[sloped,below,red] {add 360 to longitude for eastern border} + (mrc cs:lat=\mrcmapnorth,lon=180); + \mrcmarker{type=pin,position=61.22:-149.88,contents={Anchorage}} + \mrcmarker{type=pin,position=43.12:131.9, contents={Vladivostok}} + \end{tikzpicture} + \end{dispExample} + +%------------------------------------------------------------------------------- +\clearpage +\subsection{Very small Scale Maps} + If a map has a very small scale, a coordinate point may appear more than once + on the map. But, the map coordinates of this package will only + pilot to a single point: + + \tikzsetnextfilename{limit_small_scale_1}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[type=reference,latitude=48.14,longitude=11.57, + source=opentopomap, + tex width=\linewidth,tex height=4cm,zoom=1]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; \mrcclipmap + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \mrcmarker{type=pin,position=61.22:-149.88,contents={Anchorage}} + \mrcmarker{type=pin,position=43.12:131.9,contents={Vladivostok}} + \end{tikzpicture} + \end{dispExample} + + You cannot trust too much in figures from + \refCom{mrcprettymapscale}, + \refCom{mrcprettymapwidth}, + \refCom{mrcprettymapheight}, etc + for large and medium scale maps. + For small scale maps, these figures are worse and even misleading. + Better do not use them: + + \tikzsetnextfilename{limit_small_scale_2}% + \begin{dispExample} + \mermapset{supply/source=opentopomap} + \begin{tikzpicture} + \mrcmap[type=reference,latitude=48.14,longitude=11.57, + tex width=\linewidth,tex height=6cm,zoom=2]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; \mrcclipmap \mrcdrawinfo + \end{tikzpicture} + \end{dispExample} + + +%------------------------------------------------------------------------------- +\clearpage +\subsection{Zoom is not Scale} + + Using the same zoom value for different latitudes can give completely + different scales. The following example for Oslo and Rio de Janeiro + at zoom 12 scales to 1:151000 and otherwise 1:277000. + \tikzexternaldisable + + \tikzsetnextfilename{limit_zoom_scale_1} + \begin{dispExample} + \mermapsetsupply{source=stamen terrain, type=reference, zoom=12, + tex width=7cm, tex height=5cm} + \begin{tikzpicture} + \mrcmap[latitude=59.91,longitude=10.75]{oslo1} \mrcdrawmap + \end{tikzpicture}\hfill\begin{tikzpicture} + \mrcmap[latitude=-22.91,longitude=-43.20]{rio1} \mrcdrawmap + \end{tikzpicture} + \begin{center}\fontsize{7pt}{7pt}\sffamily\mrcmapattribution\end{center} + \end{dispExample} + + Same example again, but with \refKey{/mermap/flex scale} which gives + 1:150000 for both cities and comparable maps. + + \tikzsetnextfilename{limit_zoom_scale_2} + \begin{dispExample} + \mermapsetsupply{source=stamen terrain, type=reference} + \begin{tikzpicture} + \mrcmap[latitude=59.91,longitude=10.75, flex reference scale=150000, + tex width=7cm, tex height=5cm]{oslo2} \mrcdrawmap + \end{tikzpicture}\hfill\begin{tikzpicture} + \mrcmap[latitude=-22.91,longitude=-43.20, flex reference scale=150000, + tex width=7cm, tex height=5cm]{rio2} \mrcdrawmap + \end{tikzpicture} + \begin{center}\fontsize{7pt}{7pt}\sffamily\mrcmapattribution\end{center} + \end{dispExample} + + +%------------------------------------------------------------------------------- +\clearpage +\subsection{Distances} + +There are at least three kinds of distance measures between two points +on the map: +\begin{itemize} +\item Measure the distance with a ruler on the printed (or displayed) map + and multiply with the \refCom{mrcmapscaledenominator}. + Note that the map scale denominator is only (approximately) correct + for the map center. +\item Compute the loxodromic distance, e.g. with \refCom{mrcstoreloxodistance} + which gives the (approximated) distance following a loxodrome. + On our Mercator map, this would be equal to the ruler method from above, + if the map scale would be constant. +\item Compute the orthodromic distance, e.g. with \refCom{mrcstoreorthodistance} + which gives the (approximated) shortest distance following an orthodrome. +\end{itemize} +Apart from the approximate nature of the implementation, these distances +are expected to be quite identical for large scale maps, but not for +(very) small scale maps. + +\clearpage +\tikzsetnextfilename{limit_distance1}% +\begin{dispExample*}{} +\begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{fraunberg}{48.3685075}{11.9894209} + \mrcmap[type=reference, named position=munich, + flex reference scale=1000000, + source=topplusopen web, + tex width=\linewidth, tex height=10cm]{} + \mrcdrawmap + \node[below left,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south east) + {\mrcmapattribution}; + \node[below right,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south west) + {\mrcprettymapscale}; + \mrcclipmap + \path[draw] (\mrcNPcs{munich}) circle (\mrckmtotex{40}); + \node[above,fill=white,opacity=0.85,text opacity=1] + at ([yshift=\mrckmtotex{40}]\mrcNPcs{munich}) {\SI{40}{km}}; + \draw[blue,very thick] (\mrcNPcs{munich}) -- (\mrcNPcs{fraunberg}); + \mrcNPdraworthodrome[red,very thick] {munich}{fraunberg} + \path (\mrcNPcs{munich}) -- + node[sloped,above=3mm,red,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyorthodistance{munich}{fraunberg} } + node[sloped,below=3mm,blue,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyloxodistance{munich}{fraunberg} } + (\mrcNPcs{fraunberg}); + \mrcmarker{type=pin,named position=munich,contents={M\"unchen}} + \mrcmarker{type=pin,named position=fraunberg,contents={Fraunberg}} +\end{tikzpicture} +\end{dispExample*} + +\clearpage +The next example gives notable different distances. The aberration is +dependent from the center angle. + +\tikzsetnextfilename{limit_distance2}% +\begin{dispExample*}{breakable} +\begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{barcelona}{41.3947688}{2.0787285} + \mrcmap[type=reference, named position=munich, + flex reference scale=25000000, + source=topplusopen web, + tex width=\linewidth, tex height=10cm]{} + \mrcdrawmap + \node[below left,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south east) + {\mrcmapattribution}; + \node[below right,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south west) + {\mrcprettymapscale}; + \mrcclipmap + \path[draw] (\mrcNPcs{munich}) circle (\mrckmtotex{1000}); + \node[above,fill=white,opacity=0.85,text opacity=1] + at ([yshift=\mrckmtotex{1000}]\mrcNPcs{munich}) {\SI{1000}{km}}; + \draw[blue,very thick] (\mrcNPcs{munich}) -- (\mrcNPcs{barcelona}); + \mrcNPdraworthodrome[red,very thick] {munich}{barcelona} + \path (\mrcNPcs{munich}) -- + node[sloped,above=3mm,red,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyorthodistance{munich}{barcelona} } + node[sloped,below=3mm,blue,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyloxodistance{munich}{barcelona} } + (\mrcNPcs{barcelona}); + \mrcmarker{type=pin,named position=munich,contents={M\"unchen}} + \mrcmarker{type=pinflip,named position=barcelona,contents={Barcelona}} +\end{tikzpicture} +\end{dispExample*} + + +\clearpage +The following small scale example contains unacceptable deviations from +the displayed circle radius of \SI{3000}{\kilo\meter}. The aberration is +highly dependent from the center angle. For such small scale maps, +displaying a distance circle should be avoided. + + +\tikzsetnextfilename{limit_distance3}% +\begin{dispExample*}{breakable} +\begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{neskaup}{65.1446431}{-13.7420082} + \mrcNPdef{atyrau}{47.0971204}{51.866263} + \mrcNPdef{dakhla}{24.2026691}{-15.4883971} + \mrcmap[type=reference, named position=munich, + flex reference scale=75000000, + source=topplusopen web, + tex width=\linewidth, tex height=10cm]{} + \mrcdrawmap + \node[below left,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south east) + {\mrcmapattribution}; + \node[below right,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south west) + {\mrcprettymapscale}; + \mrcclipmap + \path[draw] (\mrcNPcs{munich}) circle (\mrckmtotex{3000}); + \node[above,fill=white,opacity=0.85,text opacity=1] + at ([yshift=\mrckmtotex{3000}]\mrcNPcs{munich}) {\SI{3000}{km}}; + \draw[blue,very thick] (\mrcNPcs{munich}) -- (\mrcNPcs{neskaup}); + \mrcNPdraworthodrome[red,very thick] {munich}{neskaup} + \path (\mrcNPcs{munich}) -- + node[sloped,above=3mm,red,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyorthodistance{munich}{neskaup} } + node[sloped,below=3mm,blue,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyloxodistance{munich}{neskaup} } + (\mrcNPcs{neskaup}); + \draw[blue,very thick] (\mrcNPcs{munich}) -- (\mrcNPcs{atyrau}); + \mrcNPdraworthodrome[red,very thick] {munich}{atyrau} + \path (\mrcNPcs{munich}) -- + node[sloped,above=3mm,red,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyorthodistance{munich}{atyrau} } + node[sloped,below=3mm,blue,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyloxodistance{munich}{atyrau} } + (\mrcNPcs{atyrau}); + \draw[blue,very thick] (\mrcNPcs{munich}) -- (\mrcNPcs{dakhla}); + \mrcNPdraworthodrome[red,very thick] {munich}{dakhla} + \path (\mrcNPcs{munich}) -- + node[sloped,above=3mm,red,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyorthodistance{munich}{dakhla} } + node[sloped,below=3mm,blue,fill=white,opacity=0.85,text opacity=1] + { \mrcNPprettyloxodistance{munich}{dakhla} } + (\mrcNPcs{dakhla}); + \mrcmarker{type=pinflip,named position=munich,contents={M\"unchen}} + \mrcmarker{type=pin,named position=neskaup,contents={Neskaupsta\dh ur}} + \mrcmarker{type=pin,named position=atyrau,contents={Atyrau}} + \mrcmarker{type=pinflip,named position=dakhla,contents={Ad-Dakhla}} +\end{tikzpicture} +\end{dispExample*} diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.maptiles.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.maptiles.tex new file mode 100644 index 00000000000..c5289f537c2 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.maptiles.tex @@ -0,0 +1,934 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Automated Map Definition and Map Tiles}\label{sec:automated_map}% + +\begin{center} +\begin{tikzpicture}[every node/.style={minimum width=3cm,minimum height=2cm, + align=center,fill=red!5,draw=red!50!gray}] +\node (A) {Map Supply}; +\node[at=(A.east),right=8mm] (B) {Python Script}; +\node[at=(B.east),right=8mm] (C) {Map Apply}; +\node[at=(C.east),right=8mm] (D) {Map Drawing}; +\begin{scope}[->,very thick,Blue_Gray] +\draw (A)--(B); \draw (B)--(C); \draw (C)--(D); +\end{scope} +\end{tikzpicture} +\end{center} + +As illustrated above, the script aided map definition is a process with +several stages. + +\begin{itemize} +\item Map Supply: \refCom{mrcsupplymap} is the replacement of the manual setup by + \refCom{mrcdefinemap}. Actually, it is quite similar to \refCom{mrcdefinemap}. + With \refCom{mrcsupplymap} directions for the following Python script + are formulated. +\item Python Script: The script is executed by \refCom{mrcsupplymap} during + compilation. It does some coordinate system computations and downloads + map tiles from a Web server. Finally, it writes a map definition into + a file \meta{id}|.def|. +\item Map Apply: \refCom{mrcapplymap} reads and applies the + map definition from \meta{id}|.def|. +\item Map Drawing: Afterwards, the map can be drawn by \refCom{mrcdrawmap} + and other commands. +\end{itemize} + +A map can be applied more than once, e.g. reused later in the document. +If this is not needed, map supply and map apply can be combined by +\refCom{mrcmap}. + + +%------------------------------------------------------------------------------- +\subsection{Script Activation} + +Remember to install Python beforehand, see \Fullref{sec:python}. + +\begin{docCommand}{mrcactivatescript}{} + Use this inside the preamble of your document to activate the + accompanying Python script. + Without this command, the script is not executed! + If the document is final (or the maps are final), + this line could be removed and the document + should be compilable without script. +\end{docCommand} + + +\begin{docMrcKey}{python}{=\meta{python}}{no default, initially |python|} + Names the Python~3 interpreter as \meta{python}. If your Python~3 interpreter + is not called |python|, but e.g. |python3|, then use + \begin{dispListing} + \mermapset{python=python3} + \end{dispListing} +\end{docMrcKey} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Map Types} +Currently, there are three methods provided how a map is computed by the +accompanying Python script. The technical background is documented in +\cite[Section~5]{Sturm:2020}. + +\begin{enumerate} +\item \refKey{/mermap/supply/type}|=|\docValue{reference}: + \tcbsidebyside[sidebyside adapt=left,blankest,grow to left by=1cm] + { + \tikzexternaldisable + \begin{tikzpicture} + \useasboundingbox (0,0) rectangle (3,2); + \path[draw,fill=yellow!10] (0,0) rectangle (3,2); + \path[fill=red] (1.5,1) circle [radius=1mm]; + \end{tikzpicture} + }{ + The default method determines the map dimensions from a reference + position and given document map dimensions. + Also, a zoom level \refKey{/mermap/supply/zoom} + is required which relates to the Web Mercator map tile covering of the Earth. + A higher zoom level gives a growing number of smaller map tiles. + Alternative to the zoom level, a \meta{scale denominator} can be provided + by \refKey{/mermap/supply/flex area scale}, \refKey{/mermap/flex scale} + or \refKey{/mermap/supply/flex reference scale} which determines + the zoom level implicitly. + As default, the reference position is the center of the map, but can be + aligned at the map borders. This method is quite safe to use and could + be the preferred one for many applications like showing the neighborhood + of a route target. + Finding the best reference point for depicting a certain area could + be more tricky. + } + +\item \refKey{/mermap/supply/type}|=|\docValue{areafit}: + \tcbsidebyside[sidebyside adapt=left,blankest,grow to left by=1cm] + { + \tikzexternaldisable + \begin{tikzpicture} + \useasboundingbox (0,0) rectangle (3,2); + \path[draw,fill=yellow!10] (0,0) rectangle (3,2); + \path[draw=red,line width=0.5mm] (0.2,0.5) rectangle (2.8,1.5); + \end{tikzpicture} + } + { + The map dimensions are determined by an area with + latitude and longitude boundaries which is fitted into given + document map dimensions. The zoom level is computed accordingly + for a fixed document tile size or by \refKey{/mermap/supply/flex area fit}. + In any case, the map contains the target area plus some protrusion. + This method is also quite safe to use and may be + the preferred one for many applications like showing a map which contains + a bunch of markers (e.g. for locations of universities). + If the map borders are required to exactly meet the boundaries, + the third method can be regarded. + } + +\item \refKey{/mermap/supply/type}|=|\docValue{boundaries}: + \tcbsidebyside[sidebyside adapt=left,blankest,grow to left by=1cm] + { + \tikzexternaldisable + \begin{tikzpicture} + \useasboundingbox (0,0) rectangle (3,2); + \path[draw=red,line width=0.5mm,fill=yellow!10] (0.2,0.5) rectangle (2.8,1.5); + \end{tikzpicture} + }{ + The most obvious method determines the map dimensions from + latitude and longitude boundaries. For this, a corresponding zoom level + \refKey{/mermap/supply/zoom} + is required which relates to the Web Mercator map tile covering of the Earth. + Alternative to the zoom level, a \meta{scale denominator} can be provided + by \refKey{/mermap/supply/flex area scale} + or \refKey{/mermap/supply/flex reference scale} which determines + the zoom level implicitly. + Note that a too high zoom level imposes the risk of downloading an unwanted + high quantity of map tiles resulting in a much too large document map. + Therefore, this most obvious method is \emph{not recommended} for the + beginner and may be explored after some experience. + } +\end{enumerate} + + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Map Supply} + +\begin{docCommand}{mrcsupplymap}{\oarg{options}\marg{definition}} + The \meta{options} provide parameters for the Python~3 script to supply all + materials for a map. + All options share the common prefix |/mermap/supply/|.\par + The map is identified by\\ + \meta{id}=\refKey{/mermap/definition prefix}+\meta{definition}\\ + for later drawing. + This identifier \meta{id} has to be unique for the document. + It corresponds to generated files \meta{id}|.def|, \meta{id}|.md5|, and + possibly \meta{id}|.png|. + Do not use spaces or special characters like umlauts for \meta{definition}. + \par + If \refCom{mrcactivatescript} is used inside the preamble, + \refCom{mrcsupplymap} executes the Python~3 script, otherwise nothing happens. +\end{docCommand} + + +\begin{docCommand}{mermapsetsupply}{\marg{options}} + Sets \meta{options} for all following maps inside the current \TeX\ group. + All options share the common prefix |/mermap/supply/|, e.g. for setting + \refKey{/mermap/supply/type} use + \begin{dispListing} + \mermapsetsupply{type=reference} + \end{dispListing} + Also see \refCom{mermapset} and \refCom{mermapsetmarker}. +\end{docCommand} + + +\begin{docMrcKey}{definition prefix}{=\meta{definition prefix}}{no default, initially |maps/|} + Prefix for map identifiers and generated map files, see \refCom{mrcsupplymap} + and \refCom{mrcapplymap}. + Note that \refKey{/mermap/definition prefix} is not to be used inside + the option list for \refCom{mrcsupplymap}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/type}{=\meta{type}}{no default, initially |reference|} + The \meta{type} defines the basic computation for the map. Feasible values are + \begin{itemize} + \item\docValue{reference}: \flqq map with reference position\frqq\\ + The map is constructed from a given reference position + \refKey{/mermap/supply/latitude},\\ + \refKey{/mermap/supply/longitude},\\ + a zoom level \refKey{/mermap/supply/zoom},\\ + map dimensions\\ + \refKey{/mermap/supply/width},\\ + \refKey{/mermap/supply/height},\\ + and alignment \refKey{/mermap/supply/align}. + \item\docValue{areafit}: \flqq map fitting an area\frqq\\ + The map is constructed from a given area boundaries\\ + \refKey{/mermap/supply/west},\\ + \refKey{/mermap/supply/east},\\ + \refKey{/mermap/supply/north},\\ + \refKey{/mermap/supply/south},\\ + map dimensions\\ + \refKey{/mermap/supply/width},\\ + \refKey{/mermap/supply/height},\\ + and alignment \refKey{/mermap/supply/align}. + \item\docValue{boundaries}: \flqq map with boundaries\frqq\\ + The map is constructed from given boundaries\\ + \refKey{/mermap/supply/west},\\ + \refKey{/mermap/supply/east},\\ + \refKey{/mermap/supply/north},\\ + \refKey{/mermap/supply/south},\\ + and zoom level \refKey{/mermap/supply/zoom}. + \end{itemize} +\end{docMrcKey} + +\begin{docMrcKey}{supply/zoom}{=\meta{setup zoom}}{no default, initially |9|} + Map tile zoom factor alias $z$ coordinate of the map tiles. + Used for map types \docValue{boundaries} and \docValue{reference}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/north}{=\meta{setup north latitude}}{no default, initially |50|} + Northern latitude degree, possibly negative for the southern hemisphere, + lower than $90$ but always larger than \refKey{/mermap/supply/south}. + Used for map types \docValue{boundaries} and \docValue{areafit}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/south}{=\meta{setup south latitude}}{no default, initially |48|} + Southern latitude degree, possibly negative for the southern hemisphere, + larger than $-90$ but always lower than \refKey{/mermap/supply/north}. + Used for map types \docValue{boundaries} and \docValue{areafit}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/west}{=\meta{setup west longitude}}{no default, initially |11|} + Western longitude degree, possibly negative for the western hemisphere, + possibly shifted periodically, but always lower than \refKey{/mermap/supply/east}. + Used for map types \docValue{boundaries} and \docValue{areafit}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/east}{=\meta{setup east longitude}}{no default, initially |13|} + Eastern longitude degree, possibly negative for the western hemisphere, + possibly shifted periodically, but always larger than \refKey{/mermap/supply/west}. + Used for map types \docValue{boundaries} and \docValue{areafit}. +\end{docMrcKey} + + +\begin{docMrcKey}{supply/area}{=\marg{comma separated list of named positions}}{no default} + Sets + \refKey{/mermap/supply/north}, \refKey{/mermap/supply/south}, + \refKey{/mermap/supply/west}, \refKey{/mermap/supply/east} + according to the given \meta{comma separated list of named positions}, i.e. + the described area contains all these positions. + Note that you need at least two points inside the list. + Also note to take special care, if the international dateline is on your + resulting map, see \Fullref{sec:dateline}. + Used for map types \docValue{boundaries} and \docValue{areafit}. +\end{docMrcKey} + + +\begin{docMrcKey}{supply/add area}{=\marg{comma separated list of named positions}}{no default} + Nearly identical to \refKey{/mermap/supply/area}, but + the given \meta{comma separated list of named positions} + does not reset the current area, i.e. the positions are added to the + current area which possibly grows to fit all positions. + Used for map types \docValue{boundaries} and \docValue{areafit}. +\end{docMrcKey} + + +\begin{docMrcKey}{supply/area to reference}{}{no value, initially unset} + The map settings + \refKey{/mermap/supply/north}, \refKey{/mermap/supply/south}, + \refKey{/mermap/supply/west}, \refKey{/mermap/supply/east} + are taken to compute the map center. This center position is saved + to \refKey{/mermap/supply/latitude} and \refKey{/mermap/supply/longitude}. + Used for map type \docValue{reference}. +\end{docMrcKey} + + + +\begin{docMrcKey}{supply/latitude}{=\meta{setup latitude}}{no default, initially |49|} + Latitude degree of a reference point, possibly negative for the southern hemisphere. + Used for map type \docValue{reference}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/longitude}{=\meta{setup longitude}}{no default, initially |12|} + Longitude degree of a reference point, possibly negative for the western hemisphere. + Used for map type \docValue{reference}. +\end{docMrcKey} + + +\begin{docMrcKey}{supply/position}{=\meta{setup latitude}:\meta{setup longitude}}{no default, initially |49:12|} + Latitude degree and longitude of a reference point. + Used for map type \docValue{reference}. +\end{docMrcKey} + + +\begin{docMrcKey}{supply/named position}{=\meta{name}}{style, no default} + The \emph{named position} given by \meta{name} describes + a reference point, see \Fullref{sec:names_positions}. + Used for map type \docValue{reference}. +\end{docMrcKey} + + +\pagebreak +\begin{docMrcKey}{supply/width}{=\meta{setup width in tiles}}{no default, initially |4|} + Width of the map as multiplicity of map tiles. + Used for map types \docValue{reference} and \docValue{areafit}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/tex width}{=\meta{width}}{style, no default} + Width of the map as \TeX\ dimension. + This is a style to compute \refKey{/mermap/supply/width} according to + the current \refKey{/mermap/tile size}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/height}{=\meta{setup height in tiles}}{no default, initially |4|} + Height of the map as multiplicity of map tiles. + Used for map types \docValue{reference} and \docValue{areafit}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/tex height}{=\meta{width}}{style, no default} + Height of the map as \TeX\ dimension. + This is a style to compute \refKey{/mermap/supply/height} according to + the current \refKey{/mermap/tile size}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/align}{=\meta{setup alignment}}{no default, initially |center|} + Alignment of reference point or area for map types \docValue{reference} and \docValue{areafit}. + Feasible values are + \docValue{northwest}, \docValue{north}, \docValue{northeast}, \docValue{west}, + \docValue{center}, \docValue{east}, \docValue{southwest},\docValue{south}, \docValue{southeast}. +\end{docMrcKey} + +\begin{docMrcKey}{supply/target}{=\meta{setup target}}{no default, initially |tiles|} + Defines the type of output for the Python~3 script. Feasible values are: + \begin{itemize} + \item\docValue{none}: No tiles are downloaded and no merged map is generated, just map computation. + This is the fastest method and needs no tile supplier. + \item\docValue{tiles}: Download map tiles from a tile map service (TMS) \refKey{/mermap/supply/url}. + Compilation of a document with map tile takes longer than compilation + with a merged map and transparency should not be used with tiles, + but the resulting document is smaller than a document with merged maps. + \item\docValue{mergedmap}: Download map tiles from a tile map service (TMS) + \refKey{/mermap/supply/url} and merge them into a single map picture. + This speeds compilation and allows transparency effects, but + the resulting document is possibly larger than a document with map tiles, + because map tiles often are optimized 8-bit image files while the merged + image is a 24-bit PNG file. Additionally, synergy effects of using the same map tiles + for different maps are lost. + Also, since the pixel map is clipped to full pixels, the resulting map + may differ (shift/size) from the more accurate tile representation by + one pixel. + \item\docValue{wmsmap}: Download a single map from a web map service (WMS) + \refKey{/mermap/supply/url}. Internally, the package treats a WMS like + a tile map service including all tile calculations. Actually, a single + file is downloaded. + \end{itemize} +\end{docMrcKey} + + +\clearpage +\begin{docMrcKey}{supply/url}{=\meta{setup URL}}{no default, initially empty} + Here, the url format with placeholder |{z}{x}{y}| for map tile download is defined. + \textbf{Be sure that you have the permission to download, save, and use + the map tiles from that URL. Illegal downloads are not endorsed in any + way.} + \begin{dispListing} + url={https://abc.efg.hij/{z}/{x}/{y}.png?apikey=12345678}, + \end{dispListing} + See \Fullref{sec:maptileserver} for predefined URLs. +\end{docMrcKey} + + +\begin{docMrcKey}{supply/url with api key}{=\marg{prefix}\marg{name}\marg{postfix}}{no default} + This is an alternative version of \refKey{/mermap/supply/url}. + The URL is constructed from some fixed \meta{prefix} and \meta{postfix} with + an API key in between. The API key is retrieved by \meta{name} from a + repository filled by \refCom{mrcsetapikey}. + \begin{dispListing} + url={https://abc.efg.hij/{z}/{x}/{y}.png?apikey=}{myservice}{}, + \end{dispListing} + See \Fullref{sec:maptileserver} for predefined URLs. +\end{docMrcKey} + + +\begin{docCommand}{mrcsetapikey}{\marg{name}\marg{value}} + Stores an API key \meta{value} for access with the given \meta{name}. + Typically, \meta{value} is a received ID from a map tile service provider + after personal registration. \meta{name} is a placeholder which is used + inside \refKey{/mermap/supply/url with api key} to mark the insertion + point for the API key. + \begin{dispListing} + \mrcsetapikey{myservice}{....K942XY....} + \end{dispListing} +\end{docCommand} + + + +\begin{docMrcKey}{supply/attribution}{=\meta{attribution text}}{no default, initially empty} + Attribution text for the map source. Typically, it acknowledges the copyright + of the map data provider. It may contain hyperlinks. + It is used to set up \refKey{/mermap/mapdef/attribution} afterwards + and it is accessible as \docAuxCommand{mrcmapattribution} (use read-only).\par + For technical reasons, do not use \verb+"+. \docAuxCommand{mrcumlaut} + may be used for masking umlauts, e.g. use \verb+\mrcumlaut{u}+ instead of + \verb+\"{u}+, but umlauts can also be used directly, e.g. as UTF-8 coded characters. +\end{docMrcKey} + +\begin{docMrcKey}{supply/attribution print}{=\meta{attribution text}}{no default, initially empty} + Attribution text for the map source. + In contrast to \refKey{/mermap/supply/attribution} it is intended for media + that does not support hyperlinks like printed posters, books, etc. + It is used to set up \refKey{/mermap/mapdef/attribution print} afterwards + and it is accessible as \docAuxCommand{mrcmapattributionprint} (use read-only). +\end{docMrcKey} + + +\begin{docMrcKey}{supply/basename}{=\meta{setup tile base name}}{no default, initially \texttt{tiles/tile}} + Prefix for local tile files, e.g. '|tiles/map|' for '|tiles/map_10_10_10.png|'. +\end{docMrcKey} + + +\clearpage +\begin{docMrcKey}{supply/flex reference scale}{=\meta{scale denominator}}{no default} + With the given \meta{scale denominator}, an appropriate \refKey{/mermap/supply/zoom} + and \refKey{/mermap/tile size} is computed. Note that + the \meta{scale denominator} + always applies to the current \refKey{/mermap/supply/latitude} + and is used for map type \docValue{boundaries} and \docValue{reference}. + For example, if the reference point is on the north side of the map, + also the \meta{scale denominator} + applies to the most northern latitude. + + Note to take special care to the order of the options. + \begin{itemize} + \item The reference point has to be set \emph{before} + \refKey{/mermap/supply/flex reference scale}, e.g. by + \refKey{/mermap/supply/latitude}, \refKey{/mermap/supply/position}, + \refKey{/mermap/supply/named position}. + \item \refKey{/mermap/supply/tex height}, \refKey{/mermap/supply/tex width} + (only for map type \docValue{reference}) + have to be set \emph{after} \refKey{/mermap/supply/flex reference scale}, + because the \refKey{/mermap/tile size} is adapted. + \end{itemize} + Also see \refKey{/mermap/flex tile size}, \refKey{/mermap/flex zoom}, + and \refKey{/mermap/flex scale}. +\tikzsetnextfilename{maptiles_flex_reference_scale}% +\begin{dispExample} +\begin{tikzpicture} + \mrcmap[type=reference,latitude=48.14,longitude=11.57, + flex reference scale=250000, + source=opentopomap, + tex width=\linewidth,tex height=5cm]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \node[below left=2mm,align=right,fill=white,fill opacity=0.5, + text opacity=1] at (mrcmap.north east) {scale \mrcprettymapscale}; +\end{tikzpicture} +\end{dispExample} +\end{docMrcKey} + + +\begin{docMrcKey}{supply/flex area scale}{=\meta{scale denominator}}{no default} + This is a shortcut for setting \refKey{/mermap/supply/area to reference} + and \refKey{/mermap/supply/flex reference scale}=\meta{scale denominator}. + Used for map type \docValue{boundaries} and \docValue{reference}. + + Note to take special care to the order of the options. + \begin{itemize} + \item The reference point has to be set \emph{before} + \refKey{/mermap/supply/flex area scale}. + \item \refKey{/mermap/supply/tex height}, \refKey{/mermap/supply/tex width} + (only for map type \docValue{reference}) + have to be set \emph{after} \refKey{/mermap/supply/flex reference scale}. + \end{itemize} +\end{docMrcKey} + + +\clearpage +\begin{docMrcKey}{supply/flex area fit}{\colOpt{=\meta{size}}}{default |0pt|} + This key can be used for map type \docValue{areafit} as \emph{final} + option \emph{after} all other options. + It applies a fine tuning to \refKey{/mermap/tile size}, + \refKey{/mermap/supply/width}, and \refKey{/mermap/supply/height} such + that the defined area fits exactly into the map region. + If a \meta{size} is specified, width and height are reduced for the + calculation by this \meta{size}, e.g. \meta{size}|=1cm| ensures a + border of |5mm| on each side. + Also see \refKey{/mermap/flex tile size} and \refKey{/mermap/flex zoom}. + +\tikzsetnextfilename{maptiles_flex_area_fit}% +\begin{dispExample} +\begin{tikzpicture} + \mrcNPdef{munich}{48.14}{11.58} + \mrcNPdef{rio}{-22.91}{-43.20} + \mrcNPdef{newyork}{40.71}{-74.01} + \mrcmap[ type = areafit, area = {munich,rio,newyork}, + source=topplusopen web grau, + tex width=\linewidth, tex height=7cm, + flex area fit=1cm ]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \draw[yellow] ([xshift=5mm,yshift=5mm]mrcmap.south west) rectangle + ([xshift=-5mm,yshift=-5mm]mrcmap.north east); + \draw[red,fill=red!50!gray!50!white,fill opacity=0.25] + (\mrcNPcs{newyork}) -- (\mrcNPcs{rio}) -- (\mrcNPcs{munich}) -- cycle; +\end{tikzpicture} +\end{dispExample} +\end{docMrcKey} + + + + +\clearpage +\begin{docMrcKey}{supply/pixel}{=\meta{setup pixel size}}{no default, initially |256|} + Pixel width (and height) of a tile. It is especially needed for + target \docValue{mergedmap} and also \docValue{wmsmap}. + For \docValue{wmsmap}, it is multiplied with a pseudo tile calculation + to compute the actual picture size to download. +\end{docMrcKey} + + +\begin{docMrcKey}{supply/dpi}{=\meta{dpi value}}{style, no default} + This style sets \refKey{/mermap/supply/pixel} such that the given \meta{dpi value} + is resulting (approximately). + \begin{itemize} + \item Note that this only applies for WMS Servers and not for + TMS (Tile Map Service) Servers, + because there \refKey{/mermap/supply/pixel} is a fixed number depending on + Server settings and cannot be chosen arbitrarily. + \item A high \meta{dpi value} results in large downloaded map files. + If the server does not provide a high resolution map, you will get + unnecessary large files with blurred content. + \item The \meta{dpi value} for TMS data can be changed by adapting + \refKey{/mermap/tile size} or \refKey{/mermap/flex tile size}. + \end{itemize} + +\tikzsetnextfilename{maptiles_dpi_value} +\begin{dispExample} +\begin{tikzpicture} + \mrcmap[type=reference,latitude=48.14,longitude=11.57, + flex reference scale=250000, + source=topplusopen p250, target=wmsmap, dpi=300, + tex width=\linewidth,tex height=5cm]{dpi_value} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); +\end{tikzpicture} +\end{dispExample} + +\end{docMrcKey} + + + + + +%------------------------------------------------------------------------------- +\subsection{Map Apply} + +\begin{docCommand}{mrcapplymap}{\marg{definition}} + A map which is supplied by \refCom{mrcsupplymap} is applied + inside a |tikzpicture| environment by + \refCom{mrcapplymap} where \meta{definition} identifies the map. + \refCom{mrcapplymap} replaces a manual setup by \refCom{mrcdefinemap}. + The same map can be applied more than once inside a document. + Note that applying a map does not mean to draw the map, but to prepare + everything for drawing. +\end{docCommand} + + +\begin{docCommand}{mrcmap}{\oarg{options}\marg{definition}} + This is a combination of + \refCom{mrcsupplymap} with the given \meta{options} + followed immediately by \refCom{mrcapplymap}. + If \meta{definition} is left empty, an automated unique identifier is + inserted. + If a map is to be used just once, \refCom{mrcmap} may be preferred. +\end{docCommand} + + + + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Map Tile Server}\label{sec:maptileserver} + + +To use map tiles with this package you obviously need access to a map tile server. +Thanks to all the many contributors to +\href{https://openstreetmap.org/copyright}{OpenStreetMap}, +map data is free for everyone to use. +\textbf{But, map tile servers based on OpenStreetMap are not necessarily free}. + +A list of online raster tile servers based on OpenStreetMap data is found here:\\ +\url{https://wiki.openstreetmap.org/wiki/Tile_servers} + +\begin{itemize} +\item\bfseries I do not run a map tile server. +\item I do not and cannot grant any permission to access a map tile server. +\item I do not and cannot grant any permission to use map tiles in + private, academic, free, or commercial publications. +\item All operators of map tile servers require to mention an attribution + for their maps. +\end{itemize} + +The following option allows easy usage of very few selected tile servers. +The tile server of \href{https://openstreetmap.org/copyright}{OpenStreetMap} +is not included because of its +\href{https://operations.osmfoundation.org/policies/tiles/}{Tile Usage Policy}. +I am aware that the following list could be enlarged much more, but I do not +want to add more to avoid any legal uncertainties. + +\begin{itemize} +\item\bfseries I will remove an entry immediately, if the tile server operator + asks for it. +\item\mdseries If \textbf{YOU} operate a tile server and you want an entry here, I would be + glad to add it to the following list. +\end{itemize} + +\medskip +\begin{docMrcKey}{supply/source}{=\meta{source}}{style, no default} + This style sets \refKey{/mermap/supply/url}, \refKey{/mermap/supply/attribution},\\ + \refKey{/mermap/supply/attribution print} and \refKey{/mermap/supply/basename}.\\ + Feasible values for \meta{source} are: + %\mermapset{tile size=3.2512cm} + \newcommand{\mapexample}[3][]{% + \begingroup + \mermapset{supply/source=#2}% + \begin{itemize} + \item Required attribution (\docAuxCommand{mrcmapattribution}): + \begin{tcolorbox}[sharp corners,size=fbox,colback=yellow!8,colframe=yellow!80!gray,halign=flush left] + \mrcmapattribution\end{tcolorbox} + \item Required attribution for media without hyperlinks (\docAuxCommand{mrcmapattributionprint}): + \begin{tcolorbox}[sharp corners,size=fbox,colback=yellow!8,colframe=yellow!80!gray,halign=flush left] + \mrcmapattributionprint\end{tcolorbox} + %\par\smallskip\ + \end{itemize} + \endgroup\par\smallskip\tikzsetnextfilename{maptiles_#3}% + \begin{tikzpicture} + \mrcmap[source=#2, + type=reference,latitude=48.14,longitude=11.58,zoom=7, + tex width=\linewidth,tex height=2cm,#1]{#3} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \end{tikzpicture}\par% + }% + \begin{itemize} + + \item\docValue{dummy}:\\ + Dummy tile server at loopback |127.0.0.1| for test purposes. + + \item\docValue{opentopomap}:\\ + Tile server (TMS) of \href{http://opentopomap.org/}{OpenTopoMap}. + \begin{itemize} + \item Usage (German language): \url{https://opentopomap.org/about#verwendung} + \end{itemize} + \mapexample{opentopomap}{opentopomap} + +\clearpage + \item\docValue{openrouteservice mapsurfer}:\\ + Tile server of \href{https://openrouteservice.org/}{OpenRouteService}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{openrouteservice}}\marg{api-key}.\\ + Usage: \url{https://openrouteservice.org/terms-of-service/}\\ + API documentation: \url{https://openrouteservice.org/dev/#/api-docs} + \mapexample{openrouteservice mapsurfer}{openrouteservice_mapsurfer} + + \item\docValue{stamen terrain}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#terrain} + \mapexample{stamen terrain}{stamen_terrain} + + \item\docValue{stamen terrain-background}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#terrain-background} + \mapexample{stamen terrain-background}{stamen_terrain-background} + +\clearpage + \item\docValue{stamen terrain-labels}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#terrain-labels} + \mapexample{stamen terrain-labels}{stamen_terrain-labels} + + \item\docValue{stamen terrain-lines}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#terrain-lines} + \mapexample{stamen terrain-lines}{stamen_terrain-lines} + + \item\docValue{stamen toner}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#toner} + \mapexample{stamen toner}{stamen_toner} + +\clearpage + \item\docValue{stamen toner-lite}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#toner-lite} + \mapexample{stamen toner-lite}{stamen_toner-lite} + + \item\docValue{stamen toner-hybrid}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#toner-hybrid} + \mapexample{stamen toner-hybrid}{stamen_toner-hybrid} + + \item\docValue{stamen toner-background}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#toner-background} + \mapexample{stamen toner-background}{stamen_toner-background} + +\clearpage + \item\docValue{stamen toner-labels}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#toner-labels} + \mapexample{stamen toner-labels}{stamen_toner-labels} + + \item\docValue{stamen toner-lines}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#toner-lines} + \mapexample{stamen toner-lines}{stamen_toner-lines} + + \item\docValue{stamen watercolor}:\\ + Tile server of \href{http://stamen.com}{Stamen Design}.\\ + Usage: \url{http://maps.stamen.com/#watercolor} + \mapexample{stamen watercolor}{stamen_watercolor} + +\clearpage + \item\docValue{thunderforest opencyclemap}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/opencyclemap} + \end{itemize} + \mapexample{thunderforest opencyclemap}{thunderforest_opencyclemap} + + \item\docValue{thunderforest transport}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/transport} + \end{itemize} + \mapexample{thunderforest transport}{thunderforest_transport} + + \item\docValue{thunderforest landscape}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/landscape} + \end{itemize} + \mapexample{thunderforest landscape}{thunderforest_landscape} + +\clearpage + \item\docValue{thunderforest outdoors}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/outdoors} + \end{itemize} + \mapexample{thunderforest outdoors}{thunderforest_outdoors} + + \item\docValue{thunderforest transport-dark}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/transport-dark} + \end{itemize} + \mapexample{thunderforest transport-dark}{thunderforest_transport-dark} + + \item\docValue{thunderforest spinal-map}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/spinal-map} + \end{itemize} + \mapexample{thunderforest spinal-map}{thunderforest_spinal-map} + +\clearpage + \item\docValue{thunderforest pioneer}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/pioneer} + \end{itemize} + \mapexample{thunderforest pioneer}{thunderforest_pioneer} + + \item\docValue{thunderforest mobile-atlas}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/mobile-atlas} + \end{itemize} + \mapexample{thunderforest mobile-atlas}{thunderforest_mobile-atlas} + + \item\docValue{thunderforest neighbourhood}:\\ + Tile server of \href{https://www.thunderforest.com}{Thunderforest}.\\ + A registered \meta{api-key} is needed (free plan available) + which is applied by\\ + \refCom{mrcsetapikey}\brackets{\docValue{thunderforest}}\marg{api-key}. + \begin{itemize} + \item Usage: \url{https://www.thunderforest.com/terms} + \item API documentation: \url{https://www.thunderforest.com/maps/neighbourhood} + \end{itemize} + \mapexample{thunderforest neighbourhood}{thunderforest_neighbourhood} + +\clearpage + \item\docValue{topplusopen web}:\\ + Tile server (TMS) of \href{http://www.bkg.bund.de}{Bundesamt f\"{u}r Kartographie und Geod\"{a}sie}. + \begin{itemize} + \item Covers world / Europe / Germany depending on zoom level + \item Usage (German language): \url{https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html} + \end{itemize} + \mapexample{topplusopen web}{topplusopen_web} + + \item\docValue{topplusopen web grau}:\\ + Tile server (TMS) of \href{http://www.bkg.bund.de}{Bundesamt f\"{u}r Kartographie und Geod\"{a}sie}. + \begin{itemize} + \item Covers world / Europe / Germany depending on zoom level + \item Usage (German language): \url{https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html} + \end{itemize} + \mapexample{topplusopen web grau}{topplusopen_web_grau} + +\end{itemize} + +\clearpage +\begin{tcolorbox}[spartan,colback=white] +The following sources are Web map server (WMS). Therefore, +\refKey{/mermap/supply/target} can only be set to \docValue{wmsmap} +or \docValue{none}. +\end{tcolorbox} + +\begingroup +\ExplSyntaxOn +\int_gzero:N \g_tmpa_int +\NewDocumentCommand \cleanstep {} +{ + \fp_compare:nNnT { \g_tmpa_int-trunc(\g_tmpa_int/3)*3 } = 0 + { + \int_compare:nNnT \g_tmpa_int > 0 + { + \clearpage + } + } + \int_gincr:N \g_tmpa_int +} +\ExplSyntaxOff + + \begin{itemize} + +\foreach \name / \scdenom / \xtra in {p5/5000,p10/10000,p17.5/17500,p25/25000,p50/50000,p100/100000,p250/250000} +{ +\cleanstep + \item\docValue{topplusopen \name}:\\ + Web map server (WMS) of \href{http://www.bkg.bund.de}{Bundesamt f\"{u}r Kartographie und Geod\"{a}sie}. + \begin{itemize} + \item 1:\scdenom, covers Europe / Germany depending on zoom level + \item Usage (German language): \url{https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html} + \end{itemize} + \mapexample[target=wmsmap]{topplusopen \name}{topplusopen_\name} + +\cleanstep + \item\docValue{topplusopen \name\ grau}:\\ + Web map server (WMS) of \href{http://www.bkg.bund.de}{Bundesamt f\"{u}r Kartographie und Geod\"{a}sie}. + \begin{itemize} + \item 1:\scdenom, covers Europe / Germany depending on zoom level + \item Usage (German language): \url{https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html} + \end{itemize} + \def\grau{ grau}% + \mapexample[target=wmsmap]{topplusopen \name\grau}{topplusopen_\name_grau} +} + + \end{itemize} +\endgroup + +\end{docMrcKey} + + + +\begin{docCommand}{mrcnewsupplysource}{\marg{source}\marg{options}} + Adds a new \meta{source} value to \refKey{/mermap/supply/source}. + The \meta{options} should set the keys + \refKey{/mermap/supply/url}, \refKey{/mermap/supply/attribution},\\ + \refKey{/mermap/supply/attribution print} and \refKey{/mermap/supply/basename}. + It is recommend to use |x ...| for \meta{source} to avoid conflicts + with future official additions to \refKey{/mermap/supply/source}. + \begin{dispListing} + \mrcnewsupplysource{x example} + { + url = http://127.0.0.1/dummy/{z}/{x}/{y}.png, + attribution = {Dummy tile server}, + attribution print = {Dummy tile server}, + basename = tiles/dummy, + } + \end{dispListing} +\end{docCommand} + + diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.marker.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.marker.tex new file mode 100644 index 00000000000..070b12acdac --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.marker.tex @@ -0,0 +1,552 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Markers}% +As described before, a map can be amended by arbitrary \tikzname\ code +using map coordinates. +For highlighting places or adding markers, the \refCom{mrcmarker} macro +may be helpful which provides some predefined marker types. + +%------------------------------------------------------------------------------- +\subsection{Marker Settings} + +\begin{docCommand}{mrcmarker}{\marg{options}} + Places a marker according to the given \meta{options} on the map. + All \meta{options} share the common prefix |/mermap/marker/|. + Different \refKey{/mermap/marker/type} settings are available which are + more or less customizable. + +\tikzsetnextfilename{marker_mrcmarker}% +\begin{dispExample} +% \mrcsetapikey{thunderforest}{YOUR-API-KEY} % registered key +\begin{tikzpicture} + \mrcmap[type=reference, position=48.15:11.6, + flex reference scale=500 000, + source=thunderforest neighbourhood, + tex width=\linewidth,tex height=4cm]{} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcdrawnetwork + \mrcclipmap + \mermapsetmarker{draw=red, fill=red!20!white, font=\sffamily\footnotesize} + \mrcmarker{type=classic, position=48.15:11.2, contents={A}, radius=0.5mm} + \mrcmarker{type=pin, position=48.15:11.3, contents={B}} + \mrcmarker{type=pinflip, position=48.15:11.4, contents={C}} + \mrcmarker{type=drop, position=48.15:11.5, contents={D}} + \mrcmarker{type=knob, position=48.15:11.6, contents={E}} + \mrcmarker{type=pictodropring, position=48.15:11.7, contents={F}} + \mrcmarker{type=pictoknobring, position=48.15:11.8, contents={G}} + \mrcmarker{type=ringx, position=48.15:11.9, contents={H}} + \mrcmarker{type=markx, position=48.15:12, contents={I}} +\end{tikzpicture} +\end{dispExample} +\end{docCommand} + + +\begin{docCommand}{mermapsetmarker}{\marg{options}} + Sets \meta{options} for all following markers inside the current \TeX\ group. + All options share the common prefix |/mermap/marker/|, e.g. for setting + \refKey{/mermap/marker/type} use + \begin{dispListing} + \mermapsetmarker{type=pin} + \end{dispListing} + Also see \refCom{mermapset} and \refCom{mermapsetsupply}. +\end{docCommand} + +\pagebreak + +\begin{docMrcKey}{marker/first options}{=\meta{options}}{no default, initially unset} + The given list of \meta{options} is used inside every \refCom{mrcmarker} + \emph{before} the options of \refCom{mrcmarker}. +\end{docMrcKey} + +\begin{docMrcKey}{marker/last options}{=\meta{options}}{no default, initially unset} + The given list of \meta{options} is used inside every \refCom{mrcmarker} + \emph{after} the options of \refCom{mrcmarker}. +\end{docMrcKey} + +\begin{docMrcKey}{marker/latitude}{=\meta{latitude}}{no default, initially |12|} + Latitude degree of the place marker. + It is accessible as \docAuxCommand{mrcmarkerlatitude} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/lat}{=\meta{latitude}}{no default, initially |12|} + Alias for \refKey{/mermap/marker/latitude}. +\end{docMrcKey} + +\begin{docMrcKey}{marker/longitude}{=\meta{longitude}}{no default, initially |49|} + Longitude degree of the place marker. + It is accessible as \docAuxCommand{mrcmarkerlongitude} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/lon}{=\meta{longitude}}{no default, initially |49|} + Alias for \refKey{/mermap/marker/longitude}. +\end{docMrcKey} + +\begin{docMrcKey}{marker/position}{=\meta{place latitude}:\meta{place longitude}}{no default, initially |12:49|} + Sets the latitude degree and the longitude degree of the place marker. +\end{docMrcKey} + +\begin{docMrcKey}{marker/named position}{=\meta{name}}{style, no default} + Sets the latitude degree and the longitude degree of the place marker + to the \emph{named position} denoted by \meta{name}, see \Fullref{sec:names_positions}. +\end{docMrcKey} + +\begin{docMrcKey}{marker/use inside}{=\meta{area}}{no default, initially |map|} + The place marker is used or ignored according to its belonging inside the + given \meta{area}. Feasible values for \meta{area} are: + \begin{itemize} + \item\docValue{map}: Use inside map. + \item\docValue{vicinity}: Use inside map plus vicinity, see \refKey{/mermap/vicinity}. + \end{itemize} +\end{docMrcKey} + + +\begin{docMrcKey}{marker/contents}{=\meta{text}}{no default, initially empty} + Sets \meta{text} for displaying inside the marker, if + the marker type supports such a thing. + It is accessible as \docAuxCommand{mrcmarkercontents} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/pictocontents}{=\meta{code}}{no default, initially empty} + Sets \tikzname\ \meta{code} for displaying inside the marker, if + the marker type supports such a thing. + It is accessible as \docAuxCommand{mrcmarkerpictocontents} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/alias}{=\meta{text}}{no default, initially |noname|} + The position of the marker is available as \tikzname\ coordinate by + the given \meta{text}, e.g. to draw to or from the marker. +\end{docMrcKey} + +\begin{docMrcKey}{marker/uuid}{=\meta{uuid}}{no default, initially empty} + Sets a \meta{uuid} for unique identification of markers. + It is accessible as \docAuxCommand{mrcmarkeruuid} (use read-only). + The \meta{uuid} is provided for user applications. +\end{docMrcKey} + + +\begin{docMrcKey}{marker/category}{=\meta{category}}{no default, initially empty} + Sets a \meta{category} to group markers. + It is accessible as \docAuxCommand{mrcmarkercategory} (use read-only). +\end{docMrcKey} + +\clearpage + +\begin{docMrcKey}{marker/show}{\colOpt{=true\textbar false}}{default |true|, initially |true|} + If set to |true|, the marker is shown, if it lies inside the map (or vicinity). + Otherwise, the place marker is not used. +\end{docMrcKey} + + +\begin{docMrcKey}{marker/hide}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If set to |true|, the marker is not used. + \refKey{/mermap/marker/hide} is inverse to \refKey{/mermap/marker/show}. +\end{docMrcKey} + + + +\begin{docMrcKey}{marker/show category}{=\meta{category}}{style, no default} + Sets \refKey{/mermap/marker/show} to |true|, if \refKey{/mermap/marker/category} equals \meta{category}. + Otherwise, nothing happens. + \refKey{/mermap/marker/category} has to be set \emph{before}. +\end{docMrcKey} + + +\begin{docMrcKey}{marker/show all but category}{=\meta{category}}{style, no default} + Sets \refKey{/mermap/marker/show} to |true|, if \refKey{/mermap/marker/category} does not equal \meta{category}. + Otherwise, nothing happens. + \refKey{/mermap/marker/category} has to be set \emph{before}. +\end{docMrcKey} + + +\begin{docMrcKey}{marker/hide category}{=\meta{category}}{style, no default} + Sets \refKey{/mermap/marker/show} to |false|, if \refKey{/mermap/marker/category} equals \meta{category}. + Otherwise, nothing happens. + \refKey{/mermap/marker/category} has to be set \emph{before}. +\end{docMrcKey} + + +\begin{docMrcKey}{marker/hide all but category}{=\meta{category}}{style, no default} + Sets \refKey{/mermap/marker/show} to |false|, if \refKey{/mermap/marker/category} does not equal \meta{category}. + Otherwise, nothing happens. + \refKey{/mermap/marker/category} has to be set \emph{before}. + \tikzsetnextfilename{marker_hide}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=4cm, tex height=4cm, + latitude=48.14, longitude=11.57, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{last options={hide all but category=A}} + \mrcmarker{type=knob,position=48.00:11.43,fill=blue,category=A} + \mrcmarker{type=knob,position=48.28:11.43,fill=red,category=B} + \mrcmarker{type=knob,position=48.00:11.71,fill=blue,category=A} + \mrcmarker{type=knob,position=48.28:11.71,fill=red,category=B} + \end{tikzpicture} + \end{dispExample} +\end{docMrcKey} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Marker Types} + +\begin{docMrcKey}{marker/type}{=\meta{type}}{no default, initially |classic|} + Decides about the basic shape and style of the marker. + Feasible values for \meta{type} are listed in the following. + More values can be defined by \refCom{mrcnewmarkertype}. + \begin{itemize} + % + \item\docValue{classic}: + \tikzsetnextfilename{marker_classic}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=classic} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=classic, text=blue, font=\sffamily\footnotesize} + \mrcmarker{position=48.14:11.57, contents={M\"unchen}, angle=-30} + \end{tikzpicture} + \end{dispExample} + % + \item\docValue{pin}: + \tikzsetnextfilename{marker_pin}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=pin} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=pin, draw=blue, fill=blue!20!white, + font=\sffamily\footnotesize} + \mrcmarker{position=48.14:11.57, contents={M\"unchen}, alias={munich}} + \end{tikzpicture} + \end{dispExample} + % + \clearpage + \item\docValue{pinflip}: + \tikzsetnextfilename{marker_pinflip}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=pinflip} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=pinflip, draw=red, fill=red!20!white, + font=\sffamily\footnotesize} + \mrcmarker{position=48.14:11.57, contents={M\"unchen}, shift=4mm} + \end{tikzpicture} + \end{dispExample} + % + \item\docValue{drop}: + \tikzsetnextfilename{marker_drop}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=drop} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=drop, fill=blue, draw=blue!20!white, text=white, + font=\sffamily\small\bfseries, + path style={line join=round, thin, draw=mrcmarkerfill, + double=mrcmarkerdraw,double distance=0.6pt} } + \mrcmarker{position=48.14:11.57, contents={M}, alias={munich}} + \end{tikzpicture} + \end{dispExample} + % + \clearpage + \item\docValue{pictodrop}: + \tikzsetnextfilename{marker_pictodrop}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=pictodrop, pictocontents={ + \draw[fill=red!70!gray,draw=white] + (-0.2,-0.2)--(0.2,-0.2)--(0.2,0.1)--(0,0.2)--(-0.2,0.1) -- cycle; + }} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=pictodrop, + fill=blue!75!gray!30, draw=blue, + radius=4mm, shift=-1mm} + \mrcmarker{position=48.14:11.57, + pictocontents={ + \node {\includegraphics[width=6mm]{alertmessage-warning.png}}; + }} + \end{tikzpicture} + \end{dispExample} + % + \item\docValue{pictodropring}: + \tikzsetnextfilename{marker_pictodropring}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=pictodropring} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=pictodropring, + fill=red!50!gray, draw=red!75!white, + shift=-1mm} + \mrcmarker{position=48.14:11.57} + \end{tikzpicture} + \end{dispExample} + % + \clearpage + \item\docValue{knob}: + \tikzsetnextfilename{marker_knob}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=knob} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=knob, radius=2mm, + fill=blue, draw=blue!20!white, + text=white, path style={draw=mrcmarkerfill, double=mrcmarkerdraw, + double distance=0.6pt} } + \mrcmarker{position=48.14:11.57, contents={M}} + \end{tikzpicture} + \end{dispExample} + % + \item\docValue{pictoknob}: + \tikzsetnextfilename{marker_pictoknob}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=pictoknob} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=pictoknob, radius=2mm, + fill=blue, draw=blue!20!white, + path style={draw=mrcmarkerfill, double=mrcmarkerdraw, + double distance=0.6pt} } + \mrcmarker{position=48.14:11.57, alias={munich}} + \end{tikzpicture} + \end{dispExample} + % + \clearpage + \item\docValue{pictoknobring}: + \tikzsetnextfilename{marker_pictoknobring}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=pictoknobring} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=pictoknobring, radius=2mm, inner radius=1mm, + draw=blue, fill=blue!20!white, + pictocontents={\node[above] at (0,\mrcmarkerradius) + {\mrcmarkercontents};} + } + \mrcmarker{position=48.14:11.57, contents={M\"unchen}} + \end{tikzpicture} + \end{dispExample} + % + \item\docValue{ringx}: + \tikzsetnextfilename{marker_ringx}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=ringx} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=ringx, radius=4mm, inner radius=3mm, + draw=red, fill=red!50!white, + path style={draw=mrcmarkerdraw, very thin, double=white, + double distance=0.6pt} + } + \mrcmarker{position=48.14:11.57, alias={munich}} + \end{tikzpicture} + \end{dispExample} + % + \clearpage + \item\docValue{markx}: + \tikzsetnextfilename{marker_markx}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mermapsetmarker{type=markx} + \mrcmarker{position=48.14:11.36, contents={Germering}} + \mermapsetmarker{type=markx, radius=4mm, inner radius=3mm, + draw=red, fill=red!50!white, path style={very thin} + } + \mrcmarker{position=48.14:11.57, alias={munich}} + \end{tikzpicture} + \end{dispExample} + % + \end{itemize} +\end{docMrcKey} + +\medskip +The different marker types can be customized by some additional options: + +\begin{docMrcKey}{marker/font}{=\meta{font}}{no default, initially \texttt{\textbackslash sffamily\textbackslash small}} + Font of the marker text + (\docValue{classic}, \docValue{pin}, \docValue{pinflip}, \docValue{drop}, \docValue{knob}). + It is accessible as \docAuxCommand{mrcmarkerfont} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/text}{=\meta{color}}{no default, initially |black|} + Color of the marker text + (\docValue{classic}, \docValue{pin}, \docValue{pinflip}, \docValue{drop}, \docValue{knob}). + It is accessible as \docColor{mrcmarkertext} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/draw}{=\meta{color}}{no default, initially |gray|} + Color of the marker frame + (\docValue{pin}, \docValue{pinflip}, \docValue{drop}, \docValue{pictodrop}, + \docValue{pictodropring}, \docValue{knob}, \docValue{pictoknob}, \docValue{pictoknobring}, + \docValue{ringx}, \docValue{markx}). + It is accessible as \docColor{mrcmarkerdraw} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/fill}{=\meta{color}}{no default, initially |gray!20|} + Color of the marker interior + (\docValue{pin}, \docValue{pinflip}, \docValue{drop}, \docValue{pictodrop}, + \docValue{pictodropring}, \docValue{knob}, \docValue{pictoknob}, \docValue{pictoknobring}, + \docValue{ringx}, \docValue{markx}). + It is accessible as \docColor{mrcmarkerfill} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/angle}{=\meta{angle}}{no default, initially |90|} + Angle of the marker (\docValue{classic}). + It is accessible as \docAuxCommand{mrcmarkerangle} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/shift}{=\meta{length}}{no default, initially |0pt|} + Shift of the marker text + (\docValue{pin}, \docValue{pinflip}). + It also shifts the drop center + (\docValue{drop}, \docValue{pictodrop}, \docValue{pictodropring}). + It is accessible as \docAuxCommand{mrcmarkershift} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/radius}{=\meta{length}}{no default, initially |3mm|} + Radius of the marker + (\docValue{classic}, \docValue{drop}, \docValue{pictodrop}, + \docValue{pictodropring}, \docValue{knob}, \docValue{pictoknob}, \docValue{pictoknobring}, + \docValue{ringx}, \docValue{markx}). + It is accessible as \docAuxCommand{mrcmarkerradius} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/inner radius}{=\meta{length}}{no default, initially |2.25mm|} + Inner radius of the marker + (\docValue{pictodropring}, \docValue{pictoknobring}, \docValue{ringx}). + It is accessible as \docAuxCommand{mrcmarkerinnerradius} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/path style}{=\marg{options}}{no default, initially empty} + \tikzname\ \meta{options} which are added to (some) path elements of + of the marker + (\docValue{pin}, \docValue{pinflip}, \docValue{drop}, \docValue{pictodrop}, + \docValue{pictodropring}, \docValue{knob}, \docValue{pictoknob}, \docValue{pictoknobring}, + \docValue{ringx}, \docValue{markx}). + It is accessible as \tikzname\ option \docValue{mrcpathstyle} (use read-only). +\end{docMrcKey} + +\begin{docMrcKey}{marker/node style}{=\marg{options}}{no default, initially empty} + \tikzname\ \meta{options} which are added to the node element of + of the marker + (\docValue{classic}, \docValue{pin}, \docValue{pinflip}, \docValue{drop}, \docValue{knob}). + It is accessible as \tikzname\ option \docValue{mrcnodestyle} (use read-only). +\end{docMrcKey} + + + +%------------------------------------------------------------------------------- +\subsection{New Marker Types} + +\begin{docCommand}{mrcnewmarkertype}{\marg{type name}\marg{\tikzname\ code}} + Creates a new \refKey{/mermap/marker/type} value \meta{type name} using the + given \meta{\tikzname\ code} for drawing a place marker. + To avoid future name clashes, you should start a private \meta{type name} + with letter |x|. For \meta{\tikzname\ code} settings like + \docAuxCommand{mrcmarkercontents}, + \docAuxCommand{mrcmarkerfont}, or \docColor{mrcmarkerfill} may be used + or ignored. + + \tikzsetnextfilename{marker_xmark}% + \begin{dispExample} + \mrcnewmarkertype{xmark}{ + \path[draw=mrcmarkerdraw,thick] circle (\mrcmarkerradius); + \path[draw=mrcmarkerdraw,thick] + (45:2*\mrcmarkerradius)--(225:2*\mrcmarkerradius) + (135:2*\mrcmarkerradius)--(315:2*\mrcmarkerradius); + } + \begin{tikzpicture} + \mrcmap[tex width=4cm, tex height=4cm, + latitude=48.14, longitude=11.57, target=none]{} + \mrcdrawmap[draw=path] + \mrcmarker{type=xmark, + position=48.14:11.57,alias={munich}, + draw=red} + \end{tikzpicture} + \end{dispExample} +\end{docCommand} + + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{New Marker Styles} + +\begin{docCommand}{mrcnewmarkerstyle}{\marg{style name}\marg{options}} + Creates a new \refKey{/mermap/marker/style} value \meta{style name} using the + given \meta{options} for drawing a place marker. + All \meta{options} share the common prefix |/mermap/marker/|. Here, a \emph{style} + has the same concept as a \tikzname\ style. + + \tikzsetnextfilename{marker_markerstyle}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mrcnewmarkerstyle{one}{type=pin, draw=blue, fill=blue!20!white, + font=\sffamily\footnotesize} + \mrcnewmarkerstyle{two}{type=pinflip, draw=red, fill=red!20!white, + font=\sffamily\footnotesize} + \mrcmarker{style=one, position=48.14:11.36, contents={Germering}} + \mrcmarker{style=two, position=48.14:11.57, contents={M\"unchen}} + \end{tikzpicture} + \end{dispExample} + + A \emph{style} can have one parameter, but note the small difference + in applying this parameter compared to \tikzname: + + \tikzsetnextfilename{marker_markerstyle2}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[tex width=8cm, tex height=4cm, zoom=10, + latitude=48.14, longitude=11.48, target=none]{} + \mrcdrawmap[draw=path] + \mrcnewmarkerstyle{color}{type=pin, draw=#1, fill=#1!20!white, + font=\sffamily\footnotesize} + \mrcmarker{style/color=blue, position=48.14:11.36, contents={Germering}} + \mrcmarker{style/color=red, position=48.14:11.57, contents={M\"unchen}} + \end{tikzpicture} + \end{dispExample} +\end{docCommand} + + +\begin{docMrcKey}{marker/style}{=\meta{style name}}{no default, initially unset} + Applies a given \meta{style name}, i.e. all options which were stored + by \refCom{mrcnewmarkerstyle} under this name. +\end{docMrcKey} + diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.orthodromes.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.orthodromes.tex new file mode 100644 index 00000000000..17855158412 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.orthodromes.tex @@ -0,0 +1,169 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Orthodromes and Loxodromes}\label{sec:orthodromes}% + +A loxodrome is a curve which crosses all meridians with +a constant angle. On Mercator maps, loxodromes are depicted as straight lines +and can be drawn by simple \tikzname\ |path| elements. + +On a sphere, the shortest path +from one point to another runs along an orthodrome where +an orthodrome is a great-circle. + +The mathematical background and further information are found in \cite{Sturm:2020}. + + +%------------------------------------------------------------------------------- +\subsection{Orthodrome Drawing} + +\begin{docMrcKey}{samples}{=\meta{number}}{no default, initially |100|} + An orthodrome curve is approximated by a polygon trajectory with + \meta{number} pieces. +\end{docMrcKey} + + +\begin{docTikzKey}{mermap samples}{=\meta{number}}{style, no default} + \tikzname\ variant to set \refKey{/mermap/samples}. +\end{docTikzKey} + + +\begin{docCommand}{mrcdraworthodrome}{\oarg{options}\marg{lat1}\marg{lon1}\marg{lat2}\marg{lon2}} + Draws an orthodrome curve from a point with + latitude \meta{lat1} and longitude \meta{lon1} + to a point with + latitude \meta{lat2} and longitude \meta{lon2}. + This is a \tikzname\ path object where \meta{options} are + \tikzname\ settings for this path. There are two orthodrome pieces connecting + two positions (forming a great-circle). \refCom{mrcdraworthodrome} does + not necessarily choose the shorter one, see \cite{Sturm:2020}. + The drawn orthodrome is a spherical approximation instead of an ellipsoidal + one. + \tikzsetnextfilename{ortho_orthodrome1}% + \begin{dispExample} + \begin{tikzpicture} + \mrcmap[type=areafit, + south=40.7,north=48.2,west=-74.1,east=11.6, + source=topplusopen web, + tex width=\linewidth,tex height=6cm, + ]{ortho_orthodrome1} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \draw (mrcmap.south west) rectangle (mrcmap.north east); + \mrcdraworthodrome[red,very thick,mermap samples=100] + {48.14}{11.58}{40.71}{-74.01} + \node[red,fill=white] at ([above=1.3cm]mrcmap) { + \mrcprettyorthodistance{48.14}{11.58}{40.71}{-74.01} }; + \end{tikzpicture} + \end{dispExample} +\end{docCommand} + + +\clearpage +\begin{docCommand}{mrcNPdraworthodrome}{\oarg{options}\marg{name1}\marg{name2}} + Identical to \refCom{mrcdraworthodrome}, but the start and end point are + described by named positions \meta{name1} and \meta{name2}. + + \tikzsetnextfilename{ortho_orthodrome2}% + \begin{dispExample} + \begin{tikzpicture} + \mrcNPdef{munich}{48.14}{11.58} + \mrcNPdef{newyork}{40.71}{-74.01} + \mrcmap[type=areafit, area={munich,newyork}, + source=topplusopen web, + tex width=\linewidth,tex height=6cm, + ]{ortho_orthodrome2} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \draw (mrcmap.south west) rectangle (mrcmap.north east); + \mrcmarker{type=pin,named position=munich,contents={M\"unchen}} + \mrcmarker{type=pinflip,shift=5mm,named position=newyork, + contents={New York City}} + \mrcNPdraworthodrome[red,very thick] {munich}{newyork} + \draw[blue,very thick] (\mrcNPcs{munich}) -- (\mrcNPcs{newyork}); + \node[red,fill=white] at ([above=1.3cm]mrcmap) { + \mrcNPprettyorthodistance{munich}{newyork} }; + \node[blue,fill=white] at ([below=5mm]mrcmap) { + \mrcNPprettyloxodistance{munich}{newyork} }; + \end{tikzpicture} + \end{dispExample} +\end{docCommand} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Orthodromic and Loxodromic Distances} + +\begin{docCommand}{mrcprettyorthodistance}{\marg{lat1}\marg{lon1}\marg{lat2}\marg{lon2}} + Approximate orthodromic distance between two points + with latitude \meta{lat1}, longitude \meta{lon1} + and latitude \meta{lat2}, longitude \meta{lon2} + with three valid digits. + \begin{dispExample} + \mrcprettyorthodistance{48.14}{11.58}{40.71}{-74.01} + \end{dispExample} +\end{docCommand} + + +\begin{docCommand}{mrcNPprettyorthodistance}{\marg{name1}\marg{name2}} + Approximate orthodromic distance between two named positions + \meta{name1} and \meta{name2} with three valid digits. + \begin{dispExample} + \mrcNPdef{munich}{48.14}{11.58} + \mrcNPdef{newyork}{40.71}{-74.01} + \mrcNPprettyorthodistance{munich}{newyork} + \end{dispExample} +\end{docCommand} + + +\begin{docCommand}{mrcstoreorthodistance}{\marg{macro}\marg{lat1}\marg{lon1}\marg{lat2}\marg{lon2}} + Stores the approximate orthodromic distance (in kilometers) between two points + with latitude \meta{lat1}, longitude \meta{lon1} + and latitude \meta{lat2}, longitude \meta{lon2} + to a given \meta{macro}. + \begin{dispExample} + \mrcstoreorthodistance\mydist{48.14}{11.58}{40.71}{-74.01} + \mydist + \end{dispExample} +\end{docCommand} + + +\begin{docCommand}{mrcprettyloxodistance}{\marg{lat1}\marg{lon1}\marg{lat2}\marg{lon2}} + Approximate loxodromic distance between two points + with latitude \meta{lat1}, longitude \meta{lon1} + and latitude \meta{lat2}, longitude \meta{lon2} + with three valid digits. + \begin{dispExample} + \mrcprettyloxodistance{48.14}{11.58}{40.71}{-74.01} + \end{dispExample} +\end{docCommand} + + +\begin{docCommand}{mrcNPprettyloxodistance}{\marg{name1}\marg{name2}} + Approximate loxodromic distance between two named positions + \meta{name1} and \meta{name2} with three valid digits. + \begin{dispExample} + \mrcNPdef{munich}{48.14}{11.58} + \mrcNPdef{newyork}{40.71}{-74.01} + \mrcNPprettyloxodistance{munich}{newyork} + \end{dispExample} +\end{docCommand} + + +\begin{docCommand}{mrcstoreloxodistance}{\marg{macro}\marg{lat1}\marg{lon1}\marg{lat2}\marg{lon2}} + Stores the approximate loxodromic distance (in kilometers) between two points + with latitude \meta{lat1}, longitude \meta{lon1} + and latitude \meta{lat2}, longitude \meta{lon2} + to a given \meta{macro}. + \begin{dispExample} + \mrcstoreloxodistance\mydist{48.14}{11.58}{40.71}{-74.01} + \mydist + \end{dispExample} +\end{docCommand} + diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.routes.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.routes.tex new file mode 100644 index 00000000000..f7a26cf0628 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.routes.tex @@ -0,0 +1,130 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Routes}\label{sec:routes}% + +Routes are \tikzname\ |path| objects which can be drawn with the appropriate +\tikzname\ macros and the coordinate system documented in +\Fullref{sec:map_definition}. +Nevertheless, in the following some alternatives are described which allow +to specify a path by a sequence of points (\refCom{mrcpoint}). +The idea is that such a sequence of points is exported by a third-party +application for inclusion in a \LaTeX\ map, see \Fullref{sec:routes_gpx}. + + +%------------------------------------------------------------------------------- +\subsection{Route Path Definition} + +\begin{docEnvironment}{mrcroute}{\oarg{options}} + This environment creates a \tikzname\ |path| with given \tikzname\ \meta{options}. + The \meta{environment content} is a sequence of points made by \refCom{mrcpoint}. + \begin{dispListing} + \begin{mrcroute}[red, very thick] + \mrcpoint{48.137222}{11.575556} + \mrcpoint{49.019479}{12.0976942} + ... + \end{mrcroute} + \end{dispListing} + Note that a map definition by \refCom{mrcdefinemap}, \refCom{mrcmap}, + or \refCom{mrcapplymap} is needed before a route |path| can be drawn.\par + %A |path| can be closed by adding \docAuxCommand{pgfpathclose} as last entry + %after all \refCom{mrcpoint} macros. Further |pgf| commands may be added, + %but the sequence should start with a \refCom{mrcpoint}. +\end{docEnvironment} + + +\begin{docEnvironment}{mrcroute*}{\oarg{options}} + Identical to \refEnv{mrcroute}, but the created \tikzname\ |path| is + closed. +\end{docEnvironment} + + +\begin{docCommand}{mrcrouteinput}{\oarg{options}\marg{filename}} + Identical to \refEnv{mrcroute}, but the sequence of points is included + from a file with the given \meta{filename}. +\end{docCommand} + +\begin{docCommand}{mrcrouteinput*}{\oarg{options}\marg{filename}} + Identical to \refCom{mrcrouteinput}, but the created \tikzname\ |path| is + closed. +\end{docCommand} + + +\begin{docCommand}{mrcpoint}{\marg{latitude}\marg{longitude}} + Specifies a single coordinate point with given \meta{latitude} and + \meta{longitude} as part of sequence inside \refEnv{mrcroute}.\par + This is a wrapper for |\pgfpathmoveto| respectively |\pgfpathlineto|. +\end{docCommand} + + +\begin{docMrcKey}{every route}{=\meta{options}}{no default, initially empty} + Sets \tikzname\ \meta{options} which are applied to every + \refEnv{mrcroute} and \refCom{mrcrouteinput}. +\end{docMrcKey} + + +\tikzsetnextfilename{routes_example}% +\begin{dispExample*}{center lower} +% \mrcsetapikey{thunderforest}{YOUR-API-KEY} % registered key +\begin{tikzpicture} + \mrcmap[type=areafit, + west=5,east=15,south=47,north=55, + source=thunderforest neighbourhood, + tex width=14cm, tex height=14cm, + flex area fit=5mm + ]{routes_example} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \path[draw] (mrcmap.south west) rectangle (mrcmap.north east); + \begin{mrcroute}[blue,line width=0.4mm,line cap=round, + line join=round,double=blue!5!white,double distance=0.4mm] + \mrcpoint{48.137222}{11.575556} + \mrcpoint{49.019479}{12.0976942} + \mrcpoint{49.45522}{11.07631} + \mrcpoint{50.978056}{11.029167} + \mrcpoint{52.518611}{13.408333} + \end{mrcroute} +\end{tikzpicture} +\end{dispExample*} + + +\clearpage +%------------------------------------------------------------------------------- +\subsection{Example Python Conversion Scripts for gpx}\label{sec:routes_gpx} +The following scripts are examples for conversions from a standard +routes and tracks of |gpx| files to \LaTeX\ include files +(assuming a single route/track per file). + +\begin{dispListing*}{title=Python 3 script to convert \texttt{route.gpx} to + a sequence of points file \texttt{route.inc}, + documentation minted language=python} +import xmltodict + +with open('route.gpx', encoding='utf-8') as gpx: + doc = xmltodict.parse(gpx.read()) + with open('route.inc', "w", encoding="utf-8") as inc: + for rtept in doc['gpx']['rte']['rtept']: + lat = rtept['@lat'] + lon = rtept['@lon'] + inc.write(f'\\mrcpoint{{{lat}}}{{{lon}}}\n') +\end{dispListing*} + + +\begin{dispListing*}{title=Python 3 script to convert \texttt{track.gpx} to + a sequence of points file \texttt{track.inc}, + documentation minted language=python} +import xmltodict + +with open('track.gpx', encoding='utf-8') as gpx: + doc = xmltodict.parse(gpx.read()) + with open('track.inc', "w", encoding="utf-8") as inc: + for trkpt in doc['gpx']['trk']['trkseg']['trkpt']: + lat = trkpt['@lat'] + lon = trkpt['@lon'] + inc.write(f'\\mrcpoint{{{lat}}}{{{lon}}}\n') +\end{dispListing*} + diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.scales.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.scales.tex new file mode 100644 index 00000000000..4c139d14490 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.scales.tex @@ -0,0 +1,401 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Scales and Sizes}% + +Inside a defined map several size values and scaling options are +available. Please note that due to the nature of the Mercator projection and several +simplifying assumptions all specifications for map scale, map width, map height, +etc. are imprecise in the best case and even misleading in the worst case. +They are suited for representative diagrams, +but not for critical navigation purposes etc. + +\subsection{Map Sizes and Document Sizes} + +\begin{docCommand}{mrctexwidth}{} + \TeX\ length denoting the document width of the current map. +\end{docCommand} + +\begin{docCommand}{mrctexheight}{} + \TeX\ length denoting the document width of the current map. +\end{docCommand} + +\begin{docCommand}{mrcscale}{} + Scaling factor between map and real world. + A \TeX\ length given in |pt|, but stripped from that unit, + multiplied by \refCom{mrcscale} corresponds to a real world length + given in kilometers. + Note that this is \emph{not} the map scale. + Actually, it is reciprocal proportional to the map scale + and proportional to the map scale denominator, see \refCom{mrcmapscaledenominator}. +\end{docCommand} + +\begin{docCommand}{mrctextokm}{\marg{length}} + Computes a given \TeX\ \meta{length} (with unit) into the corresponding + real world length in kilometers (without unit). + \begin{dispListing} + Map width: \mrctextokm{\mrctexwidth}\,km + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{mrctextomile}{\marg{length}} + Computes a given \TeX\ \meta{length} (with unit) into the corresponding + real world length in miles (without unit). + \begin{dispListing} + Map width: \mrctextomile{\mrctexwidth}\,mi + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{mrckmtotex}{\marg{number}} + Computes real world length \meta{number} in kilometers (without unit) + to a \TeX\ length (with unit). + \begin{dispListing} + % draw a circle with radius 20km + \draw (mrcpos) circle (\mrckmtotex{20}); + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{mrcmiletotex}{\marg{number}} + Computes real world length \meta{number} in miles (without unit) + to a \TeX\ length (with unit). + \begin{dispListing} + % draw a circle with radius 20 miles + \draw (mrcpos) circle (\mrcmiletotex{20}); + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{mrcmapscaledenominator}{} + Approximate map scale denominator. + \SI{1}{cm} on the map corresponds approximately to + \mbox{\refCom{mrcmapscaledenominator}$\cdot$\SI{1}{cm}} in the real world. + Do not confuse with \refCom{mrcscale}. + \begin{dispListing} + Map scale: 1:\mrcmapscaledenominator + \end{dispListing} +\end{docCommand} + + +\subsection{Pretty Size Output} + + +\begin{docCommand}{mrcprettymapscale}{} + Approximate map scale given with three valid digits + with a representation like |1:1000|. + \begin{dispListing} + Map scale: \mrcprettymapscale + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{mrcprettymapwidth}{} + Approximate map width in kilometers (or meters) with three valid digits: + \begin{dispListing} + Map width: \mrcprettymapwidth + \end{dispListing} + To create a pretty printing to your own liking, you can do like the + following: + \begin{dispListing} + \newcommand{\myprettymapwidth}{\SI[round-mode=figures,round-precision=3]% + {\mrctextokm{\mrctexwidth}}{km}} + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{mrcprettymapheight}{} + Approximate map height in kilometers (or meters) with three valid digits: + \begin{dispListing} + Map height: \mrcprettymapheight + \end{dispListing} +\end{docCommand} + + +\begin{docCommand}{mrcprettymapresolution}{} + Approximate map resolution in dpi (dots per inch): + \begin{dispListing} + Map resolution: \mrcprettymapresolution + \end{dispListing} +\end{docCommand} + +\begin{docCommand}{mrcprettytilesize}{} + Approximate tile size inside the document (\TeX\ size) in millimeters: + \begin{dispListing} + \TeX\ tile size: \mrcprettytilesize + \end{dispListing} +\end{docCommand} + + +\tikzsetnextfilename{scales_example}% +\begin{dispExample} +\begin{tikzpicture} + \mrcNPdef{rome}{41.89300}{12.48557} + \mermapset{named flex scale=2000000:rome} + \mrcmap[type=reference, named position=rome, source=topplusopen web, + tex width=\linewidth, tex height=10cm]{scales_example} + \mrcdrawmap + \node[below,font=\fontsize{7pt}{7pt}\sffamily] at (mrcmap.south) + {\mrcmapattribution}; + \mrcclipmap + \path[draw] (\mrcNPcs{rome}) circle (\mrckmtotex{50}); + \node[above] at ([yshift=\mrckmtotex{50}]\mrcNPcs{rome}) {\SI{50}{km}}; + \node[above right,fill=white,fill opacity=0.5,text opacity=1,align=center, + line width=0pt, inner sep=2mm] + at (mrcmap.south west) { \begin{tabular}{rl} + scale: & \mrcprettymapscale\\ + map width: & \mrcprettymapwidth\\ + map height: & \mrcprettymapheight\\ + \TeX\ tile size: & \mrcprettytilesize\\ + resolution: & \mrcprettymapresolution + \end{tabular}\\ + \begin{tikzpicture} + \mrcdrawscalebar[width-in-km=100] + \path[every node/.style={above,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.north west) -- (mrcscalebar.north east) + node[pos=0]{0} node[pos=0.2]{20} node[pos=0.4]{40} node[pos=0.6]{60} + node[pos=0.8]{80} node[pos=1]{100} node[pos=1,right,yshift=-1mm]{km}; + \end{tikzpicture} + }; +\end{tikzpicture} +\end{dispExample} + + +\clearpage +\subsection{Scale Bars} + + +\begin{docCommand}{mrcdrawscalebar}{\oarg{options}} + Draws a scale bar according to the given \meta{options}. + All \meta{options} share the common prefix |/mermap/scalebar/|. + The most essential option is the \emph{width} of the scale bar. + + \tikzsetnextfilename{scales_scalebar1} + \begin{dispExample} + \begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{vienna}{48.208333}{16.373056} + \mrcmap[tex width=\linewidth, tex height=4cm, target=none, + type=areafit, area={munich,vienna}, flex area fit=2cm]{} + \mrcdrawmap + \mrcmarker{named position=munich, contents={M\"unchen}} + \mrcmarker{named position=vienna, contents={Wien}} + \mrcdrawscalebar[width-in-km=100, solid, + at={([xshift=-10mm,yshift=5mm]mrcmap.south east)}, + placement={above left}, ] + \end{tikzpicture} + \end{dispExample} + + The size, position, and appearance of the scale bar can be customized by + setting the various \meta{options}. The shape of the scale bar + is denoted by a \tikzname\ node \docNode{mrcscalebar} which can be used + for lettering. + + \enlargethispage*{1cm} + \tikzsetnextfilename{scales_scalebar2} + \begin{dispExample} + \begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{vienna}{48.208333}{16.373056} + \mrcmap[tex width=\linewidth, tex height=4cm, target=none, + type=areafit, area={munich,vienna}, flex area fit=2cm]{} + \mrcdrawmap + \mrcmarker{named position=munich, contents={M\"unchen}} + \mrcmarker{named position=vienna, contents={Wien}} + \mrcdrawscalebar[width-in-km=100,solid,south-west-inside=10mm;3mm ] + \path[every node/.style={above,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.north west) -- (mrcscalebar.north east) + node[pos=0]{0} node[pos=0.2]{20} node[pos=0.4]{40} node[pos=0.6]{60} + node[pos=0.8]{80} node[pos=1]{100} node[pos=1,right,yshift=-1mm]{km}; + \end{tikzpicture} + \end{dispExample} + +\end{docCommand} + + +\begin{docMrcKey}{scalebar/width-in-km}{=\meta{number}}{no default, initially |0|} + Sets the width of the scale bar to match the real word length \meta{number} + in kilometers. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/width-in-kilometer}{=\meta{number}}{no default, initially |0|} + Alias for \refKey{/mermap/scalebar/width-in-km} +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/width-in-meter}{=\meta{number}}{no default, initially |0|} + Sets the width of the scale bar to match the real word length \meta{number} + in meters. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/width-in-mile}{=\meta{number}}{no default, initially |0|} + Sets the width of the scale bar to match the real word length \meta{number} + in miles. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/width-in-yard}{=\meta{number}}{no default, initially |0|} + Sets the width of the scale bar to match the real word length \meta{number} + in yards. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/partitions}{=\meta{number}}{no default, initially |5|} + Determines the \meta{number} of partitions for the scale bar. If \meta{number} + is set to 1, there is no partitioning. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/height}{=\meta{length}}{no default, initially |2mm|} + Sets the height of the scale bar to the given \TeX\ \meta{length}. +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/at}{=\marg{\tikzname\ coordinate}}{no default, + initially \texttt{\brackets{(0,0)}}} + The scale bar is positioned at the given \meta{\tikzname\ coordinate}. + The placement is done with the \refKey{/mermap/scalebar/placement} option. + Both option correspond to the \tikzname\ options for positioning nodes. + The scale bar can be positioned outside the map (e.g. below), but + remember to use \refCom{mrcclipmap} \emph{after} the scale bar + in this case, if needed. + +% \begin{dispListing} +% \mrcdrawscalebar[ +% at = {([xshift=-10mm,yshift=5mm]mrcmap.south east)}, +% placement = above left, +% ] +% \end{dispListing} + + \tikzsetnextfilename{scales_scalebar3} + \begin{dispExample} + \begin{tikzpicture} + \mrcNPdef{munich}{48.137222}{11.575556} + \mrcNPdef{vienna}{48.208333}{16.373056} + \mrcmap[tex width=\linewidth, tex height=4cm, target=none, + type=areafit, area={munich,vienna}, flex area fit=2cm]{} + \mrcdrawmap + \mrcmarker{named position=munich, contents={M\"unchen}} + \mrcmarker{named position=vienna, contents={Wien}} + \mrcdrawscalebar[width-in-km=200, partitions=8, + at={([xshift=5mm,yshift=-2mm]mrcmap.south west)}, + placement=below right ] + \path[every node/.style={below,inner sep=0.5mm,font=\sffamily\tiny}] + (mrcscalebar.south west) -- (mrcscalebar.south east) + node[pos=0]{0} node[pos=0.25]{50} node[pos=0.5]{100} node[pos=0.75]{150} + node[pos=1]{200} node[pos=1,right,yshift=1mm]{km}; + \end{tikzpicture} + \end{dispExample} +\end{docMrcKey} + +\pagebreak + +\begin{docMrcKey}{scalebar/placement}{=\meta{\tikzname\ positioning}}{no default, initially empty} + \meta{\tikzname\ positioning} of a scale bar in combination with + \refKey{/mermap/scalebar/at}. All \tikzname\ placement options for nodes + can be used, e.g. \texttt{above left} or \texttt{anchor=mid west}, etc. + Actually, \emph{any} node option could be applied here, but the intended use + is for placement options only. +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/south-east-inside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar at the south east corner of the map. + The optional \mbox{\meta{x shift}} and \meta{y shift} denote the + absolute shift values in each direction, i.e. the algebraic sign is + automatically complemented. + If only \meta{x shift} is given, then \meta{y shift} is set + to the same value. \refKey{/mermap/scalebar/at} and \refKey{/mermap/scalebar/placement} + are set by this option. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/south-east-outside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar below the south east corner of the map. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/south-west-inside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar at the south west corner of the map. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/south-west-outside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar below the south west corner of the map. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/north-west-inside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar at the north west corner of the map. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/north-west-outside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar above the north west corner of the map. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/north-east-inside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar at the north east corner of the map. +\end{docMrcKey} + +\begin{docMrcKey}{scalebar/north-east-outside}{\colOpt{=\meta{x shift};\meta{y shift}}}{default |0pt;0pt|, initially unset} + Shortcut for placing the scale bar above the north east corner of the map. +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/major style}{=\marg{\tikzname\ options}}{no default, initially empty} + The \emph{major} part of the scale bar is a single \tikzname\ path object + which can be customized by the given \meta{\tikzname\ options}. + The \emph{major} part consists of the black area in the default case. + \tikzsetnextfilename{scales_scalebar4} + \begin{dispExample} + \begin{tikzpicture} + \mrcdrawscalebar[scale=2000000, width-in-km=100, + major style={left color=red,right color=blue} ] + \end{tikzpicture} + \end{dispExample} +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/minor style}{=\marg{\tikzname\ options}}{no default, initially empty} + The \emph{minor} part of the scale bar is a single \tikzname\ path object + which can be customized by the given \meta{\tikzname\ options}. + The \emph{minor} part is seen as holes in the default case. + \refKey{/mermap/scalebar/minor style} has only an effect, if + the minor part is drawn \refKey{/mermap/scalebar/solid}. + \tikzsetnextfilename{scales_scalebar5} + \begin{dispExample} + \begin{tikzpicture} + \mrcdrawscalebar[scale=2000000, width-in-km=100, solid, + minor style={yellow} ] + \end{tikzpicture} + \end{dispExample} +\end{docMrcKey} + + +\pagebreak +\begin{docMrcKey}{scalebar/double}{\colOpt{=true\textbar false}}{default |true|, initially |true|} + If set to |true|, the scale bar is drawn as a double ruler. +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/single}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If set to |true|, the scale bar is drawn as a single ruler. + \refKey{/mermap/scalebar/single} is inverse to \refKey{/mermap/scalebar/double}. + \tikzsetnextfilename{scales_scalebar6} + \begin{dispExample} + \begin{tikzpicture} + \mrcdrawscalebar[scale=2000000, width-in-km=100, single, height=1mm] + \end{tikzpicture} + \end{dispExample} +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/transparent}{\colOpt{=true\textbar false}}{default |true|, initially |true|} + If set to |true|, the \emph{minor} part of the scale bar is drawn transparent, + i.e. as holes inside the ruler. +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/solid}{\colOpt{=true\textbar false}}{default |true|, initially |false|} + If set to |true|, the \emph{minor} part of the scale bar is drawn opaque. + It is drawn white or according to \refKey{/mermap/scalebar/minor style}. + \refKey{/mermap/scalebar/solid} is inverse to \refKey{/mermap/scalebar/transparent}. +\end{docMrcKey} + + +\begin{docMrcKey}{scalebar/scale}{=\meta{scale denominator}}{no default, initially unset} + Sets or overwrites the \meta{scale denominator} setting. + \textbf{Using this key is not needed and may even lead to erroneous displays + inside a |tikzpicture| with a defined map setting.} + This key is helpful, if a scale bar is used without a defined map. +\end{docMrcKey} + diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.sty b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.sty new file mode 100644 index 00000000000..e2ecc0fe9fa --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.sty @@ -0,0 +1,104 @@ +% !TeX root = mercatormap.tex +% include file (style) of mercatormap.tex (manual of the LaTeX package mercatormap) +\renewcommand*\l@subsection{\@dottedtocline{2}{1.5em}{2.7em}} +\renewcommand*\l@subsubsection{\@dottedtocline{3}{4.2em}{3.2em}} + +\RequirePackage[T1]{fontenc} +\RequirePackage[utf8]{inputenc} +\RequirePackage[english]{babel} +\RequirePackage{lmodern,parskip,array} +\RequirePackage[svgnames,table,hyperref]{xcolor} +\RequirePackage{tikz} +\RequirePackage{varioref} +\RequirePackage[makeindex]{imakeidx} +\RequirePackage[bookmarks,raiselinks,pageanchor,hyperindex,colorlinks]{hyperref} +\RequirePackage{varwidth,cleveref,incgraph} + +\RequirePackage[a4paper,left=2.5cm,right=2.5cm,top=1.5cm,bottom=1.5cm, + marginparsep=3mm,marginparwidth=18mm, + headheight=0mm,headsep=0cm, + footskip=1.5cm,includeheadfoot%,showframe + ]{geometry} +\RequirePackage{fancyhdr} +\fancyhf{} +\fancyfoot[C]{\thepage}% +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\footrulewidth}{0pt} +\pagestyle{fancy} +\tolerance=2000% +\setlength{\emergencystretch}{20pt}% + +\RequirePackage{array,tabularx,booktabs} +\RequirePackage{lipsum} +\RequirePackage[extendedchars,encoding,filenameencoding=utf-8]{grffile} +\RequirePackage{siunitx,xfp} + +\RequirePackage{tcolorbox} +\tcbuselibrary{skins,xparse,minted,breakable,documentation,raster} + +\providecommand\mrcpkgprefix{} +\RequirePackage{\mrcpkgprefix mercatormap} +\IfFileExists{../private/privatekeys.tex}{\input{../private/privatekeys.tex}}{} + +\RequirePackage{csquotes} +\RequirePackage[%style=authoryear, + style=numeric-comp, + sorting=nyt,urldate=long, + maxnames=8,minnames=8,abbreviate=false,backend=biber]{biblatex} +\DeclareFieldFormat{url}{\newline\url{#1}}% +\DeclareListFormat{language}{}% +\setlength{\bibitemsep}{\smallskipamount} + + +\definecolor{Green_Dark}{rgb}{0.078431,0.407843,0.176471} +\definecolor{Blue_Dark}{rgb}{0.090196,0.211765,0.364706} +\definecolor{Blue_Bright}{rgb}{0.858824,0.898039,0.945098} + +\colorlet{Blue_Gray}{blue!50!gray} + +\tcbset{skin=enhanced, + doc head={colback=yellow!10!white,interior style=fill}, + doc head key={colback=magenta!5!white,interior style=fill}, + color key=DarkViolet, + color value=Teal, + color color=Teal, + color counter=Orange!85!black, + color length=Orange!85!black, + index colorize, + index annotate, + beforeafter example/.style={ + before skip=4pt plus 2pt minus 1pt, + after skip=8pt plus 4pt minus 2pt + }, + docexample/.style={bicolor, + beforeafter example, + arc=0.66mm, + boxrule=0.33mm, + fonttitle=\bfseries, + fontlower=\footnotesize, + colframe=Blue_Gray, + colback=Blue_Gray!5!white, + colbacklower=white, + drop small lifted shadow, + listing engine=minted, + documentation minted options={tabsize=2,fontsize=\small,breaklines,autogobble}, + documentation minted style=colorful, + }, +} +\urlstyle{sf} + +\newtcblisting{fullexample}[1]{docexample,minted style=colorful, + listing and comment,pdf comment,freeze pdf,compilable listing,#1} + +\DeclareTotalTCBox{\myverb}{ O{} v }{tile,fontupper=\ttfamily,nobeforeafter, + tcbox raise base,boxsep=0.5mm,top=0pt,bottom=0pt,left=0pt,right=0pt,boxrule=0.3mm, + colback=yellow!10, + borderline horizontal={0.3mm}{0pt}{red!50}, + #1}{#2} + +\tcbmakedocSubKey{docMrcKey}{mermap} +\tcbmakedocSubKey{docTikzKey}{tikz} + +\def\tikzname{\textup{Ti\textit{k}Z}} + +\let\docNode\docValue diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.versionhistory.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.versionhistory.tex new file mode 100644 index 00000000000..9d5ece4dff5 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.doc.versionhistory.tex @@ -0,0 +1,11 @@ +% !TeX root = mercatormap.tex +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +% include file of mercatormap.tex (manual of the LaTeX package mercatormap) +\clearpage +\section{Version History}% + +\section*{v1.00 (2020/04/20)} +\begin{itemize} +\item Initial public release. +\end{itemize} diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.pdf b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.pdf Binary files differnew file mode 100644 index 00000000000..15bb306604f --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.pdf diff --git a/Master/texmf-dist/doc/latex/mercatormap/mercatormap.tex b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.tex new file mode 100644 index 00000000000..cba748e1815 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mercatormap/mercatormap.tex @@ -0,0 +1,98 @@ +% \LaTeX-Main\ +% !TeX encoding=UTF-8 +% !TeX spellcheck=en_US +%% +%% The LaTeX package mercatormap - version 1.00 (2020/04/20) +%% mercatormap.tex: Manual +%% +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2020 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de> +%% ------------------------------------------------------------------------------------------- +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This work consists of all files listed in README +%% +% arara: pdflatex: { shell: yes } +% arara: biber +% arara: pdflatex: { shell: yes } +% arara: pdflatex: { shell: yes } +% arara: pdflatex: { shell: yes, synctex: yes } +\documentclass[a4paper,11pt]{ltxdoc} +\usepackage{mercatormap.doc} + +% The following personal API-keys are needed for compilation +% \mrcsetapikey{openrouteservice}{YOUR-API-KEY} % registered key +% \mrcsetapikey{thunderforest}{YOUR-API-KEY} % registered key + +\def\version{1.00}% +\def\datum{2020/04/20}% + +\mrcactivatescript% activates Python script + +\addbibresource{mercatormap.bib} + +\hypersetup{ + pdftitle={Manual for the mercatormap package}, + pdfauthor={Thomas F. Sturm}, + pdfsubject={Map drawing based on pixel map tiles with mercator projection}, + pdfkeywords={map tiles, mercator projection, map drawing} +} + +\makeindex + +\usetikzlibrary{external} +\tikzsetexternalprefix{_figures/} +\tikzexternalize +\tikzexternaldisable% for final version +\tcbset{shield externalize} + +\nocite{Sturm:2020,package:tikz,package:xparse,package:siunitx,package:expl3} + +\pdfsuppresswarningpagegroup=1 + +%\includeonly{mercatormap.doc.intro} +%\includeonly{mercatormap.doc.examples} +%\includeonly{mercatormap.doc.definition} +%\includeonly{mercatormap.doc.maptiles} +%\includeonly{mercatormap.doc.drawing} +%\includeonly{mercatormap.doc.scales} +%\includeonly{mercatormap.doc.marker} +%\includeonly{mercatormap.doc.routes} +%\includeonly{mercatormap.doc.orthodromes} +%\includeonly{mercatormap.doc.limitations} +%\includeonly{mercatormap.doc.versionhistory} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} + +\input{mercatormap.doc.abstract.tex} +\include{mercatormap.doc.intro} +\include{mercatormap.doc.examples} +\include{mercatormap.doc.definition} +\include{mercatormap.doc.maptiles} +\include{mercatormap.doc.drawing} +\include{mercatormap.doc.scales} +\include{mercatormap.doc.marker} +\include{mercatormap.doc.routes} +\include{mercatormap.doc.orthodromes} +\include{mercatormap.doc.limitations} +\include{mercatormap.doc.versionhistory} + +\clearpage +\phantomsection +\printbibliography[heading=bibintoc] + +\clearpage +\phantomsection +\printindex + +\end{document} diff --git a/Master/texmf-dist/tex/latex/mercatormap/mercatormap.sty b/Master/texmf-dist/tex/latex/mercatormap/mercatormap.sty new file mode 100644 index 00000000000..d05872b77fe --- /dev/null +++ b/Master/texmf-dist/tex/latex/mercatormap/mercatormap.sty @@ -0,0 +1,2294 @@ +%% The LaTeX package mercatormap - version 1.00 (2020/04/20) +%% mercatormap.sty: geographic coordinates (Mercator projection) and map tiles for TikZ pictures +%% +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2020 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de> +%% ------------------------------------------------------------------------------------------- +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This work consists of all files listed in README +%% +\RequirePackage{expl3}[2020/02/25] +\RequirePackage{xparse} +\ProvidesExplPackage{mercatormap}{2020/04/20}{1.00} + {A Web Mercator projection package with map tile support} +\@ifpackagelater { expl3 } { 2020/02/25 } + { } + { + \PackageError { mercatormap } { Support~package~expl3~too~old } + { + You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~ + 'l3packages'.\MessageBreak + Loading~mercatormap~will~abort! + } + \tex_endinput:D + } + +\RequirePackage{siunitx} +\RequirePackage{graphicx,tikz,pdftexcmds} + +\ExplSyntaxOff +% space character problem if within explSyntax +\usetikzlibrary{shadings} +\ExplSyntaxOn + +%\debug_on:n {all} + + +\ProvideExpandableDocumentCommand \mrcpkgprefix {}{} + +\NewDocumentCommand\mermapset{ m } { \keys_set:nn { mermap } {#1} } +\NewDocumentCommand\mermapsetsupply{ m } { \keys_set:nn { mermap/supply } {#1} } +\NewDocumentCommand\mermapsetmarker{ m } { \keys_set:nn { mermap/marker } {#1} } + + +%---- constants ---------------------------------------------------------------- + + +\fp_const:Nn \c__mermap_scale_radius_fp { 6371*pi/180 } +\fp_const:Nn \c__mermap_mean_radius_fp { 637100000cm } +\fp_const:Nn \c__mermap_mile_fp { 1.609344 } + + +%---- map definition ----------------------------------------------------------- + +\dim_new:N \l__mermap_tile_size_dim + +\fp_new:N \l__mermap_mapeast_fp +\fp_new:N \l__mermap_mapnorth_fp +\fp_new:N \l__mermap_mapsouth_fp +\fp_new:N \l__mermap_mapwest_fp +\fp_new:N \l__mermap_tex_height_fp +\fp_new:N \l__mermap_tex_width_fp +\fp_new:N \l__mermap_tile_northoffset_fp +\fp_new:N \l__mermap_tile_southoffset_fp +\fp_new:N \l__mermap_tile_westoffset_fp + +\int_new:N \l__mermap_tile_xmax_int +\int_new:N \l__mermap_tile_xmin_int +\int_new:N \l__mermap_tile_ymax_int +\int_new:N \l__mermap_tile_ymin_int +\int_new:N \l__mermap_tile_zoom_int + +\tl_new:N \l__mermap_attribution_print_tl +\tl_new:N \l__mermap_attribution_tl +\tl_new:N \l__mermap_pixel_height_tl +\tl_new:N \l__mermap_pixel_width_tl +\tl_new:N \l__mermap_tile_basename_tl +\tl_new:N \l__mermap_tile_resource_tl + + +\keys_define:nn { mermap/mapdef } + { + west .fp_set:N = \l__mermap_mapwest_fp, + east .fp_set:N = \l__mermap_mapeast_fp, + north .fp_set:N = \l__mermap_mapnorth_fp, + south .fp_set:N = \l__mermap_mapsouth_fp, + zoom .int_set:N = \l__mermap_tile_zoom_int, + xmin .int_set:N = \l__mermap_tile_xmin_int, + ymin .int_set:N = \l__mermap_tile_ymin_int, + xmax .int_set:N = \l__mermap_tile_xmax_int, + ymax .int_set:N = \l__mermap_tile_ymax_int, + pixelwidth .tl_set:N = \l__mermap_pixel_width_tl, + pixelheight .tl_set:N = \l__mermap_pixel_height_tl, + westoffset .fp_set:N = \l__mermap_tile_westoffset_fp, + northoffset .fp_set:N = \l__mermap_tile_northoffset_fp, + southoffset .fp_set:N = \l__mermap_tile_southoffset_fp, + basename .tl_set:N = \l__mermap_tile_basename_tl, + resource .tl_set:N = \l__mermap_tile_resource_tl, + attribution .tl_set:N = \l__mermap_attribution_tl, + attribution~print .tl_set:N = \l__mermap_attribution_print_tl, + tile~size .dim_set:N = \l__mermap_tile_size_dim, + } + + +\NewDocumentCommand{\mrcdefinemap}{ m } + { + \keys_set:nn { mermap/mapdef } + { + west=11, + east=13, + north=50, + south=48, + zoom=9, + xmin=271, + ymin=173, + xmax=275, + ymax=177, + pixelwidth=100, + pixelheight=100, + westoffset=0, + northoffset=0, + southoffset=0, + basename=tiles/tile, + resource=none, + attribution=, + attribution~print=, + #1 + } + \__mermap_reset: + } + + + +%---- coordinate system -------------------------------------------------------- + +\fp_new:N \l__mermap_cs_lat_fp +\fp_new:N \l__mermap_cs_lon_fp +\fp_new:N \l__mermap_cs_southreference_fp +\fp_new:N \l__mermap_cs_x_fp +\fp_new:N \l__mermap_cs_xfactor_fp +\fp_new:N \l__mermap_cs_y_fp +\fp_new:N \l__mermap_cs_yfactor_fp +\fp_new:N \l__mermap_result_fp +\fp_new:N \l__mermap_scale_denominator_fp +\fp_new:N \l__mermap_scale_fp +\fp_new:N \l__mermap_vic_dim_fp +\fp_new:N \l__mermap_vic_east_fp +\fp_new:N \l__mermap_vic_north_fp +\fp_new:N \l__mermap_vic_south_fp +\fp_new:N \l__mermap_vic_west_fp +\fp_new:N \l__mermap_vic_westeast_fp +\fp_new:N \l__mermap_westeast_fp + +\int_new:N \l__mermap_tile_number_int + + +\keys_define:nn { mermap } + { + vicinity .fp_set:N = \l__mermap_vic_dim_fp + } +\keys_set:nn { mermap } { vicinity=2cm } + + +\NewExpandableDocumentCommand\mrcmapwest{}{\fp_to_decimal:N \l__mermap_mapwest_fp} +\NewExpandableDocumentCommand\mrcmapeast{}{\fp_to_decimal:N \l__mermap_mapeast_fp} +\NewExpandableDocumentCommand\mrcmapnorth{}{\fp_to_decimal:N \l__mermap_mapnorth_fp} +\NewExpandableDocumentCommand\mrcmapsouth{}{\fp_to_decimal:N \l__mermap_mapsouth_fp} +\NewExpandableDocumentCommand\mrcpixelwidth{}{\tl_use:N \l__mermap_pixel_width_tl} +\NewExpandableDocumentCommand\mrcpixelheight{}{\tl_use:N \l__mermap_pixel_height_tl} +\NewDocumentCommand\mrcmapattribution{}{\tl_use:N \l__mermap_attribution_tl} +\NewDocumentCommand\mrcmapattributionprint{}{\tl_use:N \l__mermap_attribution_print_tl} +\NewExpandableDocumentCommand\mrctexwidth{}{\fp_to_dim:N \l__mermap_tex_width_fp} +\NewExpandableDocumentCommand\mrctexheight{}{\fp_to_dim:N \l__mermap_tex_height_fp} +\NewExpandableDocumentCommand\mrcscale{}{\fp_to_decimal:N \l__mermap_scale_fp} +\NewExpandableDocumentCommand\mrcmapscaledenominator{}{\fp_to_decimal:N \l__mermap_scale_denominator_fp} + + +\cs_new_nopar:Npn \__mermap_reset: + { + \int_set:Nn \l__mermap_tile_number_int { \fp_to_int:n { 2^\l__mermap_tile_zoom_int }} + \fp_set:Nn \l__mermap_westeast_fp { \l__mermap_mapeast_fp-\l__mermap_mapwest_fp } + \fp_set:Nn \l__mermap_cs_xfactor_fp { \l__mermap_tile_size_dim*\l__mermap_tile_number_int/360 } + \fp_set:Nn \l__mermap_cs_yfactor_fp { \l__mermap_tile_size_dim*\l__mermap_tile_number_int/2pi } + \fp_set:Nn \l__mermap_cs_southreference_fp { tand(\l__mermap_mapsouth_fp/2+45) } + + \__mermap_longitude_to_x:n { \l__mermap_mapwest_fp } + \__mermap_x_to_longitude:n { \l__mermap_cs_x_fp - \l__mermap_vic_dim_fp } + \fp_set_eq:NN \l__mermap_vic_west_fp \l__mermap_cs_lon_fp + + \__mermap_longitude_to_x:n { \l__mermap_mapeast_fp } + \__mermap_x_to_longitude:n { \l__mermap_cs_x_fp + \l__mermap_vic_dim_fp } + \fp_set_eq:NN \l__mermap_vic_east_fp \l__mermap_cs_lon_fp + + \__mermap_latitude_to_y:n { \l__mermap_mapsouth_fp } + \__mermap_y_to_latitude:n { \l__mermap_cs_y_fp - \l__mermap_vic_dim_fp } + \fp_set_eq:NN \l__mermap_vic_south_fp \l__mermap_cs_lat_fp + + \__mermap_latitude_to_y:n { \l__mermap_mapnorth_fp } + \fp_set_eq:NN \l__mermap_tex_height_fp \l__mermap_cs_y_fp + \__mermap_y_to_latitude:n { \l__mermap_cs_y_fp + \l__mermap_vic_dim_fp } + \fp_set_eq:NN \l__mermap_vic_north_fp \l__mermap_cs_lat_fp + + \fp_set:Nn \l__mermap_tex_width_fp { \l__mermap_westeast_fp*\l__mermap_cs_xfactor_fp } + + \fp_set:Nn \l__mermap_vic_westeast_fp { \l__mermap_vic_east_fp - \l__mermap_vic_west_fp } + + \__mermap_mean_latitude:NN \l__mermap_mapsouth_fp \l__mermap_mapnorth_fp + \fp_set:Nn \l__mermap_scale_denominator_fp { 2*\c__mermap_mean_radius_fp + *cosd(\l__mermap_result_fp)*pi/\l__mermap_tile_number_int/\l__mermap_tile_size_dim } + \fp_set:Nn \l__mermap_scale_fp { \l__mermap_scale_denominator_fp / (1cm*100000) } + + \__mermap_if_inside_picture_environment:T + { + \node[name=mrcmap,at={(0,0)},above~right, + line~width=0mm,inner~sep=0mm,outer~sep=0mm,draw=none,fill=none,rectangle, + minimum~width=\mrctexwidth,minimum~height=\mrctexheight]{}; + } + } + + +\cs_new_nopar:Npn \__mermap_mean_latitude:NN #1#2 + { + \fp_set:Nn \l__mermap_result_fp { 2*atand(sqrt(tand(#1/2+45)*tand(#2/2+45))) - 90 } + } + + +\cs_new_nopar:Npn \__mermap_longitude_to_x:n #1 + { + \fp_set:Nn \l_tmpa_fp { #1-\l__mermap_mapwest_fp } + \fp_sub:Nn \l_tmpa_fp { 360*floor(\l_tmpa_fp/360) } + \fp_set:Nn \l_tmpa_fp + { \l_tmpa_fp>\l__mermap_westeast_fp + ?(\l_tmpa_fp-\l__mermap_westeast_fp>360-\l_tmpa_fp + ?\l_tmpa_fp-360 + :\l_tmpa_fp) + :\l_tmpa_fp + } + \fp_set:Nn \l__mermap_cs_x_fp { \l_tmpa_fp*\l__mermap_cs_xfactor_fp } + } + + +\cs_new_nopar:Npn \__mermap_latitude_to_y:n #1 + { + \fp_set:Nn \l__mermap_cs_y_fp + { + ln( tand((#1)/2+45)/\l__mermap_cs_southreference_fp ) * \l__mermap_cs_yfactor_fp + } + } + + +\cs_new_nopar:Npn \__mermap_x_to_longitude:n #1 + { + \fp_set:Nn \l__mermap_cs_lon_fp { \l__mermap_mapwest_fp+(#1)/\l__mermap_cs_xfactor_fp } + } + + +\cs_new_nopar:Npn \__mermap_y_to_latitude:n #1 + { + \fp_set:Nn \l__mermap_cs_lat_fp + { + 2*atand( \l__mermap_cs_southreference_fp*exp((#1)/\l__mermap_cs_yfactor_fp) ) - 90 + } + } + + +\cs_new_nopar:Npn \__mermap_pgfpoint:nn #1#2 + { + \__mermap_latitude_to_y:n {#1} + \__mermap_longitude_to_x:n {#2} + \pgfpoint{\fp_to_dim:N \l__mermap_cs_x_fp} + {\fp_to_dim:N \l__mermap_cs_y_fp} + } + + +\use:x + { + \cs_new_nopar:Npn \exp_not:N\__mermap_pgfpoint:w ##1 \c_colon_str ##2 \exp_not:N \q_stop + } + { + \__mermap_pgfpoint:nn {#1}{#2} + } + + +\cs_new_nopar:Npn \__mermap_pgfpoint:n #1 + { + \__mermap_pgfpoint:w #1 \q_stop + } + + +\NewDocumentCommand{\mrcpgfpoint}{ mm }{ \__mermap_pgfpoint:nn {#1}{#2} } + + +\keys_define:nn { mermap/cs } + { + latitude .code:n = \__mermap_latitude_to_y:n {#1}, + longitude .code:n = \__mermap_longitude_to_x:n{#1}, + lat .code:n = \__mermap_latitude_to_y:n {#1}, + lon .code:n = \__mermap_longitude_to_x:n{#1}, + } + + +\tikzdeclarecoordinatesystem{__mrc} + { + \__mermap_pgfpoint:nn #1 + } + + +\tikzdeclarecoordinatesystem{mrcq} + { + \__mermap_pgfpoint:w #1 \q_stop + } + + +\tikzdeclarecoordinatesystem{mrc}% + { + \keys_set:nn { mermap/cs }{ #1 } + \pgfpoint{\fp_to_dim:N \l__mermap_cs_x_fp} + {\fp_to_dim:N \l__mermap_cs_y_fp} + } + + +\prg_new_conditional:Npnn \__mermap_if_in_map:nn #1#2 { p, TF } + { + \fp_compare:nNnTF {#1} > \l__mermap_mapnorth_fp + { + \prg_return_false: + } + { + \fp_compare:nNnTF {#1} < \l__mermap_mapsouth_fp + { + \prg_return_false: + } + { + \fp_set:Nn \l_tmpa_fp { #2-\l__mermap_mapwest_fp } + \fp_sub:Nn \l_tmpa_fp { 360*floor(\l_tmpa_fp/360) } + \fp_compare:nNnTF \l_tmpa_fp > \l__mermap_westeast_fp + { + \prg_return_false: + } + { + \fp_set:Nn \l__mermap_cs_x_fp { \l_tmpa_fp*\l__mermap_cs_xfactor_fp } + \__mermap_latitude_to_y:n {#1} + \pgfnoderename{mrclastpos}{mrcpos} + \pgfcoordinate{mrcpos}{ + \pgfpoint{\fp_to_dim:N \l__mermap_cs_x_fp} + {\fp_to_dim:N \l__mermap_cs_y_fp} + } + \prg_return_true: + } + } + } + } + +\NewDocumentCommand{\ifmrcinmap}{ mm } + { + \__mermap_if_in_map:nnTF{#1}{#2} + } + + +\prg_new_conditional:Npnn \__mermap_if_in_vicinity:nn #1#2 { p, TF } + { + \fp_compare:nNnTF {#1} > \l__mermap_vic_north_fp + { + \prg_return_false: + } + { + \fp_compare:nNnTF {#1} < \l__mermap_vic_south_fp + { + \prg_return_false: + } + { + \fp_set:Nn \l_tmpa_fp { #2-\l__mermap_vic_west_fp } + \fp_sub:Nn \l_tmpa_fp { 360*floor(\l_tmpa_fp/360) } + \fp_compare:nNnTF \l_tmpa_fp > \l__mermap_vic_westeast_fp + { + \prg_return_false: + } + { + \fp_set:Nn \l__mermap_cs_x_fp { \l_tmpa_fp*\l__mermap_cs_xfactor_fp - \l__mermap_vic_dim_fp } + \__mermap_latitude_to_y:n {#1} + \pgfnoderename{mrclastpos}{mrcpos} + \pgfcoordinate{mrcpos}{ + \pgfpoint{\fp_to_dim:N \l__mermap_cs_x_fp} + {\fp_to_dim:N \l__mermap_cs_y_fp} + } + \prg_return_true: + } + } + } + } + +\NewDocumentCommand{\ifmrcinvicinity}{ mm } + { + \__mermap_if_in_vicinity:nnTF{#1}{#2} + } + + + + +%---- named positions ---------------------------------------------------------- + + +\cs_new_nopar:Npn \__mermap_set_named_position #1#2#3 + { + \cs_set_nopar:cpx {__mermap__lat__#1} { \fp_to_decimal:n {#2} } + \cs_set_nopar:cpx {__mermap__lon__#1} { \fp_to_decimal:n {#3} } + } + + +\NewDocumentCommand{\mrcNPdef}{ mmm } + { + \__mermap_set_named_position{#1}{#2}{#3} + } + + +\NewDocumentCommand{\mrcNPfrompoint}{ mm } + { + \path (#2); + \__mermap_y_to_latitude:n {\pgf@y} + \__mermap_x_to_longitude:n{\pgf@x} + \__mermap_set_named_position {#1} + {\fp_to_decimal:N \l__mermap_cs_lat_fp} + {\fp_to_decimal:N \l__mermap_cs_lon_fp} + } + + +\msg_new:nnnn{ mercatormap }{ np-undefined } + { Named~point~'#1'~is~undefined. } + { + The~named~point~'#1'~is~not~known:~ + perhaps~it~is~spelled~incorrectly. + } + + +\NewExpandableDocumentCommand \mrcNPlat { m } + { + \cs_if_exist_use:cF{__mermap__lat__#1} + { + \msg_error:nnx{ mercatormap }{ np-undefined }{ #1 } + } + } + + +\NewExpandableDocumentCommand \mrcNPlon { m } + { + \cs_if_exist_use:cF{__mermap__lon__#1} + { + \msg_error:nnx{ mercatormap }{ np-undefined }{ #1 } + } + } + + +\NewExpandableDocumentCommand \mrcNPcs { m } + { + __mrc~cs \c_colon_str {{\mrcNPlat{#1}}{\mrcNPlon{#1}}} + } + + +\NewDocumentCommand{\ifmrcNPinmap}{ m } + { + \__mermap_if_in_map:nnTF{\mrcNPlat{#1}}{\mrcNPlon{#1}} + } + + +\NewDocumentCommand{\ifmrcNPinvicinity}{ m } + { + \__mermap_if_in_vicinity:nnTF{\mrcNPlat{#1}}{\mrcNPlon{#1}} + } + + + +%---- map tile download -------------------------------------------------------- + +\group_begin: +\char_set_catcode_space:n {`\ } +\char_set_catcode_other:n {`\"} + +\tl_const:Nn \c__mermap_supply_call_boundaries_tl + {% + \l__mermap_python\c_space_tl boundaries + -u "\str_use:N\l__mermap_supply_url_str" + -at "\str_use:N\l__mermap_supply_attribution_str" + -atp "\str_use:N\l__mermap_supply_attribution_print_str" + -f "\l__mermap_supply_basename_tl" + -z \int_use:N\l__mermap_supply_zoom_int\c_space_tl + -w \fp_use:N\l__mermap_supply_west_fp\c_space_tl + -e \fp_use:N\l__mermap_supply_east_fp\c_space_tl + -n \fp_use:N\l__mermap_supply_north_fp\c_space_tl + -s \fp_use:N\l__mermap_supply_south_fp\c_space_tl + -p \l__mermap_supply_pixel_tl\c_space_tl + -ts \dim_use:N\l__mermap_tile_size_dim\c_space_tl + -t \l__mermap_supply_target_tl\c_space_tl + -d "\str_use:N\l__mermap_definition_id_str" + } + +\tl_const:Nn \c__mermap_supply_call_reference_tl + {% + \l__mermap_python\c_space_tl reference + -u "\str_use:N\l__mermap_supply_url_str" + -at "\str_use:N\l__mermap_supply_attribution_str" + -atp "\str_use:N\l__mermap_supply_attribution_print_str" + -f "\l__mermap_supply_basename_tl" + -mw \fp_use:N\l__mermap_supply_width_fp\c_space_tl + -mh \fp_use:N\l__mermap_supply_height_fp\c_space_tl + -z \int_use:N\l__mermap_supply_zoom_int\c_space_tl + -lat \fp_use:N\l__mermap_supply_latitude_fp\c_space_tl + -lon \fp_use:N\l__mermap_supply_longitude_fp\c_space_tl + -a \l__mermap_supply_align_tl\c_space_tl + -p \l__mermap_supply_pixel_tl\c_space_tl + -ts \dim_use:N\l__mermap_tile_size_dim\c_space_tl + -t \l__mermap_supply_target_tl\c_space_tl + -d "\str_use:N\l__mermap_definition_id_str" + } + + +\tl_const:Nn \c__mermap_supply_call_areafit_tl + {% + \l__mermap_python\c_space_tl areafit + -u "\str_use:N\l__mermap_supply_url_str" + -at "\str_use:N\l__mermap_supply_attribution_str" + -atp "\str_use:N\l__mermap_supply_attribution_print_str" + -f "\l__mermap_supply_basename_tl" + -mw \fp_use:N\l__mermap_supply_width_fp\c_space_tl + -mh \fp_use:N\l__mermap_supply_height_fp\c_space_tl + -w \fp_use:N\l__mermap_supply_west_fp\c_space_tl + -e \fp_use:N\l__mermap_supply_east_fp\c_space_tl + -n \fp_use:N\l__mermap_supply_north_fp\c_space_tl + -s \fp_use:N\l__mermap_supply_south_fp\c_space_tl + -a \l__mermap_supply_align_tl\c_space_tl + -p \l__mermap_supply_pixel_tl\c_space_tl + -ts \dim_use:N\l__mermap_tile_size_dim\c_space_tl + -t \l__mermap_supply_target_tl\c_space_tl + -d "\str_use:N\l__mermap_definition_id_str" + } + +\group_end: + + +\bool_new:N \l__mermap_script_activated_bool + +\fp_new:N \l__mermap_supply_east_fp +\fp_new:N \l__mermap_supply_height_fp +\fp_new:N \l__mermap_supply_latitude_fp +\fp_new:N \l__mermap_supply_longitude_fp +\fp_new:N \l__mermap_supply_north_fp +\fp_new:N \l__mermap_supply_south_fp +\fp_new:N \l__mermap_supply_west_fp +\fp_new:N \l__mermap_supply_width_fp + +\int_new:N \g__mermap_automap_int +\int_new:N \l__mermap_supply_zoom_int + +\iow_new:N \l__mermap_iow + +\prop_new:N \g__mermap_apikey_prop +\prop_new:N \g__mermap_definition_prop + +\str_new:N \l__mermap_definition_id_str +\str_new:N \l__mermap_definition_postfix_str +\str_new:N \l__mermap_definition_prefix_str +\str_new:N \l__mermap_supply_attribution_print_str +\str_new:N \l__mermap_supply_attribution_str +\str_new:N \l__mermap_supply_url_str + +\tl_new:N \l__mermap_last_mdfivesum_tl +\tl_new:N \l__mermap_mdfivesum_tl +\tl_new:N \l__mermap_python +\tl_new:N \l__mermap_supply_align_tl +\tl_new:N \l__mermap_supply_basename_tl +\tl_new:N \l__mermap_supply_call_tl +\tl_new:N \l__mermap_supply_pixel_tl +\tl_new:N \l__mermap_supply_target_tl +\tl_new:N \l__mermap_supply_type_tl + + +\use:x + { + \cs_new_nopar:Npn \exp_not:N\__mermap_supply_position:w ##1 \c_colon_str ##2 \exp_not:N \q_stop + } + { + \fp_set:Nn \l__mermap_supply_latitude_fp {#1} + \fp_set:Nn \l__mermap_supply_longitude_fp {#2} + } + + +\msg_new:nnnn{ mercatormap }{ api-key-undefined } + { Api~key~'#1'~is~undefined. } + { + You~have~to~set~\token_to_str:N \mrcsetapikey + \iow_char:N \{#1\iow_char:N \} + \iow_char:N \{your~key\iow_char:N \}~first. + } + +\cs_new:Npn \__mermap_supply_url_with_api_key:nnn #1#2#3 + { + \str_set:Nn \l__mermap_supply_url_str {#1} + \prop_get:NnNF \g__mermap_apikey_prop {#2} \l_tmpa_tl + { + \msg_error:nnx{ mercatormap }{ api-key-undefined }{ #2 } + } + \str_put_right:NV \l__mermap_supply_url_str \l_tmpa_tl + \str_put_right:Nn \l__mermap_supply_url_str {#3} + } + + +\cs_new:Npn \__mermap_supply_add_area_clist:N #1 + { + \clist_map_inline:Nn #1 + { + \cs_if_exist:cF{__mermap__lat__##1} + { + \msg_error:nnx{ mercatormap }{ np-undefined }{ ##1 } + } + \fp_set:Nn \l_tmpa_fp { \mrcNPlat{##1} } + \fp_compare:nNnT \l_tmpa_fp < \l__mermap_supply_south_fp + { \fp_set_eq:NN \l__mermap_supply_south_fp \l_tmpa_fp } + \fp_compare:nNnT \l_tmpa_fp > \l__mermap_supply_north_fp + { \fp_set_eq:NN \l__mermap_supply_north_fp \l_tmpa_fp } + \fp_set:Nn \l_tmpa_fp { \mrcNPlon{##1} } + \fp_compare:nNnT \l_tmpa_fp < \l__mermap_supply_west_fp + { \fp_set_eq:NN \l__mermap_supply_west_fp \l_tmpa_fp } + \fp_compare:nNnT \l_tmpa_fp > \l__mermap_supply_east_fp + { \fp_set_eq:NN \l__mermap_supply_east_fp \l_tmpa_fp } + } + } + + +\keys_define:nn { mermap/supply } + { + zoom .int_set:N = \l__mermap_supply_zoom_int, + west .fp_set:N = \l__mermap_supply_west_fp, + east .fp_set:N = \l__mermap_supply_east_fp, + north .fp_set:N = \l__mermap_supply_north_fp, + south .fp_set:N = \l__mermap_supply_south_fp, + latitude .fp_set:N = \l__mermap_supply_latitude_fp, + longitude .fp_set:N = \l__mermap_supply_longitude_fp, + position .code:n = {\__mermap_supply_position:w #1 \q_stop}, + named~position .meta:nn = {mermap/supply}{latitude=\mrcNPlat{#1},longitude=\mrcNPlon{#1}}, + width .fp_set:N = \l__mermap_supply_width_fp, + height .fp_set:N = \l__mermap_supply_height_fp, + align .tl_set:N = \l__mermap_supply_align_tl, + url .code:n = {\str_set:Nn\l__mermap_supply_url_str {#1}}, + url~with~api~key .code:n = {\__mermap_supply_url_with_api_key:nnn #1}, + basename .tl_set:N = \l__mermap_supply_basename_tl, + type .tl_set:N = \l__mermap_supply_type_tl, + target .tl_set:N = \l__mermap_supply_target_tl, + pixel .tl_set:N = \l__mermap_supply_pixel_tl, + attribution .code:n = { + \str_set:Nn \l__mermap_supply_attribution_str {#1} + \tl_set_rescan:Nnn \l__mermap_attribution_tl {}{#1} + }, + attribution~print .code:n = { + \str_set:Nn \l__mermap_supply_attribution_print_str {#1} + \tl_set_rescan:Nnn \l__mermap_attribution_print_tl {}{#1} + }, + dpi .code:n = { + \tl_set:Nx \l__mermap_supply_pixel_tl { + \fp_to_int:n { round(#1*\l__mermap_tile_size_dim/1in) } + }}, + tex~width .code:n = { + \fp_set:Nn \l__mermap_supply_width_fp{#1/\l__mermap_tile_size_dim}}, + tex~height .code:n = { + \fp_set:Nn \l__mermap_supply_height_fp{#1/\l__mermap_tile_size_dim}}, + source .code:n = { \exp_args:Nnx \keys_set:nn {mermap/supply} {_source=#1} }, + source .value_required:n = true, + _source .choice:, + area .code:n = + { + \clist_set:Nn \l_tmpa_clist { #1 } + \fp_set:Nn \l__mermap_supply_west_fp { inf } + \fp_set:Nn \l__mermap_supply_east_fp { -inf } + \fp_set:Nn \l__mermap_supply_south_fp { 89 } + \fp_set:Nn \l__mermap_supply_north_fp { -89 } + \__mermap_supply_add_area_clist:N \l_tmpa_clist + }, + area .value_required:n = true, + add~area .code:n = + { + \clist_set:Nn \l_tmpa_clist { #1 } + \__mermap_supply_add_area_clist:N \l_tmpa_clist + }, + flex~reference~scale .code:n = { + \__mermap_set_flex_scale:nn {#1} {\l__mermap_supply_latitude_fp} + }, + flex~reference~scale .value_required:n = true, + area~to~reference .code:n = { + \fp_set:Nn \l__mermap_supply_longitude_fp { (\l__mermap_supply_west_fp+\l__mermap_supply_east_fp)/2 } + \__mermap_mean_latitude:NN \l__mermap_supply_north_fp \l__mermap_supply_south_fp + \fp_set_eq:NN \l__mermap_supply_latitude_fp \l__mermap_result_fp + }, + area~to~reference .value_forbidden:n = true, + flex~area~scale .meta:nn = {mermap/supply}{area~to~reference,flex~reference~scale={#1}}, + flex~area~scale .value_required:n = true, + flex~area~fit .code:n = { + \fp_compare:nNnF \l__mermap_tile_size_dim = \l__mermap_flex_tile_size_dim + { + \fp_set:Nn \l_tmpa_fp { \l__mermap_tile_size_dim/\l__mermap_flex_tile_size_dim } + \fp_set:Nn \l__mermap_supply_width_fp{\l__mermap_supply_width_fp*\l_tmpa_fp} + \fp_set:Nn \l__mermap_supply_height_fp{\l__mermap_supply_height_fp*\l_tmpa_fp} + } + \fp_set:Nn \l__mermap_supply_width_fp{\l__mermap_supply_width_fp-(#1)/\l__mermap_flex_tile_size_dim} + \fp_set:Nn \l__mermap_supply_height_fp{\l__mermap_supply_height_fp-(#1)/\l__mermap_flex_tile_size_dim} + \fp_set:Nn \l_tmpa_fp { min ( 180*\l__mermap_supply_width_fp / (\l__mermap_supply_east_fp-\l__mermap_supply_west_fp) + , pi*\l__mermap_supply_height_fp / ln( tand(\l__mermap_supply_north_fp/2+45) / tand(\l__mermap_supply_south_fp/2+45) ) ) } + \fp_set:Nn \l_tmpb_fp { ln(\l_tmpa_fp)/ln(2) } + \fp_set:Nn \l_tmpb_fp { round(\l_tmpb_fp)/\l_tmpb_fp } + \fp_set:Nn \l_tmpb_fp { \l_tmpa_fp^(\l_tmpb_fp-1+0.0000001) } + \dim_set:Nn \l__mermap_tile_size_dim { \fp_to_dim:n { \l__mermap_flex_tile_size_dim / \l_tmpb_fp }} + \fp_set:Nn \l__mermap_supply_width_fp { \l__mermap_supply_width_fp * \l_tmpb_fp + (#1)/\l__mermap_tile_size_dim } + \fp_set:Nn \l__mermap_supply_height_fp { \l__mermap_supply_height_fp * \l_tmpb_fp + (#1)/\l__mermap_tile_size_dim } + }, + flex~area~fit .default:n = 0pt, + } + + +\keys_set:nn { mermap/supply } + { + zoom=9, + north=50, + south=48, + west=11, + east=13, + latitude=49, + longitude=12, + width=4, + height=4, + align=center, + basename=tiles/tile, + url=, + attribution=, + attribution~print=, + type=reference, + pixel=256, + target=tiles, + } + + +\keys_define:nn { mermap } + { + definition~prefix .code:n = {\str_set:Nn\l__mermap_definition_prefix_str{#1}}, + python .code:n = { + \tl_set:Nx \l__mermap_python {#1~maptiles.texpy} + }, + } + +\keys_set:nn { mermap } + { + definition~prefix = maps/, + python = python, + } + + +\msg_new:nnn { mercatormap }{ python-script } + { Python~script~'maptiles.texpy'~is~created~(for~map~tile~download). } + + +\NewDocumentCommand \mrcactivatescript {} + { + \msg_info:nn { mercatormap }{ python-script } + \group_begin: + \def\@latex@warning@no@line##1{}% suppress filecontents warning + \file_input:n {\mrcpkgprefix mercatorpy.def} + \group_end: + \bool_set_true:N \l__mermap_script_activated_bool + } +\@onlypreamble\mrcactivatescript + + +\NewDocumentCommand \mrcsetapikey { mm } + { + \prop_gput:Nnn \g__mermap_apikey_prop {#1}{#2} + } + + +\cs_new:Npn \__mermap_create_definition_id:n #1 + { + \tl_set:Nx \l_tmpa_tl {#1} + \tl_trim_spaces:N \l_tmpa_tl + \str_set:Nx \l__mermap_definition_postfix_str {\tl_to_str:N \l_tmpa_tl} + \str_concat:NNN \l__mermap_definition_id_str + \l__mermap_definition_prefix_str \l__mermap_definition_postfix_str + } + +\cs_new:Npn \__mermap_map:nn #1#2 + { + \tl_set:Nx \l_tmpa_tl {#2} + \tl_trim_spaces:N \l_tmpa_tl + \tl_if_empty:NT \l_tmpa_tl + { + \int_gincr:N \g__mermap_automap_int + \tl_set:Nx \l_tmpa_tl + { + automap- + \int_compare:nNnTF \g__mermap_automap_int<{10} {000} + { + \int_compare:nNnTF \g__mermap_automap_int<{100} {00} + { + \int_compare:nNnTF \g__mermap_automap_int<{1000} {0} {} + } + } + \int_use:N \g__mermap_automap_int + } + } + \str_set:Nx \l__mermap_definition_postfix_str {\tl_to_str:N \l_tmpa_tl} + \str_concat:NNN \l__mermap_definition_id_str + \l__mermap_definition_prefix_str \l__mermap_definition_postfix_str + \__mermap_supplymap:n {#1} + \__mermap_applymap: + } + +\NewDocumentCommand \mrcmap { O{} m } + { + \__mermap_map:nn {#1}{#2} + } + + +\msg_new:nnn{ mercatormap }{ definition-id-used } + { Map~definition~'#1'~already~existing } + + +\cs_new:Npn \__mermap_supplymap:n #1 + { + \group_begin: + \keys_set:nn { mermap/supply } { #1 } + \tl_set:Nx \l_tmpa_tl { \str_use:N\l__mermap_definition_id_str } + \prop_if_in:NVT \g__mermap_definition_prop \l_tmpa_tl + { + \msg_warning:nnx { mercatormap }{ definition-id-used }{ \tl_use:N \l_tmpa_tl } + } + \prop_gput:NVn \g__mermap_definition_prop \l_tmpa_tl {} + \bool_if:NT \l__mermap_script_activated_bool + { + \__mermap_supplymap_call: + } + %\dim_gset_eq:NN \g_tmpa_dim \l__mermap_tile_size_dim + \group_end: + %\dim_set_eq:NN \l__mermap_tile_size_dim \g_tmpa_dim + } + +\NewDocumentCommand \mrcsupplymap { O{} m } + { + \__mermap_create_definition_id:n {#2} + \__mermap_supplymap:n {#1} + } + + +\msg_new:nnn { mercatormap }{ shell-escape } + { You~must~invoke~LaTeX~with~the~--shell-escape~flag~to~produce~map~'#1'. } + +\msg_new:nnn { mercatormap }{ target-resource } + { Target~and~produced~resource~are~different~for~map~'#1'. } + +\msg_new:nnn { mercatormap }{ definition-production } + { Map~definition~file~not~produced~for~map~'#1'. } + +\cs_new:Npn \__mermap_supplymap_call: + { + \tl_set_eq:Nc \l_tmpa_tl { + c__mermap_supply_call_\l__mermap_supply_type_tl _tl } + \tl_set:Nx \l__mermap_supply_call_tl \l_tmpa_tl + \tl_set:Nx \l__mermap_mdfivesum_tl { \pdf@mdfivesum{\l__mermap_supply_call_tl} } + \tl_clear:N \l__mermap_last_mdfivesum_tl + \file_if_exist_input:n {\l__mermap_definition_id_str.md5} + \str_if_eq:VVTF \l__mermap_mdfivesum_tl \l__mermap_last_mdfivesum_tl + { + \file_if_exist:nF {\l__mermap_definition_id_str.def} + { + \__mermap_supplymap_call_shell: + } + } + { + \__mermap_supplymap_call_shell: + } + } + +\cs_new:Npn \__mermap_supplymap_call_shell: + { + \sys_if_shell_unrestricted:TF + { + \file_if_exist:nT {\l__mermap_definition_id_str.def} + { + \iow_open:Nn \l__mermap_iow {\l__mermap_definition_id_str.def} + \iow_now:Nx \l__mermap_iow {\c_backslash_str def \c_backslash_str mrcdefinemap{} \c_percent_str} + \iow_close:N \l__mermap_iow + } + + \sys_shell_now:x {\l__mermap_supply_call_tl} + + \file_if_exist:nTF {\l__mermap_definition_id_str.def} + { + \file_input:n {\l__mermap_definition_id_str.def} + \str_if_eq:VVTF \l__mermap_supply_target_tl \l__mermap_tile_resource_tl + { + \__mermap_write_mdfive:n {\l__mermap_mdfivesum_tl} + } + { + \__mermap_write_mdfive:n {false} + \msg_warning:nnx { mercatormap }{ target-resource }{ \l__mermap_definition_id_str } + } + } + { + \__mermap_write_mdfive:n {false} + \msg_warning:nnx { mercatormap }{ definition-production }{ \l__mermap_definition_id_str } + } + } + { + \__mermap_write_mdfive:n {false} + \msg_warning:nnx { mercatormap }{ shell-escape }{ \l__mermap_definition_id_str } + } + } + +\NewDocumentCommand \mermaplastfivesum { m } +{ + \tl_set:Nx \l__mermap_last_mdfivesum_tl { #1 } +} + +\cs_new:Npn \__mermap_write_mdfive:n #1 + { + \iow_open:Nn \l__mermap_iow {\l__mermap_definition_id_str.md5} + \iow_now:Nx \l__mermap_iow {\c_backslash_str mermaplastfivesum{#1} \c_percent_str} + \iow_close:N \l__mermap_iow + } + + + +%---- map drawing -------------------------------------------------------------- + + +\dim_new:N \l__mermap_flex_tile_size_dim +\dim_new:N \l__mermap_tx_dim +\dim_new:N \l__mermap_ty_dim + +\int_new:N \l__mermap_tile_x_int +\int_new:N \l__mermap_tile_xmod_int +\int_new:N \l__mermap_tile_y_int + +\tl_new:N \l__mermap_current_map_tl +\tl_new:N \l__mermap_draw_map_tl +\tl_new:N \l__mermap_tikz_map_clip_tl +\tl_new:N \l__mermap_tile_filename_tl + + +\prg_new_conditional:Npnn \__mermap_if_inside_picture_environment: { p, TF, T } + { + \cs_if_exist:NTF \pgfpictureid + { + \prg_return_true: + } + { + \prg_return_false: + } + } + + + +\cs_new_nopar:Npn \__mermap_set_flex_scale:nn #1#2 + { + \fp_set:Nn \l_tmpa_fp { 1+ln(\c__mermap_mean_radius_fp/#1*cosd(#2)*pi/\l__mermap_flex_tile_size_dim)/ln(2) } + \keys_set:nn { mermap }{ flex~zoom=\l_tmpa_fp } + } + +\use:x + { + \cs_new_nopar:Npn \exp_not:N\__mermap_set_flex_scale:w ##1 \c_colon_str ##2 \exp_not:N \q_stop + } + { + \__mermap_set_flex_scale:nn {#1}{#2} + } + +\use:x + { + \cs_new_nopar:Npn \exp_not:N\__mermap_set_named_flex_scale:w ##1 \c_colon_str ##2 \exp_not:N \q_stop + } + { + \__mermap_set_flex_scale:nn {#1}{\mrcNPlat{#2}} + } + + +\keys_define:nn { mermap } + { + tile~size .dim_set:N = \l__mermap_tile_size_dim, + flex~tile~size .dim_set:N = \l__mermap_flex_tile_size_dim, + flex~zoom .code:n = + { + \int_set:Nn \l__mermap_supply_zoom_int {\fp_to_int:n{round(#1)}} + \dim_set:Nn \l__mermap_tile_size_dim {\fp_to_dim:n{\l__mermap_flex_tile_size_dim*2^(#1-\l__mermap_supply_zoom_int)}} + }, + flex~scale .code:n = {\__mermap_set_flex_scale:w #1 \q_stop}, + named~flex~scale .code:n = {\__mermap_set_named_flex_scale:w #1 \q_stop}, + map~clip .tl_set:N = \l__mermap_tikz_map_clip_tl, + map~scope .code:n = {\tikzset{mermap_scope_style/.style={#1}}}, + map~path .code:n = {\tikzset{mermap_path_style/.style={#1}}}, + draw .tl_set:N = \l__mermap_draw_map_tl, + } + + +\keys_set:nn { mermap } + { + tile~size = 32.512mm, + flex~tile~size = 32.512mm, + map~clip=\mrcclipmap, + draw=auto, + map~scope=, + map~path={upper~left=green!50, upper~right=green!25, + lower~left=green!50!black!50, lower~right=green!25}, + } + + +\NewDocumentCommand \mrcclipmap {} + {\path[clip] (mrcmap.south~west) rectangle (mrcmap.north~east);} + +\NewDocumentCommand \mrcboundmap {} + {\path[use~as~bounding~box] (mrcmap.south~west) rectangle (mrcmap.north~east);} + + +\cs_new_nopar:Npn \__mermap_drawmap_path: + { + \begin{scope}[ + xshift=\fp_to_dim:n{ (0.5-\l__mermap_tile_westoffset_fp)*\l__mermap_tile_size_dim }, + yshift=\fp_to_dim:n{ (0.5-\l__mermap_tile_southoffset_fp)*\l__mermap_tile_size_dim }, + mermap_scope_style] + \tl_use:N \l__mermap_tikz_map_clip_tl + \path[mermap_path_style] (mrcmap.south~west) rectangle (mrcmap.north~east); + \end{scope} + } + + +\cs_new_nopar:Npn \__mermap_drawtile: + { + \tl_set:Nx \l__mermap_tile_filename_tl + { + \exp_not:o\l__mermap_tile_basename_tl + _\int_use:N\l__mermap_tile_zoom_int + _\int_use:N\l__mermap_tile_xmod_int + _\int_use:N\l__mermap_tile_y_int + .png + } + \file_if_exist:nTF \l__mermap_tile_filename_tl + { + \node[line~width=0mm,inner~sep=0mm,outer~sep=0mm,draw=none,fill=none,rectangle] + at (\l__mermap_tx_dim,\l__mermap_ty_dim) + {\includegraphics[width=\l__mermap_tile_size_dim]{\l__mermap_tile_filename_tl}}; + } + { + \path[mermap_path_style] (\l__mermap_tx_dim,\l__mermap_ty_dim) + ++(-\l__mermap_tile_size_dim/2,-\l__mermap_tile_size_dim/2) + rectangle +(\l__mermap_tile_size_dim,\l__mermap_tile_size_dim); + } + } + + +\cs_new_nopar:Npn \__mermap_drawmap_tiles: + { + \begin{scope}[ + xshift=\fp_to_dim:n{ (0.5-\l__mermap_tile_westoffset_fp)*\l__mermap_tile_size_dim }, + yshift=\fp_to_dim:n{ (0.5-\l__mermap_tile_southoffset_fp)*\l__mermap_tile_size_dim }, + mermap_scope_style] + \tl_use:N \l__mermap_tikz_map_clip_tl + \int_set_eq:NN \l__mermap_tile_x_int \l__mermap_tile_xmin_int + \dim_set:Nn \l__mermap_tx_dim {0pt} + \int_until_do:nNnn \l__mermap_tile_x_int > \l__mermap_tile_xmax_int + { + \dim_set:Nn \l__mermap_ty_dim {0pt} + \int_set:Nn \l__mermap_tile_xmod_int {\int_mod:nn{\l__mermap_tile_x_int}{\l__mermap_tile_number_int}} + \int_compare:nNnT \l__mermap_tile_xmod_int < 0 + { + \int_add:Nn \l__mermap_tile_xmod_int \l__mermap_tile_number_int + } + \int_set_eq:NN \l__mermap_tile_y_int \l__mermap_tile_ymax_int + \int_until_do:nNnn \l__mermap_tile_y_int < \l__mermap_tile_ymin_int + { + \int_compare:nNnF \l__mermap_tile_y_int < 0 + { + \int_compare:nNnT \l__mermap_tile_y_int < \l__mermap_tile_number_int + { + \__mermap_drawtile: + } + } + \dim_add:Nn \l__mermap_ty_dim \l__mermap_tile_size_dim + \int_decr:N \l__mermap_tile_y_int + } + \dim_add:Nn \l__mermap_tx_dim \l__mermap_tile_size_dim + \int_incr:N \l__mermap_tile_x_int + } + \end{scope} + } + + +\cs_new_nopar:Npn \__mermap_drawsinglemap: + { + \begin{scope}[mermap_scope_style] + \tl_use:N \l__mermap_tikz_map_clip_tl + \node[above~right,line~width=0mm,inner~sep=0mm,outer~sep=0mm,draw=none,fill=none,rectangle] at (0,0) + {\includegraphics[width=\mrctexwidth,height=\mrctexheight]{\l__mermap_definition_id_str.png}}; + \end{scope} + } + + +\cs_new_nopar:Npn \__mermap_drawmap_mergedmap: + { + \str_if_eq:VnTF \l__mermap_tile_resource_tl {mergedmap} + { + \__mermap_drawsinglemap: + } + { + \__mermap_drawmap_path: + } + } + + +\cs_new_nopar:Npn \__mermap_drawmap_wmsmap: + { + \str_if_eq:VnTF \l__mermap_tile_resource_tl {wmsmap} + { + \__mermap_drawsinglemap: + } + { + \__mermap_drawmap_path: + } + } + + +\msg_new:nnn{ mercatormap }{ draw-auto } + { 'draw=auto' -> 'draw=#1'~is~undefined. } + + +\cs_new_nopar:Npn \__mermap_drawmap_auto: + { + \cs_if_exist:cTF {__mermap_drawmap_\l__mermap_tile_resource_tl :} + { + \use:c {__mermap_drawmap_\l__mermap_tile_resource_tl :} + } + { + \str_if_eq:VnTF \l__mermap_tile_resource_tl {none} + { + \__mermap_drawmap_path: + } + { + \msg_warning:nnx { mercatormap }{ draw-undefined }{ \tl_use:N \l__mermap_tile_resource_tl } + } + } + } + + +\msg_new:nnnn{ mercatormap }{ draw-undefined } + { 'draw=#1'~is~undefined. } + { + The~option~value~'#1'~is~not~known~for~'draw': + perhaps~it~is~spelled~incorrectly. + } + +\NewDocumentCommand \mrcdrawmap { o } + { + \group_begin: + \IfNoValueF {#1} + { \keys_set:nn { mermap } {#1} } + \cs_if_exist:cTF {__mermap_drawmap_\l__mermap_draw_map_tl :} + { + \use:c {__mermap_drawmap_\l__mermap_draw_map_tl :} + } + { + \msg_warning:nnx { mercatormap }{ draw-undefined }{ \tl_use:N \l__mermap_draw_map_tl } + } + \group_end: + } + + +\cs_new_nopar:Npn \__mermap_applymap: + { + \file_input:n {\l__mermap_definition_id_str.def} + } + + +\NewDocumentCommand \mrcapplymap { m } + { + \__mermap_create_definition_id:n {#1} + \__mermap_applymap: + } + + +\cs_new_nopar:Npn \__mermap_drawinfo: + { + \begin{scope}[every~node/.style={fill=white,fill~opacity=0.8,text~opacity=1,font=\sffamily\footnotesize}] + \mrcclipmap + \tl_set:Nn \l__mermap_tile_basename_tl {_dummy_}% not existing file + \mermapset{map~path={draw=white,double=red}} + \tikzset{mermap_path_style/.style={draw=white,double=red}} + \__mermap_drawmap_tiles: + \node at (mrcmap.center) { + \begin{tabular}{ll} + scale & ca.~\mrcprettymapscale\\ + resolution & ca.~\mrcprettymapresolution\\ + \TeX\nobreakspace tile~size & ca.~\mrcprettytilesize\\ + width & ca.~\mrcprettymapwidth\\ + height & ca.~\mrcprettymapheight\\ + zoom & $z=\int_use:N \l__mermap_tile_zoom_int$\\ + horizontal & $x\in\{\int_use:N\l__mermap_tile_xmin_int,\ldots,\int_use:N\l__mermap_tile_xmax_int\}$\\ + vertical & $y\in\{\int_use:N\l__mermap_tile_ymin_int,\ldots,\int_use:N\l__mermap_tile_ymax_int\}$ + \end{tabular} + }; + \node[above] at (mrcmap.south) { + \mrcformlat[format~angle=decimal-4]{\mrcmapsouth}, + \SI[round-mode=figures,round-precision=6,detect-all]{\fp_to_decimal:n{ + \c__mermap_scale_radius_fp*(\mrcmapeast-\mrcmapwest)*cosd(\mrcmapsouth)}}{km} + }; + \node[below] at (mrcmap.north) { + \mrcformlat[format~angle=decimal-4]{\mrcmapnorth}, + \SI[round-mode=figures,round-precision=6,detect-all]{\fp_to_decimal:n{ + \c__mermap_scale_radius_fp*(\mrcmapeast-\mrcmapwest)*cosd(\mrcmapnorth)}}{km} + }; + \node[rotate=90] at ([xshift=3mm]mrcmap.west) { + \mrcformlon[format~angle=decimal-4]{\mrcmapwest}, + \SI[round-mode=figures,round-precision=6,detect-all]{\fp_to_decimal:n{ + \c__mermap_scale_radius_fp*(\mrcmapnorth-\mrcmapsouth)}}{km} + }; + \node[rotate=90] at ([xshift=-3mm]mrcmap.east) { + \mrcformlon[format~angle=decimal-4]{\mrcmapeast}, + \SI[round-mode=figures,round-precision=6,detect-all]{\fp_to_decimal:n{ + \c__mermap_scale_radius_fp*(\mrcmapnorth-\mrcmapsouth)}}{km} + }; + \end{scope}% + } + +\NewDocumentCommand{\mrcdrawinfo}{ }{ \__mermap_drawinfo: } + + +%---- geodetic network --------------------------------------------------------- + + +\dim_new:N \l__mermap_network_distance_dim +\int_new:N \l__mermap_network_pieces_int +\tl_new:N \l__mermap_network_font_tl + +\keys_define:nn { mermap } + { + network~distance .dim_set:N = \l__mermap_network_distance_dim, + network~pieces .int_set:N = \l__mermap_network_pieces_int, + network~font .tl_set:N = \l__mermap_network_font_tl, + } + +\keys_set:nn { mermap } + { + network~pieces = 8, + network~distance = 2cm, + network~font = \fontsize{4pt}{4pt}\sffamily, + } + +\cs_new_nopar:Npn \__mermap_compute_network_step:nn #1#2 + { + \fp_set:Nn \l_tmpa_fp + { + min ( \l__mermap_network_pieces_int, round((#1)/\l__mermap_network_distance_dim) ) + } + \fp_set:Nn \l_tmpb_fp { (#2)/\l_tmpa_fp } + \fp_set:Nn \l_tmpa_fp { floor(ln(\l_tmpb_fp)/ln(10)) } + \fp_compare:nNnTF {\l_tmpa_fp} < {0} + { + \fp_compare:nNnTF {\l_tmpa_fp} > {-5} + { + \use:x + { + \exp_not:N\keys_set:nn { mermap }{ format~angle=decimal\fp_to_int:N\l_tmpa_fp} + } + } + { + \keys_set:nn { mermap }{ format~angle=decimal } + } + } + { + \keys_set:nn { mermap }{ format~angle=decimal-0 } + } + \fp_set:Nn \l_tmpa_fp { 10^\l_tmpa_fp } + \fp_set:Nn \l_tmpb_fp { \l_tmpb_fp/\l_tmpa_fp } + \fp_compare:nNnTF {abs(\l_tmpb_fp-1)} < {abs(\l_tmpb_fp-2)} + { + \fp_compare:nNnTF {abs(\l_tmpb_fp-1)} < {abs(\l_tmpb_fp-5)} + { + \fp_set:Nn \l__mermap_result_fp {\l_tmpa_fp} + } + { + \fp_set:Nn \l__mermap_result_fp {5*\l_tmpa_fp} + } + } + { + \fp_compare:nNnTF {abs(\l_tmpb_fp-2)} < {abs(\l_tmpb_fp-5)} + { + \fp_set:Nn \l__mermap_result_fp {2*\l_tmpa_fp} + } + { + \fp_set:Nn \l__mermap_result_fp {5*\l_tmpa_fp} + } + } + } + + +\NewDocumentCommand\mrcdrawnetwork { o } + { + \begin{scope}[every~node/.style={inner~sep=0.5pt,black!50!gray, + font=\l__mermap_network_font_tl,fill=white,opacity=0.3,text~opacity=1}] + \IfNoValueF {#1} { \keys_set:nn { mermap } {#1} } + \tl_use:N \l__mermap_tikz_map_clip_tl + \__mermap_compute_network_step:nn {\l__mermap_tex_height_fp}{\l__mermap_mapnorth_fp-\l__mermap_mapsouth_fp} + \fp_set:Nn \l_tmpa_fp { ceil(\l__mermap_mapsouth_fp/\l__mermap_result_fp)*\l__mermap_result_fp} + \fp_compare:nNnT {\l_tmpa_fp-\l__mermap_mapsouth_fp} < {1e-10} + { + \fp_add:Nn \l_tmpa_fp {\l__mermap_result_fp} + } + \fp_while_do:nNnn {\l_tmpa_fp} < {\l__mermap_mapnorth_fp} + { + \tl_set:Nn \l_tmpa_tl {\fp_use:N\l_tmpa_fp} + \draw[gray,very~thin] (mrc~cs\c_colon_str lat=\l_tmpa_tl,lon=\mrcmapwest) + coordinate (mermap_temp) + node[right=1mm,inner~sep=0.5pt,black!50!gray,font=\l__mermap_network_font_tl, + fill=white,opacity=0.3,text~opacity=1, + ]{\mrcformlat{\l_tmpa_tl}} + -- (mermap_temp -| mrcmap.east) + node[left=1mm,inner~sep=0.5pt,black!50!gray,font=\l__mermap_network_font_tl, + fill=white,opacity=0.3,text~opacity=1, + ]{\mrcformlat{\l_tmpa_tl}} + ; + \fp_add:Nn \l_tmpa_fp {\l__mermap_result_fp} + } + \__mermap_compute_network_step:nn {\l__mermap_tex_width_fp}{\l__mermap_mapeast_fp-\l__mermap_mapwest_fp} + \fp_set:Nn \l_tmpa_fp { ceil(\l__mermap_mapwest_fp/\l__mermap_result_fp)*\l__mermap_result_fp} + \fp_compare:nNnT {\l_tmpa_fp-\l__mermap_mapwest_fp} < {1e-10} + { + \fp_add:Nn \l_tmpa_fp {\l__mermap_result_fp} + } + \fp_while_do:nNnn {\l_tmpa_fp} < {\l__mermap_mapeast_fp} + { + \tl_set:Nn \l_tmpa_tl {\fp_use:N\l_tmpa_fp} + \draw[gray,very~thin] (mrc~cs\c_colon_str lon=\l_tmpa_tl,lat=\mrcmapsouth) + coordinate (mermap_temp) + node[above=1mm,inner~sep=0.5pt,black!50!gray,font=\l__mermap_network_font_tl, + fill=white,opacity=0.3,text~opacity=1, + ]{\mrcformlon{\l_tmpa_tl}} + -- (mermap_temp |- mrcmap.north) + node[below=1mm,inner~sep=0.5pt,black!50!gray,font=\l__mermap_network_font_tl, + fill=white,opacity=0.3,text~opacity=1, + ]{\mrcformlon{\l_tmpa_tl}} + ; + \fp_add:Nn \l_tmpa_fp {\l__mermap_result_fp} + } + \end{scope} + } + + +%---- scaling and formatting --------------------------------------------------- + +\tl_new:N \l__mermap_temp_tl + +\keys_define:nn { mermap } + { + format~south .cs_set:Np = \__mermap_format_south:n #1, + format~north .cs_set:Np = \__mermap_format_north:n #1, + format~east .cs_set:Np = \__mermap_format_east:n #1, + format~west .cs_set:Np = \__mermap_format_west:n #1, + __format_angle .cs_set:Np = \__mermap_format_angle:n #1, + format~angle .choice:, + format~angle .value_required:n = true, + format~angle / decimal .meta:nn = {mermap}{__format_angle=\ang{##1}}, + format~angle / decimal-0 .meta:nn = {mermap}{__format_angle={\ang[round-mode=places,round-precision=0]{##1}}}, + format~angle / decimal-1 .meta:nn = {mermap}{__format_angle={\ang[round-mode=places,round-precision=1]{##1}}}, + format~angle / decimal-2 .meta:nn = {mermap}{__format_angle={\ang[round-mode=places,round-precision=2]{##1}}}, + format~angle / decimal-3 .meta:nn = {mermap}{__format_angle={\ang[round-mode=places,round-precision=3]{##1}}}, + format~angle / decimal-4 .meta:nn = {mermap}{__format_angle={\ang[round-mode=places,round-precision=4]{##1}}}, + format~angle / degree .meta:nn = {mermap}{format~angle=decimal-0}, + format~angle / minute .meta:nn = {mermap}{__format_angle=\__mermap_format_angle_minute:n{##1}}, + format~angle / second .meta:nn = {mermap}{__format_angle=\__mermap_format_angle_second:n{##1}}, + format~NEWS~absolute .meta:nn = {mermap}{ + format~south = {##1}, format~north = {##1}, format~east = {##1}, format~west = {##1} }, + format~NEWS~numeric .meta:nn = {mermap}{ + format~south = {$-$##1}, format~north = {##1}, format~east = {##1}, format~west = {$-$##1} }, + } + + +\keys_set:nn { mermap } + { + format~south = {#1\,S}, + format~north = {#1\,N}, + format~east = {#1\,E}, + format~west = {#1\,W}, + format~angle = decimal-4, + } + + +\NewExpandableDocumentCommand{\mrckmtotex}{ m } + { + \fp_to_dim:n { (#1)/\l__mermap_scale_fp } + } + +\NewExpandableDocumentCommand{\mrcmiletotex}{ m } + { + \fp_to_dim:n { (#1)*\c__mermap_mile_fp/\l__mermap_scale_fp } + } + +\NewExpandableDocumentCommand{\mrctextokm}{ m } + { + \fp_to_decimal:n { (#1)*\l__mermap_scale_fp } + } + +\NewExpandableDocumentCommand{\mrctextomile}{ m } + { + \fp_to_decimal:n { (#1)/\c__mermap_mile_fp*\l__mermap_scale_fp } + } + +\NewDocumentCommand{\mrcprettymapscale}{ } + { + 1\,\c_colon_str\,\num[round-mode=figures,round-precision=3,detect-all]{\fp_to_decimal:N \l__mermap_scale_denominator_fp} + } + + +\cs_new_nopar:Npn \__mermap_pretty_distance:n #1 + { + \fp_set:Nn \l_tmpa_fp { #1 } + \fp_compare:nNnTF \l_tmpa_fp < 5 + { + \SI[round-mode=figures,round-precision=3,detect-all]{\fp_to_decimal:n{1000*\l_tmpa_fp}}{\meter} + } + { + \SI[round-mode=figures,round-precision=3,detect-all]{\fp_to_decimal:N \l_tmpa_fp}{\kilo\meter} + } + } + + +\cs_new_nopar:Npn \__mermap_pretty_length:n #1 + { + \fp_set:Nn \l_tmpa_fp { (#1)*\l__mermap_scale_fp } + \fp_compare:nNnTF \l_tmpa_fp < 5 + { + \SI[round-mode=figures,round-precision=3,detect-all]{\fp_to_decimal:n{1000*\l_tmpa_fp}}{\meter} + } + { + \SI[round-mode=figures,round-precision=3,detect-all]{\fp_to_decimal:N \l_tmpa_fp}{\kilo\meter} + } + } + + +\NewDocumentCommand{\mrcprettymapwidth}{ } + { + \__mermap_pretty_length:n {\mrctexwidth} + } + +\NewDocumentCommand{\mrcprettymapheight}{ } + { + \__mermap_pretty_length:n {\mrctexheight} + } + +\NewDocumentCommand{\mrcprettymapresolution}{ } + { + \SI[round-mode=places,round-precision=0,detect-all]{\fp_to_decimal:n{1in*\l__mermap_pixel_width_tl/\l__mermap_tex_width_fp}}{dpi} + } + +\NewDocumentCommand{\mrcprettytilesize}{ } + { + \SI[round-mode=places,round-precision=3,detect-all]{\fp_to_decimal:n{\l__mermap_tile_size_dim/1mm}}{\milli\meter} + } + + +\cs_new_nopar:Npn \__mermap_format_angle_minute:n #1 + { + \fp_set:Nn \l_tmpa_fp {floor(#1)} + \fp_set:Nn \l_tmpb_fp {round((#1-\l_tmpa_fp)*60)} + \ang[add-arc-degree-zero,add-arc-minute-zero] + { + \fp_to_int:N \l_tmpa_fp ; + \fp_to_int:N \l_tmpb_fp ; + } + } + + +\cs_new_nopar:Npn \__mermap_format_angle_second:n #1 + { + \fp_set:Nn \l_tmpa_fp {floor(#1)} + \fp_set:Nn \l_tmpb_fp {floor((#1-\l_tmpa_fp)*60)} + \ang[add-arc-degree-zero,add-arc-minute-zero] + { + \fp_to_int:N \l_tmpa_fp ; + \fp_to_int:N \l_tmpb_fp ; + \fp_to_int:n {round(((#1-\l_tmpa_fp)*60-\l_tmpb_fp)*60)} + } + } + +\NewDocumentCommand{\mrcformlat}{ o m } + { + \group_begin: + \IfNoValueF {#1} + { \keys_set:nn { mermap } {#1} } + \fp_set:Nn \l_tmpa_fp {#2} + \fp_compare:nNnTF \l_tmpa_fp < 0 + { + \tl_set:Nx \l__mermap_temp_tl {\fp_to_decimal:n{-\l_tmpa_fp}} + \__mermap_format_south:n {\__mermap_format_angle:n{\l__mermap_temp_tl}} + } + { + \tl_set:Nx \l__mermap_temp_tl {\fp_to_decimal:N \l_tmpa_fp} + \__mermap_format_north:n {\__mermap_format_angle:n{\l__mermap_temp_tl}} + } + \group_end: + } + +\NewDocumentCommand{\mrcformlon}{ o m } + { + \group_begin: + \IfNoValueF {#1} + { \keys_set:nn { mermap } {#1} } + \fp_set:Nn \l_tmpa_fp {#2-360*floor((#2+180)/360)} + \fp_compare:nNnTF \l_tmpa_fp < 0 + { + \tl_set:Nx \l__mermap_temp_tl {\fp_to_decimal:n{-\l_tmpa_fp}} + \__mermap_format_west:n{\__mermap_format_angle:n{\l__mermap_temp_tl}} + } + { + \tl_set:Nx \l__mermap_temp_tl {\fp_to_decimal:N \l_tmpa_fp} + \__mermap_format_east:n {\__mermap_format_angle:n{\l__mermap_temp_tl}} + } + \group_end: + } + + +%---- scale bars --------------------------------------------------------------- + +\bool_new:N \l__mermap_scalebar_double_bool +\bool_new:N \l__mermap_scalebar_transparent_bool +\dim_new:N \l__mermap_scalebar_height_dim +\fp_new:N \l__mermap_scalebar_width_fp +\int_new:N \l__mermap_scalebar_partitions_int +\tl_new:N \l__mermap_scalebar_position_tl + + +\cs_new_nopar:Npn \__mermap_scalebar_positioning:w #1#2#3#4#5;#6;#7 \q_stop + { + \tl_if_empty:nTF {#5} + { + \fp_set:Nn \l_tmpa_fp {0} + \fp_set:Nn \l_tmpb_fp {0} + } + { + \fp_set:Nn \l_tmpa_fp {#3*(#5)} + \tl_if_empty:nTF {#6} + { + \fp_set:Nn \l_tmpb_fp {#4*(#5)} + } + { + \fp_set:Nn \l_tmpb_fp {#4*(#6)} + } + } + \tl_set:Nx \l__mermap_scalebar_at_tl + { + {([xshift=\fp_to_dim:N\l_tmpa_fp,yshift=\fp_to_dim:N\l_tmpb_fp]mrcmap.#1)} + } + \tl_set:Nn \l__mermap_scalebar_placement_tl {#2} + } + +\keys_define:nn { mermap/scalebar } + { + width-in-km .fp_set:N = \l__mermap_scalebar_width_fp, + width-in-kilometer .meta:nn = { mermap/scalebar }{ width-in-km={#1} }, + width-in-meter .meta:nn = { mermap/scalebar }{ width-in-km={(#1)/1000} }, + width-in-mile .meta:nn = { mermap/scalebar }{ width-in-km={(#1)*\c__mermap_mile_fp} }, + width-in-yard .meta:nn = { mermap/scalebar }{ width-in-km={(#1)*0.0009144} }, + partitions .int_set:N = \l__mermap_scalebar_partitions_int, + height .dim_set:N = \l__mermap_scalebar_height_dim, + at .tl_set:N = \l__mermap_scalebar_at_tl, + placement .tl_set:N = \l__mermap_scalebar_placement_tl, + major~style .code:n = {\tikzset{mrcscalebarmajor/.style={#1}}}, + minor~style .code:n = {\tikzset{mrcscalebarminor/.style={#1}}}, + double .bool_set:N = \l__mermap_scalebar_double_bool, + single .bool_set_inverse:N = \l__mermap_scalebar_double_bool, + transparent .bool_set:N = \l__mermap_scalebar_transparent_bool, + solid .bool_set_inverse:N = \l__mermap_scalebar_transparent_bool, + scale .code:n = {\fp_set:Nn \l__mermap_scale_fp { #1 / (1cm*100000) }}, + south-east-inside .code:n = + { \__mermap_scalebar_positioning:w {south~east}{above~left}{-1}{1}#1;;\q_stop }, + south-east-outside .code:n = + { \__mermap_scalebar_positioning:w {south~east}{below~left}{-1}{-1}#1;;\q_stop }, + south-west-inside .code:n = + { \__mermap_scalebar_positioning:w {south~west}{above~right}{1}{1}#1;;\q_stop }, + south-west-outside .code:n = + { \__mermap_scalebar_positioning:w {south~west}{below~right}{1}{-1}#1;;\q_stop }, + north-west-inside .code:n = + { \__mermap_scalebar_positioning:w {north~west}{below~right}{1}{-1}#1;;\q_stop }, + north-west-outside .code:n = + { \__mermap_scalebar_positioning:w {north~west}{above~right}{1}{1}#1;;\q_stop }, + north-east-inside .code:n = + { \__mermap_scalebar_positioning:w {north~east}{below~left}{-1}{-1}#1;;\q_stop }, + north-east-outside .code:n = + { \__mermap_scalebar_positioning:w {north~east}{above~left}{-1}{1}#1;;\q_stop }, + } + +\keys_set:nn { mermap/scalebar } + { + width-in-km = 0, + partitions = 5, + double = true, + transparent = true, + height = 2mm, + %at = {([xshift=-10mm,yshift=5mm]mrcmap.south~east)}, + %placement = above~left, + at = {(0,0)}, + placement =, + major~style =, + minor~style =, + } + +\cs_new_nopar:Npn \__mermap_drawscalebar: + { + \use:x + { + \exp_not:N\node[name=mrcscalebar, + at={\exp_not:V\l__mermap_scalebar_at_tl}, + \exp_not:V\l__mermap_scalebar_placement_tl, + line~width=0mm,inner~sep=0mm,outer~sep=0mm,draw=none,fill=none,rectangle, + minimum~width=\mrckmtotex{\l__mermap_scalebar_width_fp}, + minimum~height=\l__mermap_scalebar_height_dim]{}; + } + \begin{scope}[shift=(mrcscalebar.south~west)] + \__mermap_tikz_path_begin:n { fill=black, mrcscalebarmajor } + \pgfseteorule + \fp_set:Nn \l_tmpa_fp {\l__mermap_scalebar_width_fp/\l__mermap_scale_fp} % Breite + \pgfpathrectangle{\pgfpoint{0pt}{0pt}} + {\pgfpoint{\fp_to_dim:N\l_tmpa_fp}{\l__mermap_scalebar_height_dim}} + \bool_if:NF \l__mermap_scalebar_transparent_bool + { + \__mermap_tikz_path_end: + \__mermap_tikz_path_begin:n { fill=white, mrcscalebarminor } + \fp_set:Nn \l_tmpa_fp {\l__mermap_scalebar_width_fp/\l__mermap_scale_fp} + } + \fp_set:Nn \l_tmpb_fp {\l_tmpa_fp/\l__mermap_scalebar_partitions_int} + \bool_if:NTF \l__mermap_scalebar_double_bool + { + \int_set:Nn \l_tmpa_int {1} + \dim_set:Nn \l_tmpb_dim {\l__mermap_scalebar_height_dim/2} + \dim_set:Nn \l_tmpa_dim {0.2pt-\l_tmpb_dim} + \int_compare:nNnTF \l__mermap_scalebar_partitions_int = 1 + { + \pgfpathrectangle{\pgfpoint{0.2pt}{\l_tmpb_dim}} + {\pgfpoint{\fp_to_dim:n{\l_tmpb_fp-0.4pt}}{\l_tmpa_dim}} + } + { + \pgfpathrectangle{\pgfpoint{0.2pt}{\l_tmpb_dim}} + {\pgfpoint{\fp_to_dim:n{\l_tmpb_fp-0.2pt}}{\l_tmpa_dim}} + } + \int_while_do:nNnn \l_tmpa_int < \l__mermap_scalebar_partitions_int + { + \dim_set:Nn \l_tmpa_dim {-\l_tmpa_dim} + \int_compare:nNnTF {\l_tmpa_int+1} = \l__mermap_scalebar_partitions_int + { + \pgfpathrectangle{\pgfpoint{\fp_to_dim:n{\l_tmpa_int*\l_tmpb_fp}}{\l_tmpb_dim}} + {\pgfpoint{\fp_to_dim:n{\l_tmpb_fp-0.2pt}}{\l_tmpa_dim}} + } + { + \pgfpathrectangle{\pgfpoint{\fp_to_dim:n{\l_tmpa_int*\l_tmpb_fp}}{\l_tmpb_dim}} + {\pgfpoint{\fp_to_dim:N\l_tmpb_fp}{\l_tmpa_dim}} + } + \int_incr:N \l_tmpa_int + } + } + { + \int_set:Nn \l_tmpa_int {1} + \dim_set:Nn \l_tmpa_dim {\l__mermap_scalebar_height_dim-0.4pt} + \int_while_do:nNnn \l_tmpa_int < \l__mermap_scalebar_partitions_int + { + \int_compare:nNnTF {\l_tmpa_int+1} = \l__mermap_scalebar_partitions_int + { + \pgfpathrectangle{\pgfpoint{\fp_to_dim:n{\l_tmpa_int*\l_tmpb_fp}}{0.2pt}} + {\pgfpoint{\fp_to_dim:n{\l_tmpb_fp-0.2pt}}{\l_tmpa_dim}} + } + { + \pgfpathrectangle{\pgfpoint{\fp_to_dim:n{\l_tmpa_int*\l_tmpb_fp}}{0.2pt}} + {\pgfpoint{\fp_to_dim:N\l_tmpb_fp}{\l_tmpa_dim}} + } + \int_add:Nn \l_tmpa_int {2} + } + } + \__mermap_tikz_path_end: + \end{scope} + } + +\msg_new:nnnn{ mercatormap }{ scalebar-too-large } + { The~width~of~the~scale~bar~is~too~large:~#1. } + { + You~should~provide~a~smaller~value~by~using~width-in-km~or~width-in-mile. + } + +\msg_new:nnnn{ mercatormap }{ scalebar-scale-unset } + { The~map~scale~is~unknown. } + { + Use~\token_to_str:N \mrcdrawscalebar \ with~a~defined~map~or~set~'scale'~ + explicitely. + } + +\NewDocumentCommand \mrcdrawscalebar { o } + { + \group_begin: + \IfNoValueF {#1} { \keys_set:nn { mermap/scalebar } {#1} } + \fp_compare:nNnT \l__mermap_scale_fp = 0 + { + \msg_error:nn{ mercatormap }{ scalebar-scale-unset } + } + \fp_compare:nNnT {\l__mermap_scalebar_width_fp/\l__mermap_scale_fp} > {575cm} + { + \msg_error:nnx{ mercatormap }{ scalebar-too-large } + { \fp_to_dim:n{\l__mermap_scalebar_width_fp/\l__mermap_scale_fp} } + } + \__mermap_drawscalebar: + \group_end: + } + +%---- markers ------------------------------------------------------------------ + +\bool_new:N \l__mermap_marker_show_bool + +\fp_new:N \l__mermap_marker_angle_fp +\fp_new:N \l__mermap_marker_inner_radius_fp +\fp_new:N \l__mermap_marker_latitude_fp +\fp_new:N \l__mermap_marker_longitude_fp +\fp_new:N \l__mermap_marker_radius_fp +\fp_new:N \l__mermap_marker_shift_fp + +\tl_new:N \l__mermap_every_marker_first_tl +\tl_new:N \l__mermap_every_marker_last_tl +\tl_new:N \l__mermap_marker_alias_tl +\tl_new:N \l__mermap_marker_category_tl +\tl_new:N \l__mermap_marker_contents_tl +\tl_new:N \l__mermap_marker_font_tl +\tl_new:N \l__mermap_marker_pictocontents_tl +\tl_new:N \l__mermap_marker_type_tl +\tl_new:N \l__mermap_marker_uuid_tl + + +\use:x + { + \cs_new_nopar:Npn \exp_not:N\__mermap_marker_position:w ##1 \c_colon_str ##2 \exp_not:N \q_stop + } + { + \fp_set:Nn \l__mermap_marker_latitude_fp {#1} + \fp_set:Nn \l__mermap_marker_longitude_fp {#2} + } + + +\keys_define:nn { mermap/marker } + { + latitude .fp_set:N = \l__mermap_marker_latitude_fp, + lat .fp_set:N = \l__mermap_marker_latitude_fp, + longitude .fp_set:N = \l__mermap_marker_longitude_fp, + lon .fp_set:N = \l__mermap_marker_longitude_fp, + position .code:n = {\__mermap_marker_position:w #1 \q_stop}, + named~position .meta:nn = {mermap/marker}{latitude=\mrcNPlat{#1},longitude=\mrcNPlon{#1}}, + use~inside .choice: =, + use~inside .value_required:n = true, + use~inside/map .code:n = { \cs_set_eq:NN \__mermap_if_marker_inside:nnTF \__mermap_if_in_map:nnTF }, + use~inside/vicinity .code:n = { \cs_set_eq:NN \__mermap_if_marker_inside:nnTF \__mermap_if_in_vicinity:nnTF }, + alias .tl_set:N = \l__mermap_marker_alias_tl, + contents .tl_set:N = \l__mermap_marker_contents_tl, + pictocontents .tl_set:N = \l__mermap_marker_pictocontents_tl, + % name .meta:nn = {mermap/marker}{contents={#1},alias={#1}}, + uuid .tl_set:N = \l__mermap_marker_uuid_tl, + category .tl_set:N = \l__mermap_marker_category_tl, + type .tl_set:N = \l__mermap_marker_type_tl, + angle .fp_set:N = \l__mermap_marker_angle_fp, + shift .fp_set:N = \l__mermap_marker_shift_fp, + draw .code:n = \colorlet{mrcmarkerdraw}{#1}, + fill .code:n = \colorlet{mrcmarkerfill}{#1}, + text .code:n = \colorlet{mrcmarkertext}{#1}, + font .tl_set:N = \l__mermap_marker_font_tl, + radius .fp_set:N = \l__mermap_marker_radius_fp, + inner~radius .fp_set:N = \l__mermap_marker_inner_radius_fp, + path~style .code:n = {\tikzset{mrcpathstyle/.style={#1}}}, + node~style .code:n = {\tikzset{mrcnodestyle/.style={#1}}}, + show .bool_set:N = \l__mermap_marker_show_bool, + hide .bool_set_inverse:N = \l__mermap_marker_show_bool, + show~category .code:n = + { \str_if_eq:VnT \l__mermap_marker_category_tl {#1} {\bool_set_true:N \l__mermap_marker_show_bool} }, + show~all~but~category .code:n = + { \str_if_eq:VnF \l__mermap_marker_category_tl {#1} {\bool_set_true:N \l__mermap_marker_show_bool} }, + hide~category .code:n = + { \str_if_eq:VnT \l__mermap_marker_category_tl {#1} {\bool_set_false:N \l__mermap_marker_show_bool} }, + hide~all~but~category .code:n = + { \str_if_eq:VnF \l__mermap_marker_category_tl {#1} {\bool_set_false:N \l__mermap_marker_show_bool} }, + first~options .tl_set:N = \l__mermap_every_marker_first_tl, + last~options .tl_set:N = \l__mermap_every_marker_last_tl, + style .choice: =, + style .value_required:n = true, + } + + +\keys_set:nn { mermap/marker } + { + latitude = 12, + longitude = 49, + use~inside = map, + % name = noname, + contents =, + alias = noname, + pictocontents =, + angle = 90, + shift = 0pt, + fill = gray!20, + draw = gray, + text = black, + radius = 3mm, + inner~radius = 2.25mm, + path~style =, + node~style =, + font = \sffamily\small, + type = classic, + uuid =, + category =, + show = true, + } + + +\NewExpandableDocumentCommand\mrcmarkerlatitude{}{\fp_to_decimal:N \l__mermap_marker_latitude_fp} +\NewExpandableDocumentCommand\mrcmarkerlongitude{}{\fp_to_decimal:N \l__mermap_marker_longitude_fp} +\NewDocumentCommand\mrcmarkercontents{}{\tl_use:N \l__mermap_marker_contents_tl} +\NewDocumentCommand\mrcmarkerpictocontents{}{\tl_use:N \l__mermap_marker_pictocontents_tl} +\NewExpandableDocumentCommand\mrcmarkeruuid{}{\tl_use:N \l__mermap_marker_uuid_tl} +\NewExpandableDocumentCommand\mrcmarkercategory{}{\tl_use:N \l__mermap_marker_category_tl} +\NewDocumentCommand\mrcmarkerfont{}{\tl_use:N \l__mermap_marker_font_tl} +\NewExpandableDocumentCommand\mrcmarkerangle{}{\fp_to_decimal:N \l__mermap_marker_angle_fp} +\NewExpandableDocumentCommand\mrcmarkershift{}{\fp_to_dim:N \l__mermap_marker_shift_fp} +\NewExpandableDocumentCommand\mrcmarkerradius{}{\fp_to_dim:N \l__mermap_marker_radius_fp} +\NewExpandableDocumentCommand\mrcmarkerinnerradius{}{\fp_to_dim:N \l__mermap_marker_inner_radius_fp} + + +\NewDocumentCommand \mrcnewmarkerstyle { m +m } + { + \keys_define:nn { mermap/marker/style } + { + #1 .meta:nn = {mermap/marker}{#2} + } + } + + +\msg_new:nnnn{ mercatormap }{ markertype-undefined } + { Marker~type~'#1'~is~unknown. } + { + I~guess~'type=#1'~for~setting~a~marker~type~contains~a~spelling~error. + } + + +\NewDocumentCommand \mrcmarker { m } + { + \group_begin: + \keys_set:nV { mermap/marker } \l__mermap_every_marker_first_tl + \keys_set:nn { mermap/marker } { #1 } + \keys_set:nV { mermap/marker } \l__mermap_every_marker_last_tl + \__mermap_if_marker_inside:nnTF {\l__mermap_marker_latitude_fp} {\l__mermap_marker_longitude_fp} + { + \bool_if:NT \l__mermap_marker_show_bool + { + \pgfnodealias{\l__mermap_marker_alias_tl}{mrcpos} + \begin{scope}[shift=(mrcpos)] + \cs_if_exist_use:cF{__mermap_drawmarker_\l__mermap_marker_type_tl} + { + \msg_error:nnx{ mercatormap }{ markertype-undefined }{ \l__mermap_marker_type_tl } + } + \end{scope} + } + } + {} + \group_end: + } + + +\cs_new:Npn \__mermap_new_marker_type:nn #1 + { + \cs_new:cpn {__mermap_drawmarker_#1} + } + + +\NewDocumentCommand \mrcnewmarkertype { m } + { + \__mermap_new_marker_type:nn {#1} + } + + +\__mermap_new_marker_type:nn {classic} + { + \node[circle,fill=black,inner~sep=0pt,minimum~width=4pt, + pin={[text=mrcmarkertext,font=\mrcmarkerfont, + pin~distance=\mrcmarkerradius, + pin~position=\mrcmarkerangle,mrcnodestyle]\mrcmarkercontents}] {}; + } + +\__mermap_new_marker_type:nn {pin} + { + \path[fill=mrcmarkerfill,draw=none,fill~opacity=0.7] + (0,0) -- (0.1,0.5) -- (-0.1,0.5) -- cycle; + \node[fill=white,draw=none,text=mrcmarkertext, + above,font=\mrcmarkerfont,inner~sep=0.5mm,align=center, + line~width=0mm,xshift=\mrcmarkershift, + fill~opacity=0.7,text~opacity=1,xshift=0mm,mrcnodestyle] + (pin_node) at (0,0.5) {\mrcmarkercontents}; + \path[draw=mrcmarkerdraw,fill=none,line~join=round,mrcpathstyle] + (0,0) -- (0.1,0.5) -- (pin_node.south~east) -- (pin_node.north~east) + -- (pin_node.north~west) -- (pin_node.south~west) + -- (-0.1,0.5) [line~join=bevel] -- cycle; + } + +\__mermap_new_marker_type:nn {pinflip} + { + \path[fill=mrcmarkerfill,draw=none,fill~opacity=0.7] + (0,0) -- (-0.1,-0.5) -- (0.1,-0.5) -- cycle; + \node[fill=white,draw=none,text=mrcmarkertext, + below,font=\mrcmarkerfont,inner~sep=0.5mm,align=center, + line~width=0mm,xshift=\mrcmarkershift, + fill~opacity=0.7,text~opacity=1,xshift=0mm,mrcnodestyle] + (pin_node) at (0,-0.5) {\mrcmarkercontents}; + \path[draw=mrcmarkerdraw,fill=none,line~join=round,mrcpathstyle] + (0,0) -- (-0.1,-0.5) -- (pin_node.north~west) -- (pin_node.south~west) + -- (pin_node.south~east) -- (pin_node.north~east) + -- (0.1,-0.5) [line~join=bevel] -- cycle; + } + + +\cs_new_nopar:Npn \__mermap_tikz_drop_path:n #1 + { + \tl_set:Nn \l_tmpa_tl {\fp_to_dim:N\l__mermap_marker_radius_fp} + \tl_set:Nn \l_tmpb_tl {\fp_to_dim:n{\l__mermap_marker_radius_fp*0.552}} + \__mermap_tikz_path_begin:n + { + line~join=bevel,draw=mrcmarkerdraw,fill=mrcmarkerfill,mrcpathstyle + } + \pgfpathmoveto{\pgfpoint{0pt}{\fp_to_dim:n{-2*\l__mermap_marker_radius_fp-\l__mermap_marker_shift_fp}}} + \pgfpathcurveto{\pgfpoint{\l_tmpb_tl}{-\l_tmpa_tl}}{\pgfpoint{\l_tmpa_tl}{-\l_tmpb_tl}} + {\pgfpoint{\l_tmpa_tl}{0pt}} + \pgfpathcurveto{\pgfpoint{\l_tmpa_tl}{\l_tmpb_tl}}{\pgfpoint{\l_tmpb_tl}{\l_tmpa_tl}} + {\pgfpoint{0pt}{\l_tmpa_tl}} + \pgfpathcurveto{\pgfpoint{-\l_tmpb_tl}{\l_tmpa_tl}}{\pgfpoint{-\l_tmpa_tl}{\l_tmpb_tl}} + {\pgfpoint{-\l_tmpa_tl}{0pt}} + \pgfpathcurveto{\pgfpoint{-\l_tmpa_tl}{-\l_tmpb_tl}}{\pgfpoint{-\l_tmpb_tl}{-\l_tmpa_tl}} + {\pgfpoint{0pt}{\fp_to_dim:n{-2*\l__mermap_marker_radius_fp-\l__mermap_marker_shift_fp}}} + \pgfpathclose + #1 + \__mermap_tikz_path_end: + } + +\cs_new_nopar:Npn \__mermap_tikz_circle_node: + { + \node[circle,inner~sep=0pt,font=\mrcmarkerfont,text=mrcmarkertext,mrcnodestyle] + { + \hbox_set:Nn \l_tmpa_box {\mrcmarkercontents} + \fp_compare:nNnT {\box_wd:N \l_tmpa_box} > {1.5*\l__mermap_marker_radius_fp} + { + \box_resize_to_wd_and_ht:Nnn \l_tmpa_box + {\fp_to_dim:n {1.5*\l__mermap_marker_radius_fp}} + {\box_ht:N \l_tmpa_box} + } + \box_use_drop:N \l_tmpa_box + }; + } + +\__mermap_new_marker_type:nn {drop} + { + \begin{scope}[yshift=\fp_to_dim:n{2*\l__mermap_marker_radius_fp+\l__mermap_marker_shift_fp}] + \__mermap_tikz_drop_path:n {} + \__mermap_tikz_circle_node: + \end{scope} + } + +\__mermap_new_marker_type:nn {pictodrop} + { + \begin{scope}[yshift=\fp_to_dim:n{2*\l__mermap_marker_radius_fp+\l__mermap_marker_shift_fp}] + \__mermap_tikz_drop_path:n {} + \tl_use:N \l__mermap_marker_pictocontents_tl + \end{scope} + } + +\__mermap_new_marker_type:nn {pictodropring} + { + \begin{scope}[yshift=\fp_to_dim:n{2*\l__mermap_marker_radius_fp+\l__mermap_marker_shift_fp}] + \group_begin: + \pgfseteorule + \__mermap_tikz_drop_path:n { + \pgfpathcircle{\pgfpoint{0pt}{0pt}}{\fp_to_dim:N\l__mermap_marker_inner_radius_fp} + } + \group_end: + \tl_use:N \l__mermap_marker_pictocontents_tl + \end{scope} + } + +\__mermap_new_marker_type:nn {knob} + { + \path[draw=mrcmarkerdraw,fill=mrcmarkerfill,mrcpathstyle] + circle (\fp_to_dim:N\l__mermap_marker_radius_fp); + \__mermap_tikz_circle_node: + } + +\__mermap_new_marker_type:nn {pictoknob} + { + \path[draw=mrcmarkerdraw,fill=mrcmarkerfill,mrcpathstyle] + circle (\fp_to_dim:N\l__mermap_marker_radius_fp); + \tl_use:N \l__mermap_marker_pictocontents_tl + } + +\__mermap_new_marker_type:nn {pictoknobring} + { + \path[draw=mrcmarkerdraw,fill=mrcmarkerfill,mrcpathstyle,even~odd~rule] + circle (\fp_to_dim:N\l__mermap_marker_radius_fp) + circle (\fp_to_dim:N\l__mermap_marker_inner_radius_fp); + \tl_use:N \l__mermap_marker_pictocontents_tl + } + +\__mermap_new_marker_type:nn {ringx} + { + \tl_set:Nn \l_tmpa_tl {\fp_to_dim:N\l__mermap_marker_radius_fp} + \path[draw=mrcmarkerdraw,very~thin] + (45 \c_colon_str \l_tmpa_tl)--(225\c_colon_str \l_tmpa_tl) + (135\c_colon_str \l_tmpa_tl)--(315\c_colon_str \l_tmpa_tl); + \path[draw=mrcmarkerdraw,fill=mrcmarkerfill,mrcpathstyle,even~odd~rule] + circle (\l_tmpa_tl) circle (\fp_to_dim:N\l__mermap_marker_inner_radius_fp); + } + +\__mermap_new_marker_type:nn {markx} + { + \tl_set:Nn \l_tmpa_tl {\fp_to_dim:N\l__mermap_marker_radius_fp} + \path[line~join=bevel,draw=mrcmarkerdraw,fill=mrcmarkerfill,mrcpathstyle] + (0,0) -- (35 \c_colon_str \l_tmpa_tl) -- (55 \c_colon_str \l_tmpa_tl) -- cycle + (0,0) -- (125 \c_colon_str \l_tmpa_tl) -- (145 \c_colon_str \l_tmpa_tl) -- cycle + (0,0) -- (215 \c_colon_str \l_tmpa_tl) -- (235 \c_colon_str \l_tmpa_tl) -- cycle + (0,0) -- (305 \c_colon_str \l_tmpa_tl) -- (325 \c_colon_str \l_tmpa_tl) -- cycle; + } + + +%---- paths and routes --------------------------------------------------------- + + +\bool_new:N \l__mermap_path_first_point_bool + + +\keys_define:nn { mermap } + { + every~route .code:n = { \tikzset{ mermap_every_route/.style={#1} } } + } + +\keys_set:nn { mermap } + { + every~route =, + } + + +\cs_new:Npn \__mermap_tikz_path_begin:n #1 + { + \path[#1] \pgfextra + } + +\cs_new:Npn \__mermap_tikz_path_end: + { + \endpgfextra; + } + +\cs_new_nopar:Npn \__mermap_pgf_moveto_point:nn #1#2 + { + \pgfpathmoveto{\__mermap_pgfpoint:nn {#1}{#2}} + } + +\cs_new_nopar:Npn \__mermap_pgf_lineto_point:nn #1#2 + { + \pgfpathlineto{\__mermap_pgfpoint:nn {#1}{#2}} + } + +\cs_new_nopar:Npn \__mermap_route_point #1#2 + { + \bool_if:NTF \l__mermap_path_first_point_bool + { + \__mermap_pgf_moveto_point:nn {#1}{#2} + \bool_set_false:N \l__mermap_path_first_point_bool + } + { + \__mermap_pgf_lineto_point:nn {#1}{#2} + } + } + +\cs_new_nopar:Npn \__mermap_route_begin:n #1 + { + \__mermap_tikz_path_begin:n + { + draw,mermap_every_route,#1 + } + \cs_set_eq:NN \mrcpoint \__mermap_route_point + \bool_set_true:N \l__mermap_path_first_point_bool + } + +\NewDocumentEnvironment {mrcroute} { O{} } + { + \__mermap_route_begin:n {#1} + } + { + \__mermap_tikz_path_end: + } + +\NewDocumentEnvironment {mrcroute*} { O{} } + { + \__mermap_route_begin:n {#1} + } + { + \pgfpathclose + \__mermap_tikz_path_end: + } + +\NewDocumentCommand \mrcrouteinput { s O{} m } + { + \__mermap_route_begin:n {#2} + \file_input:n {#3} + \IfBooleanT {#1} + { + \pgfpathclose + } + \__mermap_tikz_path_end: + } + + +%---- orthodromes and loxodromes ----------------------------------------------- + + +\fp_new:N \l__mermap_a_x_fp +\fp_new:N \l__mermap_a_y_fp +\fp_new:N \l__mermap_a_z_fp +\fp_new:N \l__mermap_b_x_fp +\fp_new:N \l__mermap_b_y_fp +\fp_new:N \l__mermap_b_z_fp +\fp_new:N \l__mermap_delta_lambda_fp +\fp_new:N \l__mermap_delta_phi_fp +\fp_new:N \l__mermap_psi_fp +\fp_new:N \l__mermap_t_x_fp +\fp_new:N \l__mermap_t_y_fp +\fp_new:N \l__mermap_t_z_fp + +\int_new:N \l__mermap_samples_int + +\keys_define:nn { mermap } + { + samples .int_set:N = \l__mermap_samples_int, + } + +\keys_set:nn { mermap } + { + samples = 100, + } + +\tikzset{ + mermap~samples/.code={\mermapset{samples=#1}} +} + + +\cs_new_nopar:Npn \__mermap_sphere_point:nnn #1#2#3 % {x}{y}{z} + { + \fp_set:Nn \l__mermap_cs_lat_fp { asind(#3/sqrt((#1)^2+(#2)^2+(#3)^2)) } + \fp_set:Nn \l__mermap_cs_lon_fp { sign(#2)*acosd(#1/sqrt((#1)^2+(#2)^2)) } + \__mermap_pgfpoint:nn {\l__mermap_cs_lat_fp}{\l__mermap_cs_lon_fp} + } + + +\cs_new_nopar:Npn \__mermap_unit_sphere_point:nnn #1#2#3 % {x}{y}{z} radius 1 + { + \fp_set:Nn \l__mermap_cs_lat_fp { asind(#3) } + \fp_set:Nn \l__mermap_cs_lon_fp { sign(#2)*acosd(#1/sqrt((#1)^2+(#2)^2)) } + \__mermap_pgfpoint:nn {\l__mermap_cs_lat_fp}{\l__mermap_cs_lon_fp} + } + + +\cs_new:Npn \__mermap_draw_orthodrome:nnnnn #1#2#3#4#5 + { + \__mermap_tikz_path_begin:n { draw,mermap_every_route,#1 } + \fp_set:Nn \l__mermap_a_x_fp { cosd(#3)*cosd(#2) } + \fp_set:Nn \l__mermap_a_y_fp { sind(#3)*cosd(#2) } + \fp_set:Nn \l__mermap_a_z_fp { sind(#2) } + \fp_set:Nn \l__mermap_b_x_fp { cosd(#5)*cosd(#4) } + \fp_set:Nn \l__mermap_b_y_fp { sind(#5)*cosd(#4) } + \fp_set:Nn \l__mermap_b_z_fp { sind(#4) } + + \fp_set:Nn \l_tmpa_fp { sind(#2)*sind(#4) + cosd(#2)*cosd(#4)*cosd(#5-(#3)) } + \fp_set:Nn \l__mermap_psi_fp { acosd(\l_tmpa_fp) } + \fp_set:Nn \l_tmpb_fp { sind(\l__mermap_psi_fp) } + + \fp_set:Nn \l__mermap_b_x_fp { (\l__mermap_b_x_fp - \l_tmpa_fp*\l__mermap_a_x_fp)/\l_tmpb_fp } + \fp_set:Nn \l__mermap_b_y_fp { (\l__mermap_b_y_fp - \l_tmpa_fp*\l__mermap_a_y_fp)/\l_tmpb_fp } + \fp_set:Nn \l__mermap_b_z_fp { (\l__mermap_b_z_fp - \l_tmpa_fp*\l__mermap_a_z_fp)/\l_tmpb_fp } + + \__mermap_pgf_moveto_point:nn {#2}{#3} + \int_set:Nn \l_tmpa_int {1} + \int_until_do:nNnn \l_tmpa_int > \l__mermap_samples_int + { + \fp_set:Nn \l_tmpa_fp { \l__mermap_psi_fp*\l_tmpa_int/\l__mermap_samples_int } + \fp_set:Nn \l_tmpb_fp { sind(\l_tmpa_fp) } + \fp_set:Nn \l_tmpa_fp { cosd(\l_tmpa_fp) } + \fp_set:Nn \l__mermap_t_x_fp { \l_tmpa_fp*\l__mermap_a_x_fp + \l_tmpb_fp*\l__mermap_b_x_fp } + \fp_set:Nn \l__mermap_t_y_fp { \l_tmpa_fp*\l__mermap_a_y_fp + \l_tmpb_fp*\l__mermap_b_y_fp } + \fp_set:Nn \l__mermap_t_z_fp { \l_tmpa_fp*\l__mermap_a_z_fp + \l_tmpb_fp*\l__mermap_b_z_fp } + \pgfpathlineto{\__mermap_unit_sphere_point:nnn {\l__mermap_t_x_fp}{\l__mermap_t_y_fp}{\l__mermap_t_z_fp}} + \int_incr:N \l_tmpa_int + } + \__mermap_tikz_path_end: + } + + +\NewDocumentCommand \mrcdraworthodrome { O{} mmmm } + { + \__mermap_draw_orthodrome:nnnnn {#1}{#2}{#3}{#4}{#5} + } + + +\NewDocumentCommand \mrcNPdraworthodrome { O{} mm } + { + \__mermap_draw_orthodrome:nnnnn {#1}{\mrcNPlat{#2}}{\mrcNPlon{#2}}{\mrcNPlat{#3}}{\mrcNPlon{#3}} + } + + +\cs_new_nopar:Npn \__mermap_ortho_distance:nnnn #1#2#3#4 + { + \fp_set:Nn \l__mermap_result_fp + { + \c__mermap_scale_radius_fp * + acosd( sind(#1)*sind(#3) + cosd(#1)*cosd(#3)*cosd(#4-(#2)) ) + } + } + + +\NewDocumentCommand \mrcstoreorthodistance { mmmmm } + { + \__mermap_ortho_distance:nnnn {#2}{#3}{#4}{#5} + \cs_set_nopar:Npx #1 { \fp_to_decimal:N \l__mermap_result_fp } + } + + +\NewDocumentCommand \mrcprettyorthodistance { mmmm } + { + \__mermap_ortho_distance:nnnn {#1}{#2}{#3}{#4} + \__mermap_pretty_distance:n { \l__mermap_result_fp } + } + +\NewDocumentCommand \mrcNPprettyorthodistance { mm } + { + \__mermap_ortho_distance:nnnn {\mrcNPlat{#1}}{\mrcNPlon{#1}}{\mrcNPlat{#2}}{\mrcNPlon{#2}} + \__mermap_pretty_distance:n { \l__mermap_result_fp } + } + + +\cs_new_nopar:Npn \__mermap_loxo_distance:nnnn #1#2#3#4 + { + \fp_set:Nn \l__mermap_delta_phi_fp {(#3-(#1))/180*pi} + \fp_set:Nn \l__mermap_delta_lambda_fp {(#4-(#2))/180*pi} + \fp_compare:nNnTF {abs(\l__mermap_delta_phi_fp)} < {1e-5} + { + \fp_set:Nn \l_tmpa_fp { tand(#1) } + \fp_set:Nn \l_tmpb_fp { \l__mermap_delta_lambda_fp*cosd(#1) + /( 1 + (\l_tmpa_fp + (1+2*\l_tmpa_fp*\l_tmpa_fp)*\l__mermap_delta_phi_fp/3)*\l__mermap_delta_phi_fp/2 ) } + \fp_set:Nn \l__mermap_result_fp { + sqrt( \l__mermap_delta_phi_fp*\l__mermap_delta_phi_fp + \l_tmpb_fp*\l_tmpb_fp ) } + } + { + \fp_set:Nn \l__mermap_result_fp { abs(\l__mermap_delta_phi_fp) + *sqrt( 1+ (\l__mermap_delta_lambda_fp/( ln(tand(#3/2+45)) - ln(tand(#1/2+45)) ) )^2 ) } + } + \fp_set:Nn \l__mermap_result_fp { \c__mermap_scale_radius_fp*180/pi * \l__mermap_result_fp } + } + + +\NewDocumentCommand \mrcstoreloxodistance { mmmmm } + { + \__mermap_loxo_distance:nnnn {#2}{#3}{#4}{#5} + \cs_set_nopar:Npx #1 { \fp_to_decimal:N \l__mermap_result_fp } + } + + +\NewDocumentCommand \mrcprettyloxodistance { mmmm } + { + \__mermap_loxo_distance:nnnn {#1}{#2}{#3}{#4} + \__mermap_pretty_distance:n { \l__mermap_result_fp } + } + + +\NewDocumentCommand \mrcNPprettyloxodistance { mm } + { + \__mermap_loxo_distance:nnnn {\mrcNPlat{#1}}{\mrcNPlon{#1}}{\mrcNPlat{#2}}{\mrcNPlon{#2}} + \__mermap_pretty_distance:n { \l__mermap_result_fp } + } + + + +%---- supplier ----------------------------------------------------------------- + +\file_input:n { \mrcpkgprefix mercatorsupplier.def } diff --git a/Master/texmf-dist/tex/latex/mercatormap/mercatorpy.def b/Master/texmf-dist/tex/latex/mercatormap/mercatorpy.def new file mode 100644 index 00000000000..fe608f47b49 --- /dev/null +++ b/Master/texmf-dist/tex/latex/mercatormap/mercatorpy.def @@ -0,0 +1,535 @@ +\begin{filecontents*}[overwrite]{maptiles.texpy} +""" +The LaTeX package mercatormap - version 1.00 (2020/04/20) +maptiles.texpy: Python script for map tile download + +------------------------------------------------------------------------------------------- +Copyright (c) 2020 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de> +------------------------------------------------------------------------------------------- + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3 +of this license or (at your option) any later version. +The latest version of this license is in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +This work has the LPPL maintenance status `author-maintained'. + +This work consists of all files listed in README +""" + +import argparse +import math +import os +import requests +from pathlib import Path +from PIL import Image + + +packageversion = '1.00 (2020/04/20)' + + +def gd(x): + return math.atan(math.sinh(x)) + + +def arggd(x): + return math.asinh(math.tan(x)) + + +def rad2planar(lon_rad, lat_rad): + x = 0.5*lon_rad/math.pi + 0.5 + y = 0.5*arggd(lat_rad)/math.pi + 0.5 + return (x, y) + + +def deg2planar(lon_deg, lat_deg): + return rad2planar(math.radians(lon_deg), math.radians(lat_deg)) + + +def planar2rad(x, y): + lon_rad = math.pi*(2*x-1) + lat_rad = gd(math.pi*(2*y-1)) + return (lon_rad, lat_rad) + + +def planar2deg(x, y): + (lon_rad, lat_rad) = planar2rad(x, y) + return (math.degrees(lon_rad), math.degrees(lat_rad)) + + +def download(session, url, filename, overwrite=False): + local_file = Path(filename) + if local_file.is_file() and not overwrite: + return + print(url+' -> '+filename) + r = session.get(url) + r.raise_for_status() + with open(filename, 'wb') as handler: + handler.write(r.content) + return + + +def makeparentdirs(afile): + directory = Path(os.path.abspath(afile)).parent + if not directory.is_dir(): + os.makedirs(directory) + + +class MapDefinition(object): + def __init__(self, args, west, east, north, south, zoom, x_1, y_1, x_2, y_2, + width, height, west_offset, north_offset, south_offset): + self.west = west + self.east = east + self.north = north + self.south = south + self.zoom = zoom + self.x_1 = x_1 + self.y_1 = y_1 + self.x_2 = x_2 + self.y_2 = y_2 + self.width = width + self.height= height + self.west_offset = west_offset + self.north_offset = north_offset + self.south_offset = south_offset + self.n = 2 ** self.zoom + self.local_file_prefix = 'tiles/tile_' + self.attribution = args.attribution + self.attributionprint = args.attributionprint + self.pixel = args.pixel + self.pixel_width = round(self.width*self.pixel) + self.pixel_height = round(self.height*self.pixel) + self.tilesize = args.tilesize + + + @classmethod + def construct_from_boundaries_rad(cls, args, zoom, west_rad, east_rad, north_rad, south_rad): + if zoom<0: + zoom = 0 + if west_rad>=east_rad: + east_rad += 2*math.pi*math.ceil(0.5*(west_rad-east_rad)/math.pi+1e-10) + max_lat = gd(math.pi)-1e-10 + if north_rad<south_rad: + (north_rad, south_rad) = (south_rad, north_rad) + if north_rad > max_lat: + north_rad = max_lat + if south_rad < -max_lat: + south_rad = -max_lat + P = 2**(zoom-1)/math.pi + a1 = (west_rad+math.pi)*P + b1 = (math.pi-arggd(north_rad))*P + a2 = (east_rad+math.pi)*P + b2 = (math.pi-arggd(south_rad))*P + x1 = math.floor(a1) + y1 = math.floor(b1) + x2 = math.ceil(a2)-1 + y2 = math.ceil(b2)-1 + width = a2-a1 + height = b2-b1 + west_offset = a1-x1 + north_offset = b1-y1 + south_offset = y2-b2+1 + return cls(args, west_rad, east_rad, north_rad, south_rad, zoom, x1, y1, x2, y2, + width, height, west_offset, north_offset, south_offset ) + + + @classmethod + def construct_from_boundaries_deg(cls, args, zoom, west_deg, east_deg, north_deg, south_deg): + return cls.construct_from_boundaries_rad(args, + zoom,math.radians(west_deg),math.radians(east_deg), + math.radians(north_deg),math.radians(south_deg)) + + + @classmethod + def construct_from_boundaries_args(cls, args): + return cls.construct_from_boundaries_rad(args, + args.zoom,math.radians(args.west),math.radians(args.east),math.radians(args.north),math.radians(args.south)) + + + @classmethod + def construct_from_reference_rad(cls, args, zoom, width, height, + ref_lon_rad, ref_lat_rad, xalign, yalign): + if zoom<0: + zoom = 0 + P = 2**(zoom-1)/math.pi + ac = (ref_lon_rad+math.pi)*P + bc = (math.pi-arggd(ref_lat_rad))*P + a1 = ac - (1+xalign)/2*width + a2 = a1 + width + b1 = bc - (1+yalign)/2*height + b2 = b1 + height + west_rad = a1/P - math.pi + north_rad = gd(math.pi-b1/P) + east_rad = a2/P - math.pi + south_rad = gd(math.pi-b2/P) + x1 = math.floor(a1) + y1 = math.floor(b1) + x2 = math.ceil(a2)-1 + y2 = math.ceil(b2)-1 + west_offset = a1-x1 + north_offset = b1-y1 + south_offset = y2-b2+1 + return cls(args, west_rad, east_rad, north_rad, south_rad, zoom, x1, y1, x2, y2, + width, height, west_offset, north_offset, south_offset ) + + + @classmethod + def construct_from_reference_deg(cls, args, zoom, width, height, + ref_lon_deg, ref_lat_deg, xalign, yalign): + return cls.construct_from_center_rad(args, zoom, width, height, + math.radians(ref_lon_deg), math.radians(ref_lat_deg), xalign, yalign) + + + @classmethod + def construct_from_reference_args(cls, args): + return cls.construct_from_reference_rad(args, args.zoom, args.width, args.height, + math.radians(args.longitude), math.radians(args.latitude), args.xalign, args.yalign) + + + @classmethod + def construct_to_fit_region_rad(cls, args, width, height, reg_west_rad, reg_east_rad, + reg_north_rad, reg_south_rad, xalign, yalign): + if reg_west_rad>=reg_east_rad: + reg_east_rad += 2*math.pi*math.ceil(0.5*(reg_west_rad-reg_east_rad)/math.pi+1e-10) + max_lat = gd(math.pi)-1e-10 + if reg_north_rad<reg_south_rad: + (reg_north_rad, reg_south_rad) = (reg_south_rad, reg_north_rad) + if reg_north_rad > max_lat: + reg_north_rad = max_lat + if reg_south_rad < -max_lat: + reg_south_rad = -max_lat + zoom = max( 0, 1 + math.floor( math.log2( math.pi * + min( width/(reg_east_rad-reg_west_rad), height/(arggd(reg_north_rad)-arggd(reg_south_rad))) + ))) + P = 2**(zoom-1)/math.pi + + if xalign<0: + a1 = (reg_west_rad+math.pi)*P + a2 = a1 + width + elif xalign>0: + a2 = (reg_east_rad+math.pi)*P + a1 = a2 - width + else: + a1 = ((reg_west_rad+reg_east_rad)/2+math.pi)*P - width/2 + a2 = a1 + width + + if yalign<0: + b1 = (math.pi-arggd(reg_north_rad))*P + b2 = b1 + height + elif yalign>0: + b2 = (math.pi-arggd(reg_south_rad))*P + b1 = b2 - height + else: + b1 = (math.pi-(arggd(reg_north_rad)+arggd(reg_south_rad))/2)*P - height/2 + b2 = b1 + height + west_rad = a1/P - math.pi + north_rad = gd(math.pi-b1/P) + east_rad = a2/P - math.pi + south_rad = gd(math.pi-b2/P) + x1 = math.floor(a1) + y1 = math.floor(b1) + x2 = math.ceil(a2)-1 + y2 = math.ceil(b2)-1 + west_offset = a1-x1 + north_offset = b1-y1 + south_offset = y2-b2+1 + return cls(args, west_rad, east_rad, north_rad, south_rad, zoom, x1, y1, x2, y2, + width, height, west_offset, north_offset, south_offset ) + + + @classmethod + def construct_to_fit_region_deg(cls, args, width, height, + reg_west_deg, reg_east_deg, reg_north_deg, reg_south_deg, + xalign, yalign): + return cls.construct_to_fit_region_rad(args, width, height, + math.radians(reg_west_deg),math.radians(reg_east_deg), + math.radians(reg_north_deg),math.radians(reg_south_deg), + xalign, yalign) + + + @classmethod + def construct_to_fit_region_args(cls, args): + return cls.construct_to_fit_region_rad(args, args.width, args.height, + math.radians(args.west),math.radians(args.east), + math.radians(args.north),math.radians(args.south), + args.xalign, args.yalign) + + + def get_tile_quantity(self): + return (self.x_2-self.x_1+1)*(self.y_2-self.y_1+1) + + + def get_pixel_quantity(self): + return self.pixel_width*self.pixel_height + + + def download_tiles(self, url_format, local_file_prefix): + self.local_file_prefix = local_file_prefix + makeparentdirs(local_file_prefix) + with requests.Session() as s: + s.headers.update(dict(referer = 'mercatormap/'+packageversion)) + try: + for xx in range(self.x_1, self.x_2+1): + x = xx % self.n + for y in range(self.y_1, self.y_2+1): + if (y>=0) and (y<self.n): + url = url_format.format(x=x, y=y, z=self.zoom) + filename = local_file_prefix + '_{z}_{x}_{y}.png'.format(x=x, y=y, z=self.zoom) + download(s,url,filename) + except requests.exceptions.RequestException as err: + print('Download error:', err) + return False + return True + + + def merge_map(self, map_definition, local_file_prefix): + makeparentdirs(map_definition) + new_im = Image.new('RGB', (self.pixel_width, self.pixel_height), 'white') + xoff = -round(self.west_offset*self.pixel) + for xx in range(self.x_1, self.x_2+1): + x = xx % self.n + yoff = -round(self.north_offset*self.pixel) + for y in range(self.y_1, self.y_2+1): + if (y>=0) and (y<self.n): + filename = local_file_prefix + '_{z}_{x}_{y}.png'.format(x=x, y=y, z=self.zoom) + new_im.paste(Image.open(filename), (xoff,yoff)) + yoff+=self.pixel + xoff+=self.pixel + new_im.save(map_definition+'.png', optimize=True) + return True + + + def download_wms_map(self, url_format, map_definition): + makeparentdirs(map_definition) + # bbox in tiles for given zoom + xmin = self.x_1+self.west_offset + xmax = xmin+self.width + ymin = self.y_1+self.north_offset + ymax = ymin+self.height + + # global scale bbox + f = math.pi*6378137 + xmin = (2*xmin/self.n-1)*f + xmax = (2*xmax/self.n-1)*f + (ymin, ymax) = (ymax, ymin) # switch ymin/ymax + ymin = (1-2*ymin/self.n)*f + ymax = (1-2*ymax/self.n)*f + + url = url_format.format(xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax, + width=self.pixel_width, height=self.pixel_height) + filename = map_definition+'.png' + with requests.Session() as s: + s.headers.update(dict(referer = 'mercatormap/'+packageversion)) + try: + download(s,url,filename,True) + except requests.exceptions.RequestException as err: + print('Download error:', err) + return False + return True + + + def save_map(self, map_definition, tiles=False, merge=False, wms=False): + makeparentdirs(map_definition) + with open(map_definition+'.def', "w", encoding="utf-8") as desc: + desc.write(f'% generated by mercatormap maptiles {packageversion}\n') + desc.write('\\mrcdefinemap{\n') + desc.write(f' west={math.degrees(self.west)},\n') + desc.write(f' east={math.degrees(self.east)},\n') + desc.write(f' north={math.degrees(self.north)},\n') + desc.write(f' south={math.degrees(self.south)},\n') + desc.write(f' zoom={self.zoom},\n') + desc.write(f' xmin={self.x_1},\n') + desc.write(f' ymin={self.y_1},\n') + desc.write(f' xmax={self.x_2},\n') + desc.write(f' ymax={self.y_2},\n') + desc.write(f' pixelwidth={self.pixel_width},\n') + desc.write(f' pixelheight={self.pixel_height},\n') + desc.write(f' westoffset={self.west_offset},\n') + desc.write(f' northoffset={self.north_offset},\n') + desc.write(f' southoffset={self.south_offset},\n') + desc.write(f' basename={self.local_file_prefix},\n') + if self.attribution!=None: + desc.write(' attribution={'+self.attribution+'},\n') + if self.attributionprint!=None: + desc.write(' attribution print={'+self.attributionprint+'},\n') + if self.tilesize!=None: + desc.write(f' tile size={self.tilesize},\n') + if wms: + desc.write(f' resource=wmsmap,\n') + elif merge: + desc.write(f' resource=mergedmap,\n') + elif tiles: + desc.write(f' resource=tiles,\n') + else: + desc.write(f' resource=none,\n') + desc.write('}\n') + return + + + def print_description(self): + print('------ map description (class) ------') + print(f'west = {math.degrees(self.west)}') + print(f'east = {math.degrees(self.east)}') + print(f'north = {math.degrees(self.north)}') + print(f'south = {math.degrees(self.south)}') + print(f'zoom = {self.zoom}') + print(f'X_1 = {self.x_1}') + print(f'Y_1 = {self.y_1}') + print(f'X_2 = {self.x_2}') + print(f'Y_2 = {self.y_2}') + print(f'width = {self.width}') + print(f'height = {self.height}') + print(f'd_west = {self.west_offset}') + print(f'd_north = {self.north_offset}') + print(f'd_south = {self.south_offset}') + return + + +def map_tile_info(Z, X, Y): + N = 2.0 ** Z + lon_min = math.pi*(2*X-N)/N + lon_max = math.pi*(2*X+2-N)/N + lat_min = gd(math.pi*(N-2*Y-2)/N) + lat_max = gd(math.pi*(N-2*Y)/N) + r = 6371000 + height = r*(lat_max-lat_min) + rdel_lon = r*(lon_max-lon_min) + width_n = rdel_lon*math.cos(lat_max) + width_s = rdel_lon*math.cos(lat_min) + area = r*rdel_lon*(math.sin(lat_max)-math.sin(lat_min)) + print(f'(Z,X,Y) = ({Z},{X},{Y})') + print(f'west = {math.degrees(lon_min)}') + print(f'east = {math.degrees(lon_max)}') + print(f'south = {math.degrees(lat_min)}') + print(f'north = {math.degrees(lat_max)}') + print(f'height = {height/1000}') + print(f'width(N)= {width_n/1000}') + print(f'width(S)= {width_s/1000}') + print(f'area = {area/1000000}') + return + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Compute a full map description and download map tiles') + + parser.add_argument('type', type=str, help='type of map computation', + choices=['boundaries', 'reference', 'areafit']) + + parser.add_argument('-z', '--zoom', type=int, default=9, + help='zoom level (boundaries/reference)') + parser.add_argument('-w', '--west', type=float, default=11, + help='longitude west (boundaries/areafit)') + parser.add_argument('-e', '--east', type=float, default=13, + help='longitude east (boundaries/areafit)') + parser.add_argument('-n', '--north', type=float, default=48, + help='latitude north (boundaries/areafit)') + parser.add_argument('-s', '--south', type=float, default=50, + help='latitude south (boundaries/areafit)') + parser.add_argument('-lon', '--longitude', type=float, default=12, + help='longitude (reference)') + parser.add_argument('-lat', '--latitude', type=float, default=49, + help='latitude (reference)') + parser.add_argument('-mw', '--width', type=float, default=4, + help='map width as multiplicity of map tiles (reference/areafit)') + parser.add_argument('-mh', '--height', type=float, default=4, + help='map height as multiplicity of map tiles (reference/areafit)') + parser.add_argument('-a', '--align', type=str, default='center', + help='alignment of reference or area (reference/areafit)', + choices=['northwest', 'north', 'northeast', + 'west', 'center', 'east', + 'southwest', 'south', 'southeast'] ) + parser.add_argument('-d', '--definition', type=str, default='mapdefinition', + help='name of the produced map definition for LaTeX') + parser.add_argument('-t', '--target', type=str, default='tiles', + help='target to create tiles or a merged map', + choices=['none', 'tiles', 'mergedmap', 'wmsmap'] ) + parser.add_argument('-u', '--url', type=str, default=None, + help='url format with placeholder {z}{x}{y} for downloading tiles') + parser.add_argument('-at', '--attribution', type=str, default=None, + help='attribution text of the tile producer') + parser.add_argument('-atp', '--attributionprint', type=str, default=None, + help='attribution text of the tile producer') + parser.add_argument('-f', '--fileprefix', type=str, default='tiles/unknown', + help='prefix for local tile files, e.g. "tiles/map" for "tiles/map_10_10_10.png"') + parser.add_argument('-c', '--confirm', action="store_true", + help='confirm bulk download for map tiles') + parser.add_argument('-p', '--pixel', type=int, default=256, + help='pixel width/height of a tile') + parser.add_argument('-ts', '--tilesize', type=str, default=None, + help='TeX tile size') + + args = parser.parse_args() + + print('') + print('** This is maptiles.py version', packageversion, + 'for generating', args.definition) + + switcher = { + 'northwest': (-1,-1), + 'north': ( 0,-1), + 'northeast': ( 1,-1), + 'west': (-1, 0), + 'center': ( 0, 0), + 'east': ( 1, 0), + 'southwest': (-1, 1), + 'south': ( 0, 1), + 'southeast': ( 1, 1) + } + (args.xalign, args.yalign) = switcher.get(args.align) + + switcher = { + 'boundaries': MapDefinition.construct_from_boundaries_args, + 'reference': MapDefinition.construct_from_reference_args, + 'areafit': MapDefinition.construct_to_fit_region_args + } + mapdef = switcher.get(args.type)(args) + + switcher = { + 'none': 0, + 'tiles': 1, + 'mergedmap': 2, + 'wmsmap': 3 + } + target = switcher.get(args.target) + + tiles_success = False + merge_success = False + wms_success = False + + if target>0: + if args.url!=None: + if target<3: + if mapdef.get_tile_quantity()>400: + if args.confirm: + tiles_success = mapdef.download_tiles(args.url, args.fileprefix) + else: + print(f'Too many tiles ({mapdef.get_tile_quantity()}). Add confirm option to proceed anyway.'); + else: + tiles_success = mapdef.download_tiles(args.url, args.fileprefix) + if tiles_success: + print('** Download of tiles successful for', args.definition) + if target>1: + merge_success = mapdef.merge_map(args.definition, args.fileprefix) + if merge_success: + print('** Merging tiles successful for', args.definition) + else: + print('** WARNING: Merging tiles failed for', args.definition) + else: + print('** WARNING: Map tiles download failed for', args.definition) + else: + if mapdef.get_pixel_quantity()>100000000: + if args.confirm: + wms_success = mapdef.download_wms_map(args.url, args.definition) + else: + print(f'Too many pixels ({mapdef.get_pixel_quantity()}). Add confirm option to proceed anyway.'); + else: + wms_success = mapdef.download_wms_map(args.url, args.definition) + else: + print('No url for download given') + + mapdef.save_map(args.definition, tiles_success, merge_success, wms_success) +\end{filecontents*} + diff --git a/Master/texmf-dist/tex/latex/mercatormap/mercatorsupplier.def b/Master/texmf-dist/tex/latex/mercatormap/mercatorsupplier.def new file mode 100644 index 00000000000..438374ba26f --- /dev/null +++ b/Master/texmf-dist/tex/latex/mercatormap/mercatorsupplier.def @@ -0,0 +1,290 @@ +%% The LaTeX package mercatormap - version 1.00 (2020/04/20) +%% mercatorsupplier.def: predefined map supplier list +%% +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2020 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de> +%% ------------------------------------------------------------------------------------------- +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This work consists of all files listed in README +%% + +\NewDocumentCommand\mrcumlaut{m}{\"{#1}} + +\cs_new:Npn \__mermap_new_supply_source:nn #1#2 + { + \keys_define:nn { mermap/supply/_source } + { + #1 .meta:nn = {mermap/supply}{#2} + } + } + +\NewDocumentCommand\mrcnewsupplysource {mm} { + \__mermap_new_supply_source:nn {#1}{#2} +} + +\__mermap_new_supply_source:nn { dummy } + { + url = http://127.0.0.1/dummy/{z}/{x}/{y}.png, + attribution = {Dummy~tile~server}, + attribution~print = {Dummy~tile~server}, + basename = tiles/dummy, + } + +\__mermap_new_supply_source:nn { opentopomap } + { + url = https://tile.opentopomap.org/{z}/{x}/{y}.png, + attribution = { + Kartendaten:~\textcopyright\nobreakspace\href{https://openstreetmap.org/copyright}{OpenStreetMap} + \ Mitwirkende,~SRTM\nobreakspace\textbar\nobreakspace + Kartendarstellung:~\textcopyright\nobreakspace\href{http://opentopomap.org/}{OpenTopoMap} + \ (\href{https://creativecommons.org/licenses/by-sa/3.0/}{CC-BY-SA}) + }, + attribution~print = { + Kartendaten:~\textcopyright\nobreakspace www.openstreetmap.org/copyright, + \ SRTM\nobreakspace\textbar\nobreakspace + Kartendarstellung:~\textcopyright\nobreakspace opentopomap.org~(CC-BY-SA) + }, + basename = tiles/opentopomap, + } + +\keys_define:nn { mermap/supply } + { + __attribution_topplusopen .meta:nn = {mermap/supply} { + attribution = { + \textcopyright\nobreakspace\href{http://www.bkg.bund.de}{Bundesamt~f\mrcumlaut{u}r~Kartographie~und~Geod\mrcumlaut{a}sie}\nobreakspace\the\year, + \ \href{http://sg.geodatenzentrum.de/web_public/Datenquellen_TopPlus_Open.pdf}{Datenquellen} + }, + attribution~print = { + \textcopyright\nobreakspace Bundesamt~f\mrcumlaut{u}r~Kartographie~und~Geod\mrcumlaut{a}sie\nobreakspace\the\year, + \ Datenquellen:~\detokenize{http://sg.geodatenzentrum.de/web_public/Datenquellen_TopPlus_Open.pdf} + } + } + } + +\__mermap_new_supply_source:nn { topplusopen~web } + { + url = {https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web/default/WEBMERCATOR/{z}/{y}/{x}.png}, + __attribution_topplusopen, + basename = tiles/tpo_web, + } + +\__mermap_new_supply_source:nn { topplusopen~web~grau } + { + url = {https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web_grau/default/WEBMERCATOR/{z}/{y}/{x}.png}, + __attribution_topplusopen, + basename = tiles/tpo_web_grau, + } + +\cs_new:Npn \__mermap_new_supply_source_topplusopen:n #1 + { + \keys_define:nn { mermap/supply/_source } + { + topplusopen~#1 .meta:nn = {mermap/supply}{ + url = {https://sgx.geodatenzentrum.de/wms_topplus_open?service=wms&version=1.3.0&request=GetMap&Layers=#1&STYLES=default&CRS=EPSG:3857&bbox={xmin},{ymin},{xmax},{ymax}&width={width}&height={height}&Format=image/png}, + __attribution_topplusopen, + basename = tiles/tpo, + }, + topplusopen~#1~grau .meta:nn = {mermap/supply}{ + url = {https://sgx.geodatenzentrum.de/wms_topplus_open?service=wms&version=1.3.0&request=GetMap&Layers=#1_grau&STYLES=default&CRS=EPSG:3857&bbox={xmin},{ymin},{xmax},{ymax}&width={width}&height={height}&Format=image/png}, + __attribution_topplusopen, + basename = tiles/tpo, + }, + } + } +\__mermap_new_supply_source_topplusopen:n { p5 } +\__mermap_new_supply_source_topplusopen:n { p10 } +\__mermap_new_supply_source_topplusopen:n { p17.5 } +\__mermap_new_supply_source_topplusopen:n { p25 } +\__mermap_new_supply_source_topplusopen:n { p50 } +\__mermap_new_supply_source_topplusopen:n { p100 } +\__mermap_new_supply_source_topplusopen:n { p250 } + +\__mermap_new_supply_source:nn { openrouteservice~mapsurfer } + { + url~with~api~key = {https://api.openrouteservice.org/mapsurfer/{z}/{x}/{y}.png?api_key=}{openrouteservice}{}, + attribution = { + Service~\textcopyright\nobreakspace\href{https://openrouteservice.org/}{openrouteservice.org} + \nobreakspace\textbar\nobreakspace + Map~data~\textcopyright\nobreakspace\href{https://openstreetmap.org/copyright}{OpenStreetMap}~contributors + }, + attribution~print = { + Service~\textcopyright\nobreakspace openrouteservice.org + \nobreakspace\textbar\nobreakspace + Map~data~\textcopyright\nobreakspace OpenStreetMap~contributors + }, + basename = tiles/mapsurfer, + } + +\keys_define:nn { mermap/supply } + { + __attribution_stamen .meta:nn = {mermap/supply} { + attribution = { + Map~tiles~by~\href{http://stamen.com}{Stamen~Design}, + \ under~\href{http://creativecommons.org/licenses/by/3.0}{CC~BY~3.0}. + \ Data~by~\href{http://openstreetmap.org}{OpenStreetMap}, + \ under~\href{http://www.openstreetmap.org/copyright}{ODbL}. + }, + attribution~print = { + Map~tiles~by~Stamen~Design~(stamen.com), + \ under~CC~BY~3.0. + \ Data~by~OpenStreetMap, + \ under~ODbl~(www.openstreetmap.org/copyright). + } + } + } +\__mermap_new_supply_source:nn { stamen~terrain } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/terrain/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/terrain, + } +\__mermap_new_supply_source:nn { stamen~terrain-background } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/terrain-background/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/terrain-background, + } +\__mermap_new_supply_source:nn { stamen~terrain-labels } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/terrain-labels/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/terrain-labels, + } +\__mermap_new_supply_source:nn { stamen~terrain-lines } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/terrain-lines/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/terrain-lines, + } +\__mermap_new_supply_source:nn { stamen~toner } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/toner/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/toner, + } +\__mermap_new_supply_source:nn { stamen~toner-lite } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/toner-lite, + } +\__mermap_new_supply_source:nn { stamen~toner-hybrid } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/toner-hybrid/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/toner-hybrid, + } +\__mermap_new_supply_source:nn { stamen~toner-background } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/toner-background/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/toner-background, + } +\__mermap_new_supply_source:nn { stamen~toner-labels } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/toner-labels/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/toner-labels, + } +\__mermap_new_supply_source:nn { stamen~toner-lines } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/toner-lines/{z}/{x}/{y}.png}, + __attribution_stamen, + basename = tiles/toner-lines, + } +\__mermap_new_supply_source:nn { stamen~watercolor } + { + url = {https://stamen-tiles-a.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png}, + attribution = { + Map~tiles~by~\href{http://stamen.com}{Stamen~Design}, + \ under~\href{http://creativecommons.org/licenses/by/3.0}{CC~BY~3.0}. + \ Data~by~\href{http://openstreetmap.org}{OpenStreetMap}, + \ under~\href{http://creativecommons.org/licenses/by-sa/3.0}{CC~BY~SA}. + }, + attribution~print = { + Map~tiles~by~Stamen~Design~(stamen.com), + \ under~CC~BY~3.0. + \ Data~by~OpenStreetMap, + \ under~CC~BY~SA. + }, + basename = tiles/watercolor, + } + +\keys_define:nn { mermap/supply } + { + __attribution_thunderforest .meta:nn = {mermap/supply} { + attribution = { + Maps~\textcopyright\nobreakspace\href{https://www.thunderforest.com/}{Thunderforest}, + \ Data~\textcopyright\nobreakspace\href{https://openstreetmap.org/copyright}{OpenStreetMap~contributors} + }, + attribution~print = { + Maps~\textcopyright\nobreakspace www.thunderforest.com, + \ Data~\textcopyright\nobreakspace www.osm.org/copyright + } + } + } +\__mermap_new_supply_source:nn { thunderforest~opencyclemap } + { + url~with~api~key = {https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/opencyclemap, + } +\__mermap_new_supply_source:nn { thunderforest~transport } + { + url~with~api~key = {https://tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/transport, + } +\__mermap_new_supply_source:nn { thunderforest~landscape } + { + url~with~api~key = {https://tile.thunderforest.com/landscape/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/landscape, + } +\__mermap_new_supply_source:nn { thunderforest~outdoors } + { + url~with~api~key = {https://tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/outdoors, + } +\__mermap_new_supply_source:nn { thunderforest~transport-dark } + { + url~with~api~key = {https://tile.thunderforest.com/transport-dark/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/transport-dark, + } +\__mermap_new_supply_source:nn { thunderforest~spinal-map } + { + url~with~api~key = {https://tile.thunderforest.com/spinal-map/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/spinal-map, + } +\__mermap_new_supply_source:nn { thunderforest~pioneer } + { + url~with~api~key = {https://tile.thunderforest.com/pioneer/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/pioneer, + } +\__mermap_new_supply_source:nn { thunderforest~mobile-atlas } + { + url~with~api~key = {https://tile.thunderforest.com/mobile-atlas/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/mobile-atlas, + } +\__mermap_new_supply_source:nn { thunderforest~neighbourhood } + { + url~with~api~key = {https://tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png?apikey=}{thunderforest}{}, + __attribution_thunderforest, + basename = tiles/neighbourhood, + } + diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index ccb3e480862..ed969d6f7df 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -478,7 +478,7 @@ my @TLP_working = qw( mdframed mdputu mdsymbol mdwtools media4svg media9 medstarbeamer meetingmins memdesign memexsupp memoir MemoirChapStyles memory memorygraphs mendex-doc mentis - mensa-tex menu menukeys merriweather + mensa-tex menu menukeys mercatormap merriweather metafont-beginners metago metalogo metalogox metaobj metaplot metapost-colorbrewer metapost-examples metastr metatex metatype1 metauml method metre metrix diff --git a/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc b/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc index 306b4c3508b..e74f7c48e30 100644 --- a/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc @@ -84,6 +84,7 @@ depend luasseq depend maker depend makeshape depend mathspic +depend mercatormap depend milsymb depend miniplot depend mkpic diff --git a/Master/tlpkg/tlpsrc/mercatormap.tlpsrc b/Master/tlpkg/tlpsrc/mercatormap.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/mercatormap.tlpsrc |