地理信息系统工具

d9t.gis的Python项目详细描述


简介

这个包的目的是让你接近一个现成的可用区域搜索 对于现有的“地址”在一个给定的距离从起点。

这是为德国开发的,任何地方都有邮政编码。我们想要 具有搜索功能以查找“接近”的对象(即 一段规定的距离)。

你也可以使用任何其他的关键点来协调 努力。唯一的要求是密钥是唯一的。

为此,邮政编码是我们最好的解决方案。我们有免费的名单 德国邮政编码和相应的地理信息系统信息(见数据目录)。 此列表来自opengeodb项目,并被授权为公共域: http://sourceforge.net/projects/opengeodb/

样板

首先,我们加载所需的zcml,因为这是一个单元测试。
>>> from Products.Five.zcml import load_config, load_string
>>> import d9t.gis
>>> import Products.Five
>>> import five.localsitemanager
>>> load_config('configure.zcml', package=Products.Five)
>>> load_config('configure.zcml', package=five.localsitemanager)
>>> load_config('configure.zcml', package=d9t.gis)

用法

可测量对象

一个可测量的物体必须提供像坐标,也可以是 由适配器提供。

让我们定义一个通用地址类(我知道,它是极简的和不完整的)。

>>> from zope.interface import implements, Interface
>>> from zope.component import queryUtility, adapts
>>> from d9t.gis.interfaces import ICoordinate, ICoordinateProvider
>>> class Address(object):
...     implements(ICoordinate)
...
...     def __init__(self, country, zip):
...         zip_coordinate_provider = queryUtility(ICoordinateProvider)
...         coordinate = zip_coordinate_provider.coordinate(country, zip)
...         self.latitude = coordinate.latitude
...         self.longitude = coordinate.longitude

现在让我们生成几个地址。

>>> a1 = Address("DE", "89073")
>>> a2 = Address("DE", "88299")

也可以创建简单的坐标。包括演示坐标类:

>>> from d9t.gis.coordinate import Coordinate
>>> c1 = Coordinate(9.99968113200213, 48.4052825255534)   # DE 89073
>>> c2 = Coordinate(10.0191253966503, 47.8117109627977)   # DE 88299

需要注意的是,zipcoordinateprovider在zope启动时从csv加载gis数据。 这需要的时间远远少于一秒钟,我们决定将数据存储在 佐德不会有任何优势。

计算距离

>>> from d9t.gis.interfaces import IDistanceCalculation
>>> distance_util = queryUtility(IDistanceCalculation)

您可以测量任何提供图标坐标的对象之间的距离。所以: 坐标之间

>>> distance_util.distance(c1, c2)
65.033485081783098

地址之间

>>> distance_util.distance(a1, a2)
65.033485081783098

在坐标和地址之间

>>> distance_util.distance(a1, c2)
65.033485081783098
>>> distance_util.distance(a1, c1)
0.0

常见用法

可能你已经有了一些地址对象 地理信息系统信息。也许你想-这确实是个好主意- 防止你的地址对象知道地理信息系统的信息。

您可以通过为 你的物品。

假设我们有一个已经不存在任何GIS信息的类:

>>> class IMyAddress(Interface):
...     """ """
>>> class MyAddress(object):
...     implements(IMyAddress)
...     address = ""
...     zip_code = ""
...     city = ""
...     country = ""
...     def __init__(self, address, zip_code, city, country):
...         self.address, self.zip_code, self.city, self.country = address, zip_code, city, country

然后您将拥有该类型的对象:

>>> my_a1 = MyAddress("Ilextwiete 12", "22455", "Hamburg", "DE")
>>> my_a2 = MyAddress("Gangweg 2", "80797", "Muenchen", "DE")

为了测量距离,你的物体必须提供坐标。所以让我们 创建一个适配器,它只需使用一个随时可用的实用程序来获取坐标。

>>> class MyAddressCoordinate(object):
...     implements(ICoordinate)
...     adapts(IMyAddress)
...
...     def __init__(self, my_address):
...         self.my_address = my_address
...         zip_coordinate_provider = queryUtility(ICoordinateProvider)
...         coordinate = zip_coordinate_provider.coordinate(self.my_address.country, self.my_address.zip_code)
...         self.latitude = coordinate.latitude
...         self.longitude = coordinate.longitude

您通常会在zcml中提供适配器,但由于这是一个测试用例, 我们在这里做:

>>> from zope.app.testing import ztapi
>>> ztapi.provideAdapter(IMyAddress, ICoordinate, MyAddressCoordinate)

然后您可以像往常一样测量:

>>> distance_util.distance(my_a1, my_a2)
624.79554959923701

就近到达

如果你想知道几个地址中哪一个最接近给定的地址,只需 为实用程序提供一个已知图标坐标的列表和一个要查找的列表。你会回来的 元组列表,其中[0]是距离,[1]是原始对象。 顺便说一句:正如你所看到的,任何可适应的对象都是可以的,并按原样返回。

