大部分情况下,地理绘图可使用 Arcgis 等工具实现。但正版的 Arcgis 并非所有人可以承受。本文基于 Python 的 cartopy 和
matplotlib 等库,为地理空间绘图的代码实现提供参考。
所有所需库如下:
gma、cartopy、matplotlib、numpy
更多内容可转到:地理与气象分析库----使用指南(点击阅读原文)。
基于 Python 的地理空间绘图目标实现以下效果(包含比例尺、指北针、经纬网、图例等):


制图流程图
本例以 ESA 2020 陆表覆盖河南省地物分类数据为例,通过gma.rasp.AddColorTable 更新色彩映射表,形成三个与原始文件不同
的副本栅格(仅配色不同)。并对四个栅格进行绘制。这四个文件分别为:
“地表覆盖_河南_ESA_2020.tif” ----原始数据"地表覆盖_河南_ESA_2020 - 副本.tif" “地表覆盖_河南_ESA_2020 - 副本 (2).tif”
“地表覆盖_河南_ESA_2020 - 副本 (3).tif”
底图以我国省、地级市边界以及1-5级河流和湖泊为主。
python学习交流Q群:906715085###
import gma
# 1.根据定义更新——第一个副本
## 待更新的色彩映射表
ColorTable = {10:(0,112,255,255),
20:(255,211,127,255),
30:(76,230,0,255),
40:(123,104,238,255),
50:(230,230,0,255),
60:(205,245,122,255),
70:(156,200,121,255),
80:(245,162,122,255),
90:(190,210,255,255),
95:(109,150,178,255),
100:(223,198,142,255)}
## 将定义的色彩映射表更新到 副本
gma.rasp.AddColorTable("地表覆盖_河南_ESA_2020 - 副本.tif",
ColorTable = ColorTable)
# 2.根据模板栅格更新——第二个副本
## 将 副本 的色彩映射表更新到 副本(2)
gma.rasp.AddColorTable("地表覆盖_河南_ESA_2020 - 副本 (2).tif",
"地表覆盖_河南_ESA_2020 - 副本.tif")
# 3.根据模板栅格和定义更新——第三个副本
## 将 副本 以及定义的色彩映射表更新到 副本 (3)
gma.rasp.AddColorTable("地表覆盖_河南_ESA_2020 - 副本 (3).tif",
"地表覆盖_河南_ESA_2020 - 副本.tif",
ColorTable = {10:(100,100,100,255), 40:(200,200,200,255)})
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.colors as cor
import numpy as np
import gma.extend.mapplottools as mpt
PAR = {'font.sans-serif': 'Times New Roman',
'axes.unicode_minus': False,
}
plt.rcParams.update(PAR)
InFiles = ["地表覆盖_河南_ESA_2020.tif", "地表覆盖_河南_ESA_2020 - 副本.tif",
"地表覆盖_河南_ESA_2020 - 副本 (2).tif", "地表覆盖_河南_ESA_2020 - 副本 (3).tif"]
#### 读取四组数据色彩信息
CMap = []
Colors = []
for InFile in InFiles:
DataSet = gma.Open(InFile)
Color = DataSet.GetGDALDataset().GetRasterBand(1).GetColorTable()
ColorTable = [Color.GetColorEntry(i) for i in range(Color.GetCount())]
# 转换 色彩映射表 为 Matplotlib 可识别的格式
CMapV = tuple(tuple(np.array(CT) / 255) for CT in ColorTable)
# 生成色带
CMap.append(cor.ListedColormap(CMapV))
Colors.append([CMapV[i] for i in range(10, 110, 10)] + [CMapV[95]])
#### 为四组数据分配名称
Method = ['原始配色', '根据定义更新', '根据模板栅格更新', '根据模板栅格和定义更新']
#### 为颜色值定义含义
ColorName = ['林地', '灌木', '草地', '耕地', '建筑', '裸地/稀疏植被区', '雪和冰', '开阔水域',
'草本湿地', '红树林', '苔藓和地衣']
当数据过大时,直接绘制可能失败。若想精确绘制,可采用此方法(若涉及到投影,大数据耗时较久)。否则,可以缩放数据,
减小分辨率(类似栅格金字塔构建规则)进行绘制。
BlockSize = 8000
Columns = DataSet.Columns
Rows = DataSet.Rows
Blocks = [(r, c) for r in range(0, Rows, BlockSize) for c in range(0, Columns, BlockSize)]
GEOT = DataSet.GeoTransform
Columns = DataSet.Columns
Rows = DataSet.Rows
# 数据边界
ExtentData = [GEOT[0], GEOT[0] + GEOT[1] * Columns, GEOT[3] + GEOT[-1] * Rows, GEOT[3]]
# 绘图边界(以数据边界为基础确定)
EL, ER, EB, ET = 0.2, 0.1, 0.15, 0.05 # 左右、下上边界的扩展比例
ExtentPLT = [ExtentData[0] - (ExtentData[1] - ExtentData[0]) * EL,
ExtentData[1] + (ExtentData[1] - ExtentData[0]) * ER,
ExtentData[2] - (ExtentData[3] - ExtentData[2]) * EB,
ExtentData[3] + (ExtentData[3] - ExtentData[2]) * ET]
python学习交流Q群:906715085####
WKTCRS = DataSet.Projection
DataCRS = mpt.GetCRS(WKTCRS)
fig = plt.figure(figsize = (10, 10), dpi = 600)
# 定义一个标准中国区 ALBERS 投影
Alberts_China = ccrs.AlbersEqualArea(central_longitude = 105, standard_parallels = (25.0, 47.0))
for i in range(4):
ax = plt.subplot(2, 2, i + 1, projection = Alberts_China)
# 0.控制数据显示范围
ax.set_extent(ExtentPLT, crs = DataCRS)
# 1.绘制底图图层(应用自有高精度数据做底图)
## 1.1 添加行政边界
mpt.AddGeometries(ax, r"Region\VTD_PG_PLCity_China.shp", EdgeColor = 'LightGrey', LineWidth = 0.1)
mpt.AddGeometries(ax, r"Region\VTD_PG_Province_China.shp", EdgeColor = 'Gray', LineWidth = 0.2)
## 1.2 添加河流湖泊
mpt.AddGeometries(ax, r"river\1级河流.shp", EdgeColor = 'RoyalBlue', LineWidth = 0.4)
mpt.AddGeometries(ax, r"river\2级河流.shp", EdgeColor = 'DodgerBlue', LineWidth = 0.3)
mpt.AddGeometries(ax, r"river\3级河流.shp", EdgeColor = 'DeepSkyBlue', LineWidth = 0.2)
mpt.AddGeometries(ax, r"river\4级河流.shp", EdgeColor = 'SkyBlue', LineWidth = 0.15)
mpt.AddGeometries(ax, r"river\5级河流.shp", EdgeColor = 'LightSkyBlue', LineWidth = 0.05)
mpt.AddGeometries(ax, r"river\主要湖泊.shp", EdgeColor = 'none', LineWidth = 0, FaceColor = '#BEE8FF')
# 2.绘制数据图层
## 分块绘制(节约内存)
for Block in Blocks:
# 数据都一样,读取一个文件的数据即可
DrawData = DataSet.ToArray(*Block, BlockSize, BlockSize)
ExtentBlock = [GEOT[0] + Block[1] * GEOT[1], GEOT[0] + (DrawData.shape[1] + Block[1]) * GEOT[1],
GEOT[3] - (DrawData.shape[0] + Block[0]) * GEOT[1], GEOT[3] - Block[0] * GEOT[1]]
im = ax.imshow(DrawData, transform = DataCRS, cmap = CMap[i], extent = ExtentBlock, zorder = 2,
interpolation = 'none', vmin = 0, vmax = 255)
# 3.为绘制区域增加经纬网
gl = ax.gridlines(draw_labels = True, dms = False, x_inline = False, y_inline = False,
linestyle = (0, (10, 10)),
linewidth = 0.2,
color = 'Gray',
rotate_labels = False,
xlabel_style = {'fontsize': 8},
ylabel_style = {'fontsize': 8})
## 3.1忽略相邻轴的经纬网标签
if i % 2 == 0:
gl.right_labels = False
else:
gl.left_labels = False
if i < 2:
gl.bottom_labels = False
else:
gl.top_labels = False
ax.set_title(Method[i], fontsize = 10, y = 0.92, fontdict = {'family':'SimSun'})
# n.其他优化设置
## n.1 添加指北针
mpt.AddCompass(ax, LOC = (0.2, 0.85), SCA = 0.04, FontSize = 10)
## n.2 添加比例尺
mpt.AddScaleBar(ax, LOC = (0.8, 0.08), SCA = 0.1, FontSize = 6, PROJType = 'PROJCS', UnitPad = 0.25, BarWidth = 0.6)
## n.3 添加图例并修饰
mpt.AddLegend(ax, Colors[i], LegendName = '分类', LengedInterval = 0.4, LabelList = ColorName,
LegendSize = 8, TextInterval = 0.1, LOC = (0.05, 0.32), SCA = 0.03, AspectRatio = 1.5,
Columns = 2, ColumnWide = 0.15, RowInterval = 0.015, FontSize = 6, EdgeColor = 'k', EdgeWidth = 0.1)
plt.subplots_adjust(wspace = 0.05, hspace = -0.05)
plt.show()

还有没有学会的小伙伴嘛,点名批评不认真哟!关于今天的这一篇文章喜欢的记得点赞,让我看看是哪一位靓仔在支持我,不懂
的也记得评论留言,学习的事马虎不得。下一章见啦~
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决