python编程之一:使用网格索引算法进行空间数据查询

        这是学习python以来第一次实现一个功能。是因为今天在网上面试一个兼职程序员,对方给我出一道题,题目如下:

        写个python的接口,给定经度和维度范围,查出在中国的区域,要求性能尽可能的快。全国经纬度表参见这个网页:http://t.cn/aWKhXM


        做这个题的时候大脑首先想到是两个算法,一个是网格索引,一个是四叉树索引。考虑到初次用python实现,个人感觉网格索引更容易实现一下,贴出以下代码,简单做了单元测试,还有问题忘指出。


    

#!/usr/bin/env python
#coding = utf-8
'''
Author: buffer
E-mail: 179770346@qq.com
desc:   此处使用网格索引算法查找,网格划分越细,查找效率越高,可能内存会越大,需要权衡.
        还可以使用四叉树算法来做空间索引,但是考虑四叉树可能稍微复杂,使用网格算法
'''

#空间对象
class GeoObject:
    def __init__(self, name, x, y):
        self.name = name
        self.x = x
        self.y = y

#网格索引查找类
class GeoSearch:
    def __init__(self):
        try:
            file = open("./data.txt", 'r')
        except IOError:
            print "Can't open the file!"
            
        #读取空间数据到内存中,并获取整个空间数据的外接矩形范围
        objArray = []
        dXMax = -999.0 #初始化一个无穷小的范围
        dXMin = 999.0
        dYMax = -999.0
        dYMin = 999.0
        
        file.readline();
        for cursor in file:
            info = []
            for str in cursor.split(" "):
                if str == "" or str == " ":
                    continue
                info.append(str)
            if len(info) < 3:
                #print info[0], info[1], info[2], info[3], len(info)
                continue
            mydXMax = mydXMin = float(info[1]) 
            mydYMax = mydYMin = float(info[2])
            objArray.append(GeoObject(info[0], mydXMax, mydYMax))
            if dXMax < mydXMax:
                dXMax = mydXMax
            if dXMin > mydXMin:
               dXMin = mydXMin
            if dYMax < mydYMax:
                dYMax = mydYMax
            if dYMin > mydYMin:
                dYMin = mydYMin
        print dXMax, dXMin, dYMax, dYMin
            
        #将整个空间范围划分等份的网格
        self.m_nGridCount = 32
        self.m_dOriginX = dXMin
        self.m_dOriginY = dYMin
        self.dSizeX = (dXMax - dXMin) / self.m_nGridCount
        self.dSizeY = (dYMax - dYMin) / self.m_nGridCount
        self.m_vIndexCells = []
        for i in range(0, self.m_nGridCount * self.m_nGridCount + 1):
            self.m_vIndexCells.append([])
        #self.m_vIndexCells = [list()] * (self.m_nGridCount * self.m_nGridCount)
        print self.m_nGridCount, self.m_dOriginX, self.m_dOriginY, \
              self.dSizeX, self.dSizeY, len(self.m_vIndexCells), len(objArray)

        #将每个对象注册到空间索引中
        for obj in objArray:
            nXCol = int((obj.x - self.m_dOriginX) / self.dSizeX)
            nYCol = int((obj.y - self.m_dOriginY) / self.dSizeY)
            if nXCol < 0:
                nXCol = 0
            if nXCol >= self.m_nGridCount:
                nXCol = self.m_nGridCount - 1
            if nYCol < 0:
                nYCol = 0
            if nYCol <= self.m_nGridCount:
                nYCol = self.m_nGridCount - 1
                
            iIndex = nXCol * self.m_nGridCount + nYCol
            self.m_vIndexCells[iIndex].append(obj)
            #print iIndex, len(self.m_vIndexCells[iIndex])
            
    def Search(self, dXMax, dXMin, dYMax, dYMin):
        #计算输入外接矩形所在网格的范围
        nXMin = int((dXMin - self.m_dOriginX) / self.dSizeX)
        nXMax = int((dXMax - self.m_dOriginX) / self.dSizeX + 0.5) #四舍五入
        nYMin = int((dYMin - self.m_dOriginY) / self.dSizeY)
        nYMax = int((dYMax - self.m_dOriginY) / self.dSizeY + 0.5)
        print nXMin, nXMax, nYMin, nYMax
        
        #遍历这些网格得到所有符合条件的设备
        for n in range(nYMin, nYMax):
            for m in range(nXMin, nXMax):
                iIndex = n * self.m_nGridCount + m
                for obj in self.m_vIndexCells[iIndex]:
                    if obj.x <= dXMax and obj.x >= dXMin and \
                       obj.y <= dYMax and obj.y >= dYMin:
                        print obj.name
        

if __name__ == '__main__':
    geoSearch = GeoSearch();
    geoSearch.Search(134.28, 99.25, 52.97, 34.25)
    

测试文件格式如下:

