在 tmap 中使用外部图标
2023年3月10日
编程
作为一个强大的专题地图绘制包,**tmap** 确实让使用 R 语言绘制地图变得非常方便。然而如果想要在地图中引入图标(通常是外部图片文件,目前仅支持 png 格式),官方文档并没有给出详细的用例,而且文档描述也语焉不详。经过一系列的摸索后,终于找到了设置图标的方法。 既然要设置图标,那绘制的数据一般是点数据,这里就以点数据为例。在函数 `tm_symbols()` 中有两个名称非常相近的参数:`shape` 和 `shapes` 。前者是用于指定形状的名称,相当于“颜色”,后者用于提供可用的形状选项,相当于“调色盘”,不妨称之为“**调形盘**”。比如,如果 `shape` 指定了 `"square"` ,那么函数会在 `shapes` 的值中寻找名称为 `"square"` 的形状,然后使用该形状绘制要素。 # 生成形状选项——调形盘 函数默认提供的形状都是 R 语言自带的几种形状(21-25),如果想要使用自定义的图标,那么就需要使用 `tmap_icons()` 函数生成一个“调形盘”。假设 `poi_sel` 是一批 POI 数据,其中有一个变量 `category`表示 POI 的类别,并且我们在当前工作目录的`icon/`文件夹下有一批与所有`category` 值一一对应的图标文件。那么下面的代码就可以生成一个调形盘。 ```R poi_category <- unique(poi_sel$category) poi_icon_labels <- map_chr(poi_title_map[poi_category], ~ strsplit(.x, "\\.")[[1]][2]) category_icon_path <- map_chr(poi_category, ~ file.path("icon", sprintf("%s.png", .x))) names(category_icon_path) <- poi_icon_labels poi_icons <- tmap_icons(category_icon_path, width = 48, height = 48) poi_icons ``` ```plaintext $iconUrl [1] "icon/公司企业.png" "icon/超级市场.png" "icon/综合市场.png" [4] "icon/商场.png" "icon/加油站.png" "icon/丧葬设施.png" [7] "icon/政府机关.png" "icon/会展中心.png" "icon/科研机构.png" [10] "icon/中餐厅.png" "icon/外国餐厅.png" "icon/快餐厅.png" [13] "icon/咖啡厅.png" "icon/运动场馆.png" "icon/小学.png" [16] "icon/中学.png" "icon/高等院校.png" "icon/停车场出入口.png" [19] "icon/地铁站.png" "icon/火车站.png" "icon/充电站.png" [22] "icon/公园广场.png" "icon/国家级景点.png" $iconWidth [1] 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 $iconHeight [1] 48 48 45 48 48 46 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 $iconAnchorX [1] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 $iconAnchorY [1] 24 24 22 24 24 23 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 $iconNames [1] "Company" "Supermarket" "Market" "ShoppingCenter" [5] "GasStation" "FuneralFacility" "Government" "ConventionCenter" [9] "Research" "ChineseFood" "ForeignFood" "FastFood" [13] "Café" "Gym" "PrimarySchool" "HighSchool" [17] "University" "ParkingEntrances" "Subway" "TrainStation" [21] "ChargingStation" "Park" "ScenicSpot" ``` 可以看到,在这个代码中,我们从所有类别中生成了一个 `category_icon_path` 列表,并且通过 `names()` 函数设置了键名。那么,生成的 `poi_icons` 中就会出现一个 `iconNames` 的变量。传入 `tmap_icons()` 的参数仅仅是一个不具名的向量,那么 `poi_icons` 中也就不会出现 `iconNames` 这个变量。这一点会影响后续使用。 # 使用形状 通常情况下,如果我们使用外部 PNG 图片文件作为要素符号,那么应该不需要对其进行颜色的设置,只需要设置大小即可。**tmap** 包提供了一个函数 `tm_markers()` 专门用来处理这种情况。使用这个函数绘制出来的符号没有边框,使用 `tm_symbols()` 也可以调用我们生成的调形盘绘制符号,但是会在外面加上一个边框,用来表示 `col` 参数设置的变量。 使用调形盘进行形状绘制的方法也很简单,例如(数据 `poi_sel_en` 中的 `category` 变量根据 `poi_sel` 转换过来的,值与 `poi_icons$iconNames` 对应): ```R base_map + tm_shape(poi_sel_en) + tm_markers(shape = "category", shapes = poi_icons, size = 2, title.shape = "Category", icon.scale = 0.2) + tm_layout( legend.outside = T, legend.outside.size = 0.2, legend.title.size = 2, legend.text.size = 1.4, ) + tm_compass(position = c("right", "top")) + tm_scale_bar(position = c("right", "bottom")) ``` 可以看到,我们通过 `shape` 参数制定了用于改变形状的列,然后将调形盘通过参数 `shapes` 传入。那么该函数就会在 `poi_icons` 中找到名称与 `category` 变量值对应的形状,并使用该形状进行符号绘制。绘制出来的图形如下。 ![data_poi_sel.png](/media/acd15635-17d3-49ce-a612-42aca11f10fb_data_poi_sel.png) 那么如果调形盘中不存在 `iconNames` 变量会怎么样呢?这时就要求我们传入 `shape` 的值或列是数值型的,函数会以该数值为索引找到形状,而不再是通过名称进行查找了。
感谢您的阅读。本网站 MyZone 对本文保留所有权利。