|
楼主 |
发表于 2013-3-12 12:21
|
显示全部楼层
本帖最后由 lee1892 于 2013-3-12 12:46 编辑
接43楼的讨论。按43楼最后提到的改进方法,修改了代码,使用一个一维数组保存含有基站的网格,并用一个字典对象对其索引。
本贴附件:
地理信息的网格查找示例_改进网格数组 By Lee1892.rar
(159.77 KB, 下载次数: 307)
第二步的初始化网格数组就变成下面的一小段:
[code=vb] nMaxLatGrid = Int((Int(dblMaxLat) - Int(dblMinLat) + 1) / dGridStep) + 1
nMaxLonGrid = Int((Int(dblMaxLon) - Int(dblMinLon) + 1) / dGridStep) + 1
ReDim arrWithBaseGrids(1 To nCount)
Set dicWithBaseGrids = CreateObject("Scripting.Dictionary")
[/code]
而第三步的分配基站至网格就会改为如下:
[code=vb]
For i = 1 To nCount
With arrBases(i)
nLatGrid = Int((.Latitude - Int(dblMinLat)) / dGridStep) + 1
nLonGrid = Int((.Longitude - Int(dblMinLon)) / dGridStep) + 1
End With
sGridAddress = nLatGrid & "," & nLonGrid
If Not dicWithBaseGrids.Exists(sGridAddress) Then
nGridCount = nGridCount + 1
dicWithBaseGrids(sGridAddress) = nGridCount
With arrWithBaseGrids(nGridCount)
.BasesNum = 1
ReDim .BasesInd(1 To 1)
.BasesInd(1) = i
.LatAddress = nLatGrid
.LonAddress = nLonGrid
End With
Else
nGridInd = dicWithBaseGrids(sGridAddress)
With arrWithBaseGrids(nGridInd)
.BasesNum = .BasesNum + 1
ReDim Preserve .BasesInd(1 To .BasesNum)
.BasesInd(.BasesNum) = i
End With
End If
Next
ReDim Preserve arrWithBaseGrids(1 To nGridCount)
[/code]
如此一来,网格的步长就可以随意改小而不用担心造成内存不足的问题。
但这又带来另一个问题,如果将网格改的很小,会导致基站对于网格而言非常稀疏,从而使得在对工作站逐圈搜索时效率非常低。显然找到一个合适的网格步长应该是代码完成的工作。附件的代码采用了如下的方法,原因可自行思考分析:
[code=vb]
' 计算较合适的网格步长
dGridStep = (dblMaxLat - dblMinLat) / Sqr(nCount)
If (dblMaxLon - dblMinLon) / Sqr(nCount) < dGridStep Then
dGridStep = (dblMaxLon - dblMinLon) / Sqr(nCount)
End If
i = 0
Do Until Round(dGridStep, i) > 0
i = i + 1
Loop
dGridStep = Round(dGridStep, i)
'dGridStep = GRID_STEP
[/code]
后续的思考:如果希望使用较小的网格划分,但获得较快的执行速度该如何处理?应该是对逐圈搜索这一段代码进行优化,优化方法则应该根据基站分布的特点有针对性的改进。
|
|