%% The LaTeX package mercatormap - version 1.02 (2020/08/06) %% mercatormap.sty: geographic coordinates (Mercator projection) and map tiles for TikZ pictures %% %% ------------------------------------------------------------------------------------------- %% Copyright (c) 2020 by Prof. Dr. Dr. Thomas F. Sturm %% ------------------------------------------------------------------------------------------- %% %% 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/08/06}{1.02} {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_tl\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_tl\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_tl\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 \bool_new:N \l__mermap_fail_on_missing_resource_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 \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 } } } \msg_new:nnn { mercatormap }{ input-area-marker } { The~marker~input~file~'#1'~does~not~exist. } \cs_new:Npn \__mermap_supply_add_area_marker_position: { \fp_compare:nNnT \l__mermap_marker_latitude_fp < \l__mermap_supply_south_fp { \fp_set_eq:NN \l__mermap_supply_south_fp \l__mermap_marker_latitude_fp } \fp_compare:nNnT \l__mermap_marker_latitude_fp > \l__mermap_supply_north_fp { \fp_set_eq:NN \l__mermap_supply_north_fp \l__mermap_marker_latitude_fp } \fp_compare:nNnT \l__mermap_marker_longitude_fp < \l__mermap_supply_west_fp { \fp_set_eq:NN \l__mermap_supply_west_fp \l__mermap_marker_longitude_fp } \fp_compare:nNnT \l__mermap_marker_longitude_fp > \l__mermap_supply_east_fp { \fp_set_eq:NN \l__mermap_supply_east_fp \l__mermap_marker_longitude_fp } } \cs_new:Npn \__mermap_supply_add_area_marker:n #1 { \group_begin: \RenewDocumentCommand \mrcmarker { m } { \keys_set:nn { mermap/marker } { ##1 } \__mermap_supply_add_area_marker_position: } \file_if_exist_input:nF {#1} { \msg_error:nnn { mercatormap }{ input-area-marker }{ #1 } } \tl_gset:Nx \g_tmpa_tl { \exp_not:N\fp_set:Nn \exp_not:N\l__mermap_supply_west_fp { \fp_to_decimal:N\l__mermap_supply_west_fp } \exp_not:N\fp_set:Nn \exp_not:N\l__mermap_supply_east_fp { \fp_to_decimal:N\l__mermap_supply_east_fp } \exp_not:N\fp_set:Nn \exp_not:N\l__mermap_supply_south_fp { \fp_to_decimal:N\l__mermap_supply_south_fp } \exp_not:N\fp_set:Nn \exp_not:N\l__mermap_supply_north_fp { \fp_to_decimal:N\l__mermap_supply_north_fp } } \group_insert_after:N \g_tmpa_tl \group_end: } \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 }, area~from~marker~input .code:n = { \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_marker:n { #1 } }, area~from~marker~input .value_required:n = true, add~area~from~marker~input .code:n = { \__mermap_supply_add_area_marker:n { #1 } }, 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}}, fail~on~missing~resource .bool_set:N = \l__mermap_fail_on_missing_resource_bool, python .code:n = { \tl_set:Nx \l__mermap_python_tl {#1~maptiles.texpy} }, } \keys_set:nn { mermap } { definition~prefix = maps/, fail~on~missing~resource = true, 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: } \group_end: } \NewDocumentCommand \mrcsupplymap { O{} m } { \__mermap_create_definition_id:n {#2} \__mermap_supplymap:n {#1} } \msg_new:nnnn { mercatormap }{ shell-escape } { You~must~invoke~LaTeX~with~the~--shell-escape~flag~to~produce~map~'#1'. } { The~--shell-escape~flag~is~needed,~because~a~Python~sript~has~to~be~called;~see~package~documentation. } \msg_new:nnnn { mercatormap }{ target-resource } { Target~and~produced~resource~are~different~for~map~'#1'. } { Your~target~was~'\l__mermap_supply_target_tl'.\\ The~produced~resource~is~'\l__mermap_tile_resource_tl'.\\ Check,~if~'\l__mermap_supply_target_tl'~is~available~via~'\str_use:N\l__mermap_supply_url_str'\\ or~if~the~zoom~value~is~too~large. } \msg_new:nnnn { mercatormap }{ definition-production } { Map~definition~file~not~produced~for~map~'#1'. } { **~The~failed~shell~command~was:\\ \l__mermap_supply_call_tl\\ **~Python~setup~correct? } \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} } \file_if_exist:nTF {\l__mermap_definition_id_str.def} { \tl_clear:N \l__mermap_last_mdfivesum_tl \file_if_exist_input:n {\l__mermap_definition_id_str.md5} \str_if_eq:VVF \l__mermap_mdfivesum_tl \l__mermap_last_mdfivesum_tl { \__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} \bool_if:NTF \l__mermap_fail_on_missing_resource_bool { \msg_error:nnx { mercatormap }{ target-resource }{ \l__mermap_definition_id_str } } { \msg_warning:nnx { mercatormap }{ target-resource }{ \l__mermap_definition_id_str } } } } { \msg_error:nnx { mercatormap }{ definition-production }{ \l__mermap_definition_id_str } } } { \msg_error: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 = {(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 \bool_new:N \l__mermap_marker_use_links \bool_new:N \l__mermap_marker_use_urls \fp_new:N \l__mermap_marker_angle_fp \fp_new:N \l__mermap_marker_distance_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_generic_tl \tl_new:N \l__mermap_marker_link_tl \tl_new:N \l__mermap_marker_pictocontents_tl \tl_new:N \l__mermap_marker_type_tl \tl_new:N \l__mermap_marker_url_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, uuid .tl_set:N = \l_mermap_marker_uuid_tl, generic .tl_set:N = \l_mermap_marker_generic_tl, url .tl_set:N = \l__mermap_marker_url_tl, link .tl_set:N = \l__mermap_marker_link_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, distance .fp_set:N = \l__mermap_marker_distance_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} }, use~links .bool_set:N = \l__mermap_marker_use_links, ignore~links .bool_set_inverse:N = \l__mermap_marker_use_links, use~urls .bool_set:N = \l__mermap_marker_use_urls, ignore~urls .bool_set_inverse:N = \l__mermap_marker_use_urls, 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, contents =, alias = noname, pictocontents =, angle = 90, shift = 0pt, distance = 5mm, fill = gray!20, draw = gray, text = black, radius = 3mm, inner~radius = 2.25mm, path~style =, node~style =, font = \sffamily\small, type = classic, uuid =, generic =, url =, link =, category =, show = true, use~links = true, use~urls = 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} \NewDocumentCommand\mrcmarkergeneric{}{\tl_use:N \l_mermap_marker_generic_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\mrcmarkerdistance{}{\fp_to_dim:N \l__mermap_marker_distance_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. } \cs_new_nopar:Npn \__mermap_hyper_path:n #1 { \pgfpointanchor{path~picture~bounding~box}{south~west} \pgf@xb-\pgf@x \pgf@yb-\pgf@y \pgfpointanchor{path~picture~bounding~box}{north~east} \advance\pgf@xb\pgf@x \advance\pgf@yb\pgf@y \advance\pgf@x-1bp \advance\pgf@y-1bp \advance\pgf@xb-2bp \advance\pgf@yb-2bp \pgftext[at={\pgfqpoint{\pgf@x}{\pgf@y}},right,top] { \hypersetup{pdfborder=0~0~0} #1{\vrule height\pgf@yb depth0ptwidth0pt\vrule height0ptdepth0ptwidth\pgf@xb} } } \cs_new_nopar:Npn \__mermap_hyper_path_insert: { \cs_if_exist:NT \hypersetup { \bool_if:NT \l__mermap_marker_use_urls { \tl_if_empty:NF \l__mermap_marker_url_tl { \__mermap_hyper_path:n {\href{\l__mermap_marker_url_tl}} } } \bool_if:NT \l__mermap_marker_use_links { \tl_if_empty:NF \l__mermap_marker_link_tl { \__mermap_hyper_path:n {\hyperlink{\l__mermap_marker_link_tl}} } } } } \tikzset { mrchyperpath/.style = { path~picture = {\__mermap_hyper_path_insert:} } } \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,mrchyperpath]\mrcmarkercontents}] {}; } \__mermap_new_marker_type:nn {pin} { \tl_set:Nx \l_tmpa_tl {\fp_to_dim:N \l__mermap_marker_distance_fp} \path[fill=mrcmarkerfill,draw=none,fill~opacity=0.7] (0,0) -- (0.1,\l_tmpa_tl) -- (-0.1,\l_tmpa_tl) -- 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,mrchyperpath] (pin_node) at (0,\l_tmpa_tl) {\mrcmarkercontents}; \path[draw=mrcmarkerdraw,fill=none,line~join=round,mrcpathstyle] (0,0) -- (0.1,\l_tmpa_tl) -- (pin_node.south~east) -- (pin_node.north~east) -- (pin_node.north~west) -- (pin_node.south~west) -- (-0.1,\l_tmpa_tl) [line~join=bevel] -- cycle; } \__mermap_new_marker_type:nn {pinflip} { \tl_set:Nx \l_tmpa_tl {\fp_to_dim:N \l__mermap_marker_distance_fp} \path[fill=mrcmarkerfill,draw=none,fill~opacity=0.7] (0,0) -- (-0.1,-\l_tmpa_tl) -- (0.1,-\l_tmpa_tl) -- 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,mrchyperpath] (pin_node) at (0,-\l_tmpa_tl) {\mrcmarkercontents}; \path[draw=mrcmarkerdraw,fill=none,line~join=round,mrcpathstyle] (0,0) -- (-0.1,-\l_tmpa_tl) -- (pin_node.north~west) -- (pin_node.south~west) -- (pin_node.south~east) -- (pin_node.north~east) -- (0.1,-\l_tmpa_tl) [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,mrchyperpath } \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,mrchyperpath] 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,mrchyperpath] 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,mrchyperpath,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,mrchyperpath,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,mrchyperpath] (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 }