PyQt 定制静态地图应用

                                             定制静态地图应用

 

下面我们在NetBeans的Python IDE中新建一个Python工程,点击创建工程,出现的界面如图33-9所示。

 
(点击查看大图)图33-9  新建Python工程

输入工程的名称为staticmap,Python IDE会为我们创建名为staticmap.py的代码文件,并将其设定为主文件,如图33-10所示。

 
(点击查看大图)图33-10  设定工程名称和存储位置

下面为生成的主文件staticmap.py添加相应的代码,首先在程序的开始加载所需的模块,引用部分代码段如下:

from PyQt4.QtCore import * 
from PyQt4.QtGui import *
import urllib

引入QtCore和QtGui所包含的类,PyQt4的基本模块都包含在QtGui中。由于静态地图的请求还须要对URL地址进行解析,所以再引入urllib类库处理HTTP相关的部分。

主程序部分也不复杂,其代码如下:

def main(): 
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())

对于PyQt4程序来说,要创建一个application对象。application类位于QtGui模块中,程序的主体就是这个QApplication,sys.argv用于传入命令行参数。

MyWindow是用于定义窗体的类,w.show()的作用是将定义的窗体显示出来。最后,主程序会进入application的事件循环。循环不断从窗口接受要处理的事件,然后将其分发给对应的事件处理方法。

事件循环的终止须要通过调用exit()方法或销毁widget来结束,调用sys.exit()方法可以确保程序正确退出,并且在退出时会告知系统。由于exec是python的一个关键字,所以在exec_()方法后会有一个下划线来表示与关键字的区别。

在MyWindow 类中,我们指定QDialog是刚才在Qt设计器中通过UI文件生成的Ui_Dialog(须要与UI设计器中指定的名称保持一致),其代码如下:

class MyWindow(QDialog): 
def __init__(self, *args):
QDialog.__init__(self, *args)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
# create connection
self.connect(self.ui.pushButton, SIGNAL("clicked()"), self.run_command)

__init__内的代码段定制界面的外观,我们引用了Qt设计器中通过UI文件编译生成的Ui_Dialog。当然,如果不是很复杂的界面,完全可以在函数中通过手工编写来加入窗体中要显示的文本框、按钮等部件。

在这里,我们通过信号槽的机制将确认按钮与接下来执行命令的操作run_command进行连接,也就是说,当按钮被点击时,触发的事件交由run_command函数进行处理。
run_command函数的代码段如下:

def run_command(self):
addr = str(self.ui.le.text().toUtf8())
self.getGeoCode(addr)

在函数中取得从输入栏获取的地址作为查询条件传递给getGeoCode函数,QLineEdit.text()回传的QString字符串与Python字串不同,可以转成Unicode字串后再赋值给字符串变量。

getGeoCode函数取得坐标的代码段如下:

def getGeoCode(self, addr):
geo_url='http://maps.google.com/maps/geo?'+urllib.urlencode
({'q':addr})+'&output=csv&key='+google_key
try:
g=urllib.urlopen(geo_url)
ret=g.read().split(',')          
if(ret[0]!='200'):
       QMessageBox.warning(None, "Error", addr+" not found", QMessageBox.Yes)
else:
       self.showMap(ret[2], ret[3])  
except urllib.HTTPError:
QMessageBox.warning(None, "Error", "Http error", QMessageBox.Yes)

在静态地图请求中,输入项为请求地址的地名,须要通过Google提供的地址译码功能将地名对应的位置转换为经纬度,所以,我们使用的URL字串为"http://maps.google.com/ maps/geo?"后面带的参数是查询的地址,output是输出的格式。目前的输出格式支持xml、kml、csv、Json,在这里使用的是以逗号分隔的csv格式,后面再添加之前申请的Google Maps API Key就可以得到解析后的地址坐标。

在urllib库的支持下,我们得到请求位置的地址坐标。如果没有找到地址对应的坐标,则使用QMessageBox来弹出一个消息以提示用户。如果找到地址对应的坐标,就将经纬度坐标作为参数传递给函数showMap来显示对应的地图。

函数showMap的代码段如下:

def showMap(self, lat,lang): 
stmap_url='http://maps.google.com/staticmap?center=
'+lat+','+lang+'&markers='+lat+','+lang+',red&zoom=
14&size=512x512&maptype=mobile&key='+google_key
urllib.urlretrieve(stmap_url, "stmap.gif")
image = QImage("stmap.gif")
self.ui.imageLabel.setPixmap(QPixmap.fromImage(image))
self.ui.imageLabel.adjustSize()

正确取得坐标后,我们将纬度(lat)和经度(lang)传递给showMap函数,以组装请求静态地图的字符串。在这里定义的缩放等级为14。在Google Maps中缩放的范围是0~18,0级即为整个地球,18级为最精细的地图。但除了美国、加拿大等国,往往无法获得最精细的地图。

取回的地图大小设置为512像素×512像素,同时512像素×512像素也是可以获取的最大图片。MapType种类设置为mobile,比较适合在便携式设备上查看, 此外还可以在地图上放置自定义的图标。本例采用在图片中心显示默认图标。

得到的静态地图使用urllib.urlretrieve()函数保存为名为stmap.gif的图片,然后将图片填充到imageLabel所对应的显示标签之中。这样,取得的地图就可以显示在程序对应的视窗上了。

下面我们在NetBeans中点击运行(F6)来启动应用,在弹出的对话框中输入Los Angeles的简称"LA",点击确定之后,就可以在程序中获取Google静态地图返回的地图,如图33-11所示。

 
(点击查看大图)图33-11  在程序中调用Google的静态地图

应用程序的完整代码如下:

import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import urllib
from ui_staticmap import Ui_Dialog
google_key='YOU_API_KEY_HERE'
def main(): 
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())

class MyWindow(QDialog):
def __init__(self, *args):
QDialog.__init__(self, *args)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
# create connection
self.connect(self.ui.pushButton, SIGNAL("clicked()"), self.run_command)
def getGeoCode(self, addr):
geo_url='http://maps.google.com/maps/geo?'+urllib.urlencode
({'q':addr})+'&output=csv&key='+google_key
try:
g=urllib.urlopen(geo_url)
ret=g.read().split(',')          
if(ret[0]!='200'):
QMessageBox.warning(None, "Error",
addr+" not found", QMessageBox.Yes)
else:
self.showMap(ret[2], ret[3])  
except urllib.HTTPError:
QMessageBox.warning(None, "Error",
"Http error", QMessageBox.Yes)
def showMap(self, lat,lang): 
stmap_url='http://maps.google.com/staticmap?center='+lat+','
+lang+'&markers='+lat+','+lang+',red&zoom=14&size=
512x512&maptype=mobile&key='+google_key
urllib.urlretrieve(stmap_url, "stmap.gif")
image = QImage("stmap.gif")
self.ui.imageLabel.setPixmap(QPixmap.fromImage(image))
self.ui.imageLabel.adjustSize()
    def run_command(self):
addr = str(self.ui.le.text().toUtf8())
self.getGeoCode(addr)

if __name__ == "__main__":
main()

至此,Google静态地图功能只发挥了一小部分,感兴趣的朋友还可以对程序进一步拓展,为应用加上地图缩放等级的调整、手动位置的调整,甚至可以加入在静态地图上进行路径设置等功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值