让我们从这个列表中测量离muenchen(my_a2)最近的3是什么:

>>> nearest = distance_util.nearest(my_a2, (my_a1, my_a2, c1, c2, a1, a2))
>>> ["%s (%s)" % (n[0], n[1].__class__) for n in nearest]
["0.0 (<class 'MyAddress'>)", "175.137634687 (<class 'Address'>)", "175.137634687 (<class 'd9t.gis.coordinate.Coordinate'>)", "175.24792832 (<class 'Address'>)", "175.24792832 (<class 'd9t.gis.coordinate.Coordinate'>)", "624.795549599 (<class 'MyAddress'>)"]

您还可以将搜索限制为3个结果(当然是排序的):

>>> nearest = distance_util.nearest(my_a2, (my_a1, my_a2, c1, c2, a1, a2), 3)
>>> ["%s (%s)" % (n[0], n[1].__class__) for n in nearest]
["0.0 (<class 'MyAddress'>)", "175.137634687 (<class 'Address'>)", "175.137634687 (<class 'd9t.gis.coordinate.Coordinate'>)"]

靠近拉链

如果你需要在给定的坐标周围一定距离内的所有拉链,你可以 找到有用的inearbysips实用程序。

>>> from zope.component import getUtility
>>> from d9t.gis.interfaces import INearbyZips, IDistanceCalculation
>>> nbz = getUtility(INearbyZips)
>>> distance_util = getUtility(IDistanceCalculation, name="km")
>>> nbz.nearbyZips(c1, distance_util.toRadiant(10))
set([('DE', '89077'), ('DE', '89231'), ('DE', '89075'), ('DE', '89073')])

这是10公里。 注意!这只适用于远离辐射的边界。远离+180度! 这是由于速度优化。抱歉;)

高级

附近有门户网站目录

使用portal_catalog时,只会得到无法使用的大脑 要适应的接口。那么,请不要获取object()任何内容。是一个 浪费。

相反,为大脑创建一个这样的装饰器:

>>> class MyAddressBrainCoordinateDecorator(object):
...     implements(ICoordinate)
...     def __init__(self, brain):
...         self.brain = brain
...         zip_coordinate_provider = queryUtility(ICoordinationProvider)
...         coordinate = zip_coordinate_provider.coordinate(brain.getCountry, brain.getZip)
...         self.latitude = coordinate.latitude
...         self.longitude = coordinate.longitude

然后在用它们进行最近的搜索之前装饰你的大脑并把它们找回来 搜索后:

>>> brains = []
>>> decorated_brains = [MyAddressBrainCoordinateDecorator(brain) for brain in brains]
>>> nearest = distance_util.nearest(my_a2, decorated_brains, 5)
>>> brains = [decorated_brain.brain for decorated_brain in decorated_brains]

也一样糟糕的是,这样一来门户目录搜索的惰性就消失了。但是 一个小于100的结果集并不重要。如果你的套装是 足够大的性能影响,任何想法都是受欢迎的。

玩得开心;)

变更日志

d9t.gis-0.4[20120525]

  • Fixed a bug where a rounding error (caused by float) crashed with ValueError: math domain error when the lookup-coordinate were identical to one in the list, i.e. when the distance should have been 0.

d9t.gis-0.3[20081217]

  • Added nearby Zips utility (FAST, no. DAMN FAST!) [Daniel Kraft, Oliver Roch]
  • Added named distance utility for miles and km [Daniel Kraft, Oliver Roch]
  • Made zip database pluggable. You may now code your sql implementation. [Daniel Kraft, Oliver Roch]

d9t.gis-0.2

  • Fully functional and complete doctest available. [Daniel Kraft]

d9t.gis-0.1未发布

  • Initial package structure. [zopeskel]

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
异常如何在java中优雅地处理FileNotFoundexception   java线程卡在BlockingQueue上。无缘无故   类网格程序w/java   StrutsJava:动态应用Velocity脚本   java在运行时重写/禁用方面   java Apache POI无法正确读取Excel单元格中的秒数   具有不同用户权限的Java文件夹/文件创建   java我可以检查Firebase ValueEventListener onDataChanged是否已被调用吗?   尽管获得了用户权限,java Android开发文件权限仍被拒绝   java如何使用JPA映射map<EnumType,Double>?   java是否使用UI线程显示toast消息?   JAVAlang.IllegalArgumentException:不支持的元素:rss   java Android setRequestedOrientation活动和视图生命周期   安卓如何在Java中定义支票盒?   在Java中,对于大输入,字符串解析长期失败   使Java在XP中按计划任务运行读取env用户变量时出现问题   任务“:workflowsjava:NodeDriver”的梯度执行失败。main()   java如何检测是否只设置了部分属性?   在客户端web服务上使用JBossWS时,java无法找到/更改log4j的默认配置   java LibGDX写入文本文件并接收各种错误