目录
前言
一、任务
二、实现与解析
1.引入库
2.构造数据模型
3.渲染地图元素
4.执行查询 *** 作以及完成绘图
三、总结
前言
本书假定读者了解Pyhon、信息技术的基本知识,并且至少对地理空间分析有一定的认识。
讲述的是第1章 Python与地理空间分析“牛刀小试”部分的代码实现和解析。
一、任务
现在,你已经对地理空间分析有了进一步的了解,接下来我们要着手使用Python构建一个名
为SimpleGIS的GIS应用了。这个程序将使用地理数据模型构建一个完整的GIS应用,而且可以
渲染专题地图,显示不同城市的人口数量。
数据模型还将是结构化的,所以你可以进行一些基本的查询 *** 作。SimpleGIS将会包含科罗
拉多州的3个城市及其人口数量。
更重要的一点是,我们将完全使用Pytohn代码实现这个小型系统的构建,从而展示Python语
言的强大威力。当然我们还会用到Python标准库中的部分模块,但不会下载任何第三方应用包。
笔者使用Python版本是3.9,IDE为VScode,其他IDE可以参考这个:推荐10 款最好的 Python IDE | 菜鸟教程 (runoob.com)
二、实现与解析这一部分主要的解析都在注释中。
1.引入库唯一使用的外部库是turtle,初学者常用的画图库。
import turtle as t2.构造数据模型
首先声明一些和所有城市相关的常量。
# 在计算机科学中,将常用的数字放在方便记忆的变量中是普遍的做法。这个变量通常被称为常量。 # 妙处在于,索引也可以这样。 # 下面三个常量其实规定了列表中元素的先后顺序,即第一个是名称,第二个是点坐标(经纬度),第三个是人口数量。 NAME = 0 POINTS = 1 POP = 2 # 科罗拉多州,纬度在北纬37至41度之间,经度在西经102至109度之间,有5187582人。 state = ["COLORADO", [[-109, 37],[-109, 41],[-102, 41],[-102,37]], 5187582] # 城市 cities = [] cities.append(["DENVER",[-104.98, 39.74], 634265]) cities.append(["BOULDER",[-105.27, 40.02], 98889]) cities.append(["DURANGO",[-107.88,37.28], 17069])
然后定义地图尺寸大小和确定绘制边界,以及定义一个转换函数,用于将世界坐标(经纬度)转换成屏幕坐标。
# 地图大小 map_width = 400 map_height = 300 # 首先需要确定最大范围,即州的尺寸。 # 先假定一个范围。有趣的是,假定的最小值很大,最大值反而很小。 minx = 180 maxx = -180 miny = 90 maxy = -90 # 这个循环的妙处在于,即使要绘制的地图边界不是方方正正的,也可以确定边界值。 # 实际上确定了最小外接矩形(MBR)。 for x,y in state[POINTS]: if x < minx: minx = x elif x > maxx: maxx = x if y < miny: miny = y elif y > maxy: maxy = y # 第2步是计算州和绘图板之间的缩放比例.这个比例是用来将经纬度坐标转化成屏幕坐标的。 # 我们获取州在x和y坐标上的尺寸,然后和地图的尺寸进行比较得到缩放比例: dist_x = maxx - minx dist_y = maxy - miny x_ratio = map_width / dist_x y_ratio = map_height / dist_y # 转换函数 def convert(point): # lon:经度 lat:维度 lon = point[0] lat = point[1] x = map_width - ((maxx - lon) * x_ratio) y = map_height - ((maxy - lat) * y_ratio) # turtle图形引擎是以屏幕中心为起点位置的,因此必须把坐标点的位置进行适当的偏移 x = x - (map_width/2) y = y - (map_height/2) return [x,y]
详细的说明如图:
对convert函数的说明
3.渲染地图元素首先画边界。
# 开始画图 t.up() # 这里单独为第一个位置设变量,是为了画出封闭图形,而不需要在坐标列表增加一个点。 first_pixel = None for point in state[POINTS]: pixel = convert(point) if not first_pixel: first_pixel = pixel t.goto(pixel) t.down() t.goto(first_pixel) t.up() t.goto([0,0]) t.write(state[NAME], align="center", font=("Arial",16,"bold"))
然后绘制城市,注意这里使用convert函数的方法和上面不同的,显示了作者定义函数时的精巧构思。
# 绘制城市 for city in cities: pixel = convert(city[POINTS]) t.up() t.goto(pixel) # 绘制城市位置 t.dot(10) # 标记城市 t.write(city[NAME] + ", Pop.: " + str(city[POP]), align="left") t.up()
效果图
4.执行查询 *** 作以及完成绘图# 执行一个属性查询 *** 作来确定人口最多的城市 biggest_city = max(cities, key=lambda city:city[POP]) t.goto(0,-200) t.write("The biggest city is: " + biggest_city[NAME]) # 执行一个属性查询 *** 作来确定最西边的城市 western_city = min(cities, key=lambda city:city[POINTS]) t.goto(0,-220) t.write("The western-most city is: " + western_city[NAME]) # 关闭画笔 t.pen(shown=False) # 使用t.done()可以保存窗体 t.done()
效果图
三、总结
本文简单介绍了“牛刀小试”部分的代码实现,其实数学原理也很简单,不需要高等数学就可以推导其中的坐标转换公式,可以自己动手画图、结合图形加深理解。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)