我正在尝试在 LaTeX pdf 文档中绘制类似以下的地图:
我想从一对列表(国家,颜色)中自动生成它们来确定颜色。
pst-map2dII
我找到了包裹pst-geo
,但是它的文档是 2004 年的,是法语的,其中的教程示例似乎不再起作用(或者我没有理解法语部分的重要内容)。
这个包还能用吗?如果能,我该如何让基本版本工作?无论是英文手册还是类似于上述世界地图的简单教程示例,都会受到热烈欢迎。如果不行,其他在 LaTeX 之外自动生成它们的包或方法也同样受欢迎。
答案1
这是一张制作美国地图的 TikZ 图片。我制作它的方式如下:
- 我从维基百科下载了 svg 地图
- 我使用 Inkscape 将 svg 转换为 tikz 代码(详细模式)
- 详细模式用州的缩写名称注释了路径,所以我只是复制了名称并将它们作为每条路径的样式(你可以用正则表达式来做到这一点)
- 我
state
为每一个状态定义了一种风格和一种样式。
您可以重复相同的步骤,从 https://commons.wikimedia.org/wiki/File:BlankMap-World6.svg 获得世界地图。
现在,您只需重新定义样式即可为科罗拉多着色(或修改其渲染的许多方面)CO
。如果您愿意,可以将所有这些包装在一个宏中,并使用一个可选的样式参数来覆盖状态的样式。
代码太长了,无法回答这个问题,我将其作为要点发布在
https://gist.github.com/bordaigorl/fce575813ff943f47505
更新
上面的 Gist 现在包含两个文件:USAmap.tex 和 main.tex。第一个文件定义了一个\USA
带有可选参数的命令。main.tex 文件显示了如何使用它:
\documentclass{standalone}
\usepackage{tikz}
\input{USAmap.tex}
\begin{document}
\begin{tikzpicture}
\USA[every state={draw=white, ultra thick, fill=black!10},CA={fill=blue},NY={fill=red}]
\draw[dashed] (TX.center) -- (CA.center) -- (AL.center);
\node at (CO) {CO};
\end{tikzpicture}
\end{document}
生成以下内容
主要的附加功能是定义样式来控制每个状态的外观以及为每个状态创建(近似)节点,以便您可以例如将标签附加到状态或绘制路径等。唯一的缺点是节点的形状是状态路径的边界框(出于简单性和性能原因)因此中心可能位于其外面(例如参见 FL)但它足以让您了解可以用这种方法做什么。
状态的样式也可以使用 tikz 进行全局设置,如下所示
\tikzset{set state val/.style args={#1/#2}{#1={fill=blue!#2}}}
\tikzset{set state val/.list={CA/100,FL/80,TX/55,NY/20}}
它将列表解释{CA/100,FL/80,TX/55,NY/20}
为状态/百分比的配对,并为每个提到的状态分配一个蓝色阴影,其强度与百分比成比例。
答案2
虽然不是一个完整的解决方案,但也许是继续下去的一种方式。
如果尚未完成,您必须将所有地图数据文件安装到某个位置,例如pst-geo/data
您的 tex 发行版,并将路径添加到\WorldMap
命令中。
所有数据文件也可以从 ctan 获得:http://www.ctan.org/tex-archive/graphics/pstricks/contrib/pst-geo/data
运行xelatex
正常,但由于某种原因latex
,导致转换dvipdf
失败。
该示例取自 Herbert Voss 的书(示例 25-3-1),可从以下网址获取http://www.ctan.org/tex-archive/info/examples/PSTricks_en
\documentclass{article}
\usepackage{pstricks,pst-map2d}
\begin{document}
\psset{unit=3.7,linewidth=.75pt}
\begin{pspicture*}(-6.5,1)(-3,3)
\WorldMap[rivers=true,city=true,USA=true,maillage=true,path=/usr/local/texlive/2013/texmf-dist/tex/latex/pst-geo/data]
\end{pspicture*}
\end{document}
答案3
我知道这个帖子有点过时了,但我真的很喜欢 Bordaigorl 上面的回答。不过我很懒,所以我写了一个小 perl 脚本,将 Inkscape 输出转换为一个很好的宏源,与 Bordaigorl 上面的例子类似。
操作步骤:
- 从 Wikipedia 下载 SVG 地图。我使用了世界地图和“紧凑”版本,后者更扁平一些,并且不包括极地地区。因此https://commons.wikimedia.org/wiki/File:BlankMap-World6.svg和https://commons.wikimedia.org/wiki/File:BlankMap-World6,_compact.svg。
- 在 Inkscape 中打开 SVG 文件并将其导出为 Tikz。在导出选项中,启用“详细”模式,因为这会将所有对象名称作为注释。
- 现在通过我下面添加的 perl 脚本来执行路径,例如
cat Worldmap-raw.tex | ./Map2tikz.pl >Worldmap.tex
- 将文件包含在 TeX 中。下面还有一个例子。根据 Inkscape 输出,“ocean”可能会被捕获为路径,并最终得到样式选项 [Map/state, Map/xx],这会在第一次 TeX 运行中产生错误。在这种情况下,打开 Workmap.tex 文件,找到 Map/xx 文本(通常在第 8 行左右)并删除整个“[Map/state, Map/SD]”部分 - 或者如果您愿意,可以用漂亮的海洋样式替换。
- 展现幸福!
这里是 perl 部分:
#!/usr/bin/perl
# First written: Mon 2018-05-07 11:37:16 UTC+0200 (CEST) by Hendrik G. Seliger
# Last changes: Mon 2018-05-07 14:36:54 UTC+0200 (CEST) by Hendrik G. Seliger
# A script to read a map exported by Inkscape as verbose tikz
# and set proper path names so we can highlight countries/states
# by using their identifier
###
$, = ' '; # set output field separator
$\ = "\n"; # set output record separator
# While reading the file, we create three variables
# Set_Defaults: contains the command to set defaults for all regions
# Set_Commands: contains the code to set up commands to change each regions style
# Create_Map: The outline of the actual map. This changes the tikzpicture into a scope
$Set_Defaults = "\\tikzset{Map/.cd, state/.style={fill, draw=white, ultra thick}";
$Set_Commands = "\\tikzset{every state/.style={Map/state/.style={#1}}";
$Create_Map = "\\newcommand{\\Map}[1][]{";
# The we use a variable to always catch the current path name = state identifier
# We use "xx" to mark an unset state
$Current_State = "xx";
while ( <STDIN> ) {
# chomp; # strip record separator
# Remember current line, as we will change it further down
$Current_Line = $_;
# Get the current state/country identifier
if ( $Current_Line =~ /% (\w\w)$/) {
$Current_State = $1;
# Make it upper case
$Current_State =~ s/(.)/\u$1/g;
$Set_Defaults .= ", " . $Current_State . "/.style={}";
$Set_Commands .= ", " . $Current_State . "/.style={Map/" . $Current_State . "/.style={#1}}";
}
# rewrite path commands
# \path -> \path[Map/state, Map/XX]
# checking for "path " with space at end keeps the global/ocean background
# which is exactly what we want
if ( $Current_Line =~ /\\path /) {
# Determine current style
$Style = "[Map/state, Map/" . $Current_State . "] ";
$Current_Line =~ s/path /path$Style/g;
}
# rewrite start if tikzpicture
# \begin{tikzpicture}[y=0.80pt, x=0.80pt, yscale=-1.000000, xscale=1.000000, inner sep=0pt, outer sep=0pt] -> [y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt,#1]
if ($Current_Line =~ /\\begin{tikzpicture}\[(.*)\](.*)$/ ) {
$Current_Line = "\\begin{scope}[" . $1 .",#1]" . $2 . "\n";
}
if ($Current_Line =~ /\\end{tikzpicture}/ ) {
$Current_Line =~ s/\\end{tikzpicture}//g;
}
$Create_Map .= $Current_Line;
}
$Set_Defaults .= '}';
$Set_Commands .= '}';
$Create_Map .= "\\end{scope}}";
print $Set_Defaults;
print $Set_Commands;
print $Create_Map;
##### END OF MAIN, SUBROUTINES NEXT #####
谨防perl 脚本不进行错误检查,因此如果您对 Inkscape 输出进行修改,它就不会成功。此外,它可能无法与其他地图文件配合使用,例如,如果国家/州区域名称不正确。
顺便说一句,我只检查州/国家/地区的两个字母标识符,因为这会收集具有多个地区的国家/地区,例如美国地图上的 MI 或世界地图上的法国。后者是下一级别细分的一个很好的例子,因为并非所有部门都是名称,因此只需通过 Inkscape 导出为例如“path2168”。
以及一个示例 TeX 文件(我使用路拉泰克斯,因为我的正常 pdflatex 超出了世界地图上的内存):
% !TeX TS-program = lualatex
\documentclass{standalone}
\usepackage{tikz}
\input{Worldmap.tex}
\begin{document}
\begin{tikzpicture}
\Map[every state={draw=white, ultra thick, fill=black!10},DE={fill=blue},US={fill=red}]
\end{tikzpicture}
\end{document}
也许这对其中一个有帮助。
答案4
您是否考虑过使用 NCL 或其 Python 等效物 PyNGL?它可以生成矢量图像,而且产品非常灵活。您不仅可以制作地图,还可以对数据进行预处理和后处理以放在地图上……
https://www.ncl.ucar.edu/ https://www.pyngl.ucar.edu/
当然,代码是开源的。示例很多,安装也很容易。你可以复制代码并根据自己的需要进行调整。
这有帮助吗?Marco