一、背景
该章节是在学习《python地理空间分析指南》时所做的小实验。目标功能包括:
(1)构建简单的GIS应用
(2)渲染专题地图
(3)简单查询及现实功能
实验是在 anoconda(python 3.6版)+ pycharm + win10的环境下进行的。
二、模型构建
模型的构建大致分为两个部分,第一是数据模型部分,第二是地图数据渲染部分。
1.数据模型部分的实现
数据模型部分主要利用python的List实现,它能以特定的顺序作为存储对象的容器。这部分的python代码为:
# 导入需要的第三方库
import turtle as t
# 声明和城市相关的常量,数字表示其在list中的位置
NAME = 0 # 城市名字
POINTS = 1 # 城市坐标
POP = 2 # 城市人口
# 为科罗拉多州创建一个列表
state = ["COLORADO", [[-109, 37], [-109, 41], [-102, 41], [-102, 37]], 5187582]
# 将每个城市信息嵌套进空的列表cities中
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])
# 定义GIS底图尺寸
map_width = 400
map_height = 300
# 设定地图的全局边框并将其尺寸限制在州一级
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
x_ratio = map_width / dist_x
y_ratio = map_height / dist_y
# 使用之前的缩放比例将经纬度坐标转换成屏幕坐标。
def convert(point):
lon = point[0]
lat = point[1]
x = map_width - ((maxx - lon) * x_ratio)
y = map_height - ((maxy - lat) * y_ratio)
# 绘图板是以屏幕中心为原点的,因此需要把坐标点的位置进行适当平移
x = x - (map_width) / 2
y = y - (map_height) / 2
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"))
# 调试代码时使用
t.done() # 用于显示当前构建的GIS效果,之后可注释掉
第一部分完成之后的效果为:
这样便完成了一个非常简单的科罗拉多州的地图制作过程。
2. 地图渲染过程
渲染城市的名称,位置,人口等信息将使用turtle引擎。turtle的主要用途是可视化编程模块,且支持负的屏幕坐标系统,这对于地图渲染有着非常好的支持。渲染过程的python代码如下:
# 绘制所有的城市信息
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") # 使用str()将人口转化为字符串
t.up()
# 显示人口最多的城市
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()
最终的效果图为:
三、分析
1. 后期还可以对其进行改进优化,例如创建位置总览图,为地图配色,添加地图标题等
2. 程序的完整代码为:
import turtle as t
NAME = 0
POINTS = 1
POP = 2
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
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
x_ratio = map_width / dist_x
y_ratio = map_height / dist_y
def convert(point):
lon = point[0]
lat = point[1]
x = map_width - ((maxx - lon) * x_ratio)
y = map_height - ((maxy - lat) * y_ratio)
x = x - (map_width) / 2
y = y - (map_height) / 2
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"))
# t.done()
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()
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()