使用Python构建一个小的GIS系统

最近在学习python地理空间分析,这里完全使用Python构建一个小型的GIS应用,包含的功能:渲染专题地图,显示不同城市的人口数量;基于结构化的数据模型,进行基本的属性查询操作。这个示例完全使用python及标准库实现,有助于初学者了解Python的强大威力。

构建SimpleGIS

具体的代码主要分为两个部分。第一部分是数据模型部分,第二部分是简陋的地图数据渲染和属性查询部分。

第一部分:使用Python中的列表List进行数据组织,它的优势在于可以映射更复杂的数据结构。

# 完全使用python构建一个小型GIS系统
import turtle as t
t.pen(shown=False) # 隐藏画笔光标
firstItem = 0   
NAME = 0
POINTS = 1
POP = 2    
state = ["COLORADO",[[-109,37],[-109,41],[-102,41],[-102,37]],5187582]
cities = []
cities.append(['ZZ',[-104.98,39.74],634265])
cities.append(['LY',[-105.27,40.02],98889])
cities.append(['KF',[-107.88,37.28],17069])

 第二部分:使用python的turtle渲染地图。在GIS系统中最重要的功能实现就是世界坐标系及其转换函数,作用就在于将真实的经纬坐标转为屏幕坐标格式。我们知道大多说的图形引擎都会以屏幕的左上角或右下角作为坐标原点。然而turtle却是以屏幕坐标中心点作为坐标原点,也就是说它可以支持负的屏幕坐标系统,这是很少见的。大家可以体会下它与别的图形引擎在坐标转换上的异同。

# 指定GIS地图屏幕显示尺寸
map_width = 600;map_height = 500
# 这里对书中代码做了修改,个人感觉这样代码可读性会更强一些
def convert(point):
	minx = 180
	maxx = -180
	miny = 90
	maxy = -90
	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
	dist_x = maxx - minx
	dist_y = maxy - miny
	# 以(maxx,maxy)为基点计算实际长度与屏幕长度的缩放比例
	x_radio = map_width / dist_x
	y_radio = map_height / dist_y
	lon = point[0]
	lat = point[1]
	# 实际坐标转为像素坐标
	# 因为turtle以屏幕中点做原点,(maxx,maxy)对应(map_width/2,map_height/2)
	x = map_width/2 - ((maxx - lon)*x_radio)
	y = map_height/2 - ((maxy - lat)*y_radio)
	return [x,y]
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"))
# 绘制城市
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 = "center")
	t.up()
# GIS应用的核心——属性查询
# 1 人口最多城市
biggest_city = max(cities,key=lambda city:city[POP])
t.goto(0,300)
t.write("The biggest city id :" + biggest_city[NAME])
# 2 距离西部最远城市
western_city = max(cities,key=lambda city:city[POINTS])
t.goto(0,275)
t.write("The western-most city is:"+ western_city[NAME])

t.done()

代码运行结果:

 总结

当然这个示例代码只是很简单的一个GIS应用系统,但是“山以凌尺故能高”,有兴趣的小伙伴可以一起讨论在此基础上进行扩展完善哦!


版权声明:本文为Smallnoob709原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。