风玫瑰图这一段时间我看到有人在求助如何使用 ArcGIS 添加风玫瑰图,还重复看到了好几次,然后我自己去试了试,发现使用 ArcGIS 确实不太好弄。 1.什么是风玫瑰图风玫瑰图(wind rose plot)用来简单描述某一地区风向风速的分布,可分为风向玫瑰图和风速玫瑰图。在风玫瑰图的极坐标系上,每一部分的长度表示该风向出现的频率,最长的部分表示该风向出现的频率最高。风玫瑰图通常分16个方向,也有的再细分为32个方向。 风玫瑰图可以直接替代指北针,所以有的人也叫玫瑰指北针,为什么名字里都有一个“玫瑰”呢?可能是形状像玫瑰花瓣吧。 2.添加方法ArcGIS 没有自带的风玫瑰图,并且 ArcGIS 不支持 svg 格式,支持一种叫 emf (好像叫这个)的远古狗屎格式,在我的测试下非常难用。 所以要如何才能把风玫瑰图添加到地图中呢? 有发现一些有趣的解决办法:直接把风玫瑰图拖进 arcmap 中(不能是 png 格式的),然后可以重分类,再配准到地图上。这个方法不错,大家可以尝试,不过这个很可能出现各种范围报错。 其实为什么非得要使用 ArcGIS 做呢?直接使用 PS 把风玫瑰图加上去就行了。 或者更快速更有效,直接使用 python 的 PIL 库也可以实现把风玫瑰图加到地图的指定位置,甚至可以批量添加。 使用Python添加风玫瑰图1.数据资料准备1.1制作完成的地图基本制作完成的地图或多张(不包含指北针,因为风玫瑰图就能替代指北针)。 1.2风玫瑰图准备已经制作好的风玫瑰图,最好使用 svg 格式,这个格式是一种广泛用于网络的矢量格式,是万维网的标准,也是制作各种图标的标准格式之一;或者使用 png 格式也可以,但要保证大小分辨率足够,不然最后添加到地图上会模糊。 符号来源:https://www./png-zuwuu1/ 2.添加风玫瑰图2.1导入 PIL 模块现在在 Python3 中安装 PIL 模块实际上是指 Pillow 模块,因为原来的 PIL 模块已经不更新了,而 Pillow 模块是对 PIL 的继承和发展。同时 Pillow 模块完全继承了 PIL 的所有语法和各种名词空间,包括导入方式。 from PIL import Image2.2获取图片尺寸获取地图的尺寸和风玫瑰图的尺寸。 # Get map size# map_x: map image X # map_x: map image Y map_path = "map.jpg" we_map = Image.open(map_path) map_x = we_map.size[0] # 宽 map_y = we_map.size[1] # 高 # 风玫瑰图与边框的距离 offset_x , offset_y = 420, 420 # ▶注释1◀ # Get windrose image size: # w_d_x: windrose image X # w_d_y: windrose image Y windrose_path = "wind-rose.png" windrose = Image.open(windrose_path) print(windrose.size) w_d_x = windrose.size[0] w_d_y = windrose.size[1] 获取的图片尺寸是一个 宽 高 组成的元组:(width, height)。 ▶注释1◀: ①这里的 offset_x 和 offset_y 指风玫瑰图(下图中的黑色矩形)到边框的距离,亮橙色箭头。 ②图像中的坐标系和一般的数学坐标系是不一样的,坐标原点在图像左上端点,Y 轴向下为正,X 轴向左为正。 2.3粘贴区将风玫瑰图粘贴到地图前,需要在地图上预先设置一个“粘贴区”,且尺寸大小需要和风玫瑰图大小保持一致。 x_topleft = map_x - offset_x - w_d_xy_topleft = offset_y x_bottomright = map_x - offset_x y_bottomright = offset_y + w_d_y box=(x_topleft, y_topleft, x_bottomright, y_bottomright) 这个 box 就是所谓的“粘贴区”,其中依次输入左上角x坐标、左上角y坐标、右下角x坐标、右下角y坐标。 2.4粘贴最后一步就是把风玫瑰图粘贴到地图上,然后 save 保存。 # 使用透明图层为掩膜裁剪出目标区域。clip_mask = windrose.convert('RGBA') we_map.paste(windrose, box, clip_mask) we_map.save("test.jpg") 需要注意的一点就是腌膜,腌膜可以帮助将 png 图片中的透明部分裁剪扔掉。 3.完整代码和成果# -*- coding:utf-8 -*-from PIL import Image # Get map size # map_x: map image X # map_x: map image Y map_path = "map.jpg" we_map = Image.open(map_path) map_x = we_map.size[0] map_y = we_map.size[1] # 风玫瑰图与边框的距离 offset_x , offset_y = 420, 420 # Get windrose image size: # w_d_x: windrose image X # w_d_y: windrose image Y windrose_path = "wind-rose.png" windrose = Image.open(windrose_path) print(windrose.size) w_d_x = windrose.size[0] w_d_y = windrose.size[1] x_topleft = map_x - offset_x - w_d_x y_topleft = offset_y x_bottomright = map_x - offset_x y_bottomright = offset_y + w_d_y box=(x_topleft, y_topleft, x_bottomright, y_bottomright) # 使用透明图层为掩膜裁剪出目标区域。 clip_mask = windrose.convert('RGBA') we_map.paste(windrose, box, clip_mask) we_map.save("test.jpg") # we_map.show() 最后代码量很少,这里只是展示一个思路,抛砖引玉,毕竟还有使用 PS 这种更加简单快速的方法。 |
|