区县                          经度                          纬度                  
北京市                        116.4                         39.9 
天安门                        116.38                        39.9 
东城区                        116.42                        39.93
西城区                        116.37                        39.92
崇文区                        116.43                        39.88
宣武区                        116.35                        39.87
朝阳区                        116.43                        39.92
丰台区                        116.28                        39.85
石景山区                      116.22                        39.9 
海淀区                        116.3                         39.95
门头沟区                      116.1                         39.93
房山区                        116.13                        39.75
通州区                        116.65                        39.92
顺义区                        116.65                        40.13
昌平区                        116.23                        40.22
大兴区                        116.33                        39.73
怀柔区                        116.63                        40.32
平谷区                        117.12                        40.13
密云县                        116.83                        40.37
延庆县                        115.97                        40.45
天津市                        117.2                         39.12
和平区                        117.2                         39.12
河东区                        117.22                        39.12
河西区                        117.22                        39.12
南开区                        117.15                        39.13
河北区                        117.18                        39.15
红桥区                        117.15                        39.17
塘沽区                        117.65                        39.02
汉沽区                        117.8                         39.25
大港区                        117.45                        38.83
东丽区                        117.3                         39.08
西青区                        117.0                         39.13
津南区                        117.38                        38.98
北辰区                        117.13                        39.22
武清区                        117.03                        39.38
宝坻区                        117.3                         39.72
滨海新区                      117.68                        39.03
宁河县                        117.82                        39.33
静海县                        116.92                        38.93
蓟县                          117.4                         40.05
石家庄市                      114.52                        38.05
长安区                        114.52                        38.05
桥东区                        114.5                         38.05
桥东区                        114.9                         40.78
桥东区                        114.5                         37.07
桥西区                        114.47                        37.05
桥西区                        114.87                        40.83
桥西区                        114.47                        38.03
新华区                        114.47                        38.05
新华区                        116.87                        38.32
井陉矿区                      114.05                        38.08
裕华区                        114.52                        38.02
井陉县                        114.13                        38.03
正定县                        114.57                        38.15
栾城县                        114.65                        37.88
行唐县                        114.55                        38.43
灵寿县                        114.37                        38.3 
高邑县                        114.6                         37.6 
深泽县                        115.2                         38.18
赞皇县                        114.38                        37.67
无极县                        114.97                        38.18
平山县                        114.2                         38.25
元氏县                        114.52                        37.75
赵县                          114.77                        37.75
辛集市                        115.22                        37.92
藁城市                        114.83                        38.03
晋州市                        115.03                        38.03
新乐市                        114.68                        38.35
鹿泉市                        114.3                         38.08
唐山市                        118.2                         39.63
路南区                        118.17                        39.63
路北区                        118.22                        39.63
古冶区                        118.42                        39.73
开平区                        118.27                        39.68
丰南区                        118.1                         39.57
丰润区                        118.17                        39.83
滦县                          118.7                         39.75
滦南县                        118.68                        39.5 
乐亭县                        118.9                         39.42
迁西县                        118.32                        40.15
玉田县                        117.73                        39.88
唐海县                        118.45                        39.27
遵化市                        117.95                        40.18
迁安市                        118.7                         40.02
秦皇岛市                      119.6                         39.93
海港区                        119.6                         39.93
山海关区                      119.77                        40.0 
北戴河区                      119.48                        39.83
青龙满族自治县                118.95                        40.4 
昌黎县                        119.17                        39.7 
抚宁县                        119.23                        39.88
卢龙县                        118.87                        39.88
邯郸市                        114.48                        36.62
邯山区                        114.48                        36.6 
丛台区                        114.48                        36.63
复兴区                        114.45                        36.63
峰峰矿区                      114.2                         36.42
邯郸县                        114.53                        36.6 
临漳县                        114.62                        36.35
成安县                        114.68                        36.43
大名县                        115.15                        36.28
涉县                          113.67                        36.57
磁县                          114.37                        36.35
肥乡县                        114.8                         36.55
永年县                        114.48                        36.78
邱县                          115.17                        36.82
鸡泽县                        114.87                        36.92
广平县                        114.93                        36.48
馆陶县                        115.3                         36.53
魏县                          114.93                        36.37
曲周县                        114.95                        36.78
武安市                        114.2                         36.7 
邢台市                        114.48                        37.07
桥东区                        114.5                         38.05
桥东区                        114.9                         40.78
桥东区                        114.5                         37.07
桥西区                        114.87                        40.83
桥西区                        114.47                        38.03
桥西区                        114.47                        37.05
邢台县                        114.5                         37.08
临城县                        114.5                         37.43
内丘县                        114.52                        37.3 
柏乡县                        114.68                        37.5 
隆尧县                        114.77                        37.35
任县                          114.68                        37.13
南和县                        114.68                        37.0 
宁晋县                        114.92                        37.62
巨鹿县                        115.03                        37.22
新河县                        115.25                        37.53
广宗县                        115.15                        37.07
平乡县                        115.03                        37.07
威县                          115.25                        36.98
清河县                        115.67                        37.07
临西县                        115.5                         36.85
南宫市                        115.38                        37.35
沙河市                        114.5                         36.85
保定市                        115.47                        38.87
新市区                        115.45                        38.87
北市区                        115.48                        38.87
南市区                        115.5                         38.85
满城县                        115.32                        38.95
清苑县                        115.48                        38.77
涞水县                        115.72                        39.4 
阜平县                        114.18                        38.85
徐水县                        115.65                        39.02
定兴县                        115.77                        39.27
唐县                          114.98                        38.75
高阳县                        115.78                        38.68
容城县                        115.87                        39.05
涞源县                        114.68                        39.35
望都县                        115.15                        38.72
安新县                        115.93                        38.92
易县                          115.5                         39.35
曲阳县                        114.7                         38.62
蠡县                          115.57                        38.48
顺平县                        115.13                        38.83
博野县                        115.47                        38.45
雄县                          116.1                         38.98
涿州市                        115.97                        39.48
定州市                        114.97                        38.52
安国市                        115.32                        38.42
高碑店市                      115.85                        39.33
张家口市                      114.88                        40.82
桥东区                        114.5                         38.05
桥东区                        114.9                         40.78
桥东区                        114.5                         37.07
桥西区                        114.87                        40.83
桥西区                        114.47                        38.0

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值