在 Django 中使用 GeoPy 和 ImportExport 进行地理编码
Geocoding with GeoPy and ImportExport in Django
我正在通过 ImportExport plugin, and at the point of saving this the model runs a geocoding process with GeoPy.
将地址的 .CSV 文件中的数据集导入到 Django 中的模型中
90% 的时间都有效,但有一些条目出现以下错误:
...
in save
_, latlon = geocoder.geocode(address)
TypeError: cannot unpack non-iterable NoneType object
我猜地理编码没有找到地址,但我不确定为什么它不只是将该字段留空。我在 Django 文档、GeoPy 文档和 google 地图地理编码文档中查找了相关部分,但似乎没有找到任何关于如何修复它的提示。
下面是更完整的回溯错误输出:
Traceback (most recent call last):
File "C:\Users\henry\webvenv\aavenv\lib\site-packages\import_export\resources.py", line 522, in import_row
self.save_instance(instance, using_transactions, dry_run)
File "C:\Users\henry\webvenv\aavenv\lib\site-packages\import_export\resources.py", line 315, in save_instance
instance.save()
File "C:\Users\henry\webvenv\project\architects\models.py", line 51, in save
_, latlon = geocoder.geocode(address)
TypeError: cannot unpack non-iterable NoneType object
下面是 app/model.py,它由 .CSV 文件和 运行 地理编码过程填充:
from django.conf import settings
from urllib.request import URLError
from django.contrib.gis.db import models
from django.contrib.gis import geos
import geopy.geocoders
from geopy.geocoders import GoogleV3
class Architect(models.Model):
id = models.CharField(max_length=100, primary_key=True)
sname = models.CharField(max_length=100)
fname = models.CharField(max_length=100)
a1 = models.CharField(max_length=100)
a2 = models.CharField(max_length=100)
a3 = models.CharField(max_length=100)
a4 = models.CharField(max_length=100)
a5 = models.CharField(max_length=100)
a6 = models.CharField(max_length=100)
pcode = models.CharField(max_length=100)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
location = models.PointField(u"longitude/latitude", blank=True, null=True)
objects = models.Manager()
#Original def:
# def __str__(self):
# return self.id
def __unicode__(self):
return self.id
def save(self, **kwargs):
if not self.location:
address = u'%s %s %s %s %s %s' % (self.a2, self.a3, self.a4, self.a5, self.a6, self.pcode)
address = address.encode('utf-8')
geocoder = GoogleV3(api_key='my API key')
try:
_, latlon = geocoder.geocode(address)
except (URLError, ValueError):
pass
else:
point = "POINT(%s %s)" % (latlon[1], latlon[0])
self.location = geos.fromstr(point)
super(Architect, self).save()
我现在似乎已经解决了我的问题
我的解决方案涉及将 'TypeError' 添加到异常中。
我还添加了 10 秒的超时来帮助解决出现会话超时错误的地理编码,据我所知,GeoPy 的默认超时是 1 秒。
如果有更简洁或更有效的方式来编写此代码,我将不胜感激。
...
def save(self, **kwargs):
if not self.location:
address = u'%s %s %s %s %s %s' % (self.a2, self.a3, self.a4, self.a5, self.a6, self.pcode)
address = address.encode('utf-8')
geocoder = GoogleV3(api_key='My API Key')
try:
_, latlon = geocoder.geocode(address, timeout=10)
except (URLError, ValueError, TypeError):
pass
else:
point = "POINT(%s %s)" % (latlon[1], latlon[0])
self.location = geos.fromstr(point)
super(Architect, self).save()
我正在通过 ImportExport plugin, and at the point of saving this the model runs a geocoding process with GeoPy.
将地址的 .CSV 文件中的数据集导入到 Django 中的模型中90% 的时间都有效,但有一些条目出现以下错误:
... in save _, latlon = geocoder.geocode(address) TypeError: cannot unpack non-iterable NoneType object
我猜地理编码没有找到地址,但我不确定为什么它不只是将该字段留空。我在 Django 文档、GeoPy 文档和 google 地图地理编码文档中查找了相关部分,但似乎没有找到任何关于如何修复它的提示。
下面是更完整的回溯错误输出:
Traceback (most recent call last):
File "C:\Users\henry\webvenv\aavenv\lib\site-packages\import_export\resources.py", line 522, in import_row
self.save_instance(instance, using_transactions, dry_run)
File "C:\Users\henry\webvenv\aavenv\lib\site-packages\import_export\resources.py", line 315, in save_instance
instance.save()
File "C:\Users\henry\webvenv\project\architects\models.py", line 51, in save
_, latlon = geocoder.geocode(address)
TypeError: cannot unpack non-iterable NoneType object
下面是 app/model.py,它由 .CSV 文件和 运行 地理编码过程填充:
from django.conf import settings
from urllib.request import URLError
from django.contrib.gis.db import models
from django.contrib.gis import geos
import geopy.geocoders
from geopy.geocoders import GoogleV3
class Architect(models.Model):
id = models.CharField(max_length=100, primary_key=True)
sname = models.CharField(max_length=100)
fname = models.CharField(max_length=100)
a1 = models.CharField(max_length=100)
a2 = models.CharField(max_length=100)
a3 = models.CharField(max_length=100)
a4 = models.CharField(max_length=100)
a5 = models.CharField(max_length=100)
a6 = models.CharField(max_length=100)
pcode = models.CharField(max_length=100)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
location = models.PointField(u"longitude/latitude", blank=True, null=True)
objects = models.Manager()
#Original def:
# def __str__(self):
# return self.id
def __unicode__(self):
return self.id
def save(self, **kwargs):
if not self.location:
address = u'%s %s %s %s %s %s' % (self.a2, self.a3, self.a4, self.a5, self.a6, self.pcode)
address = address.encode('utf-8')
geocoder = GoogleV3(api_key='my API key')
try:
_, latlon = geocoder.geocode(address)
except (URLError, ValueError):
pass
else:
point = "POINT(%s %s)" % (latlon[1], latlon[0])
self.location = geos.fromstr(point)
super(Architect, self).save()
我现在似乎已经解决了我的问题
我的解决方案涉及将 'TypeError' 添加到异常中。
我还添加了 10 秒的超时来帮助解决出现会话超时错误的地理编码,据我所知,GeoPy 的默认超时是 1 秒。
如果有更简洁或更有效的方式来编写此代码,我将不胜感激。
...
def save(self, **kwargs):
if not self.location:
address = u'%s %s %s %s %s %s' % (self.a2, self.a3, self.a4, self.a5, self.a6, self.pcode)
address = address.encode('utf-8')
geocoder = GoogleV3(api_key='My API Key')
try:
_, latlon = geocoder.geocode(address, timeout=10)
except (URLError, ValueError, TypeError):
pass
else:
point = "POINT(%s %s)" % (latlon[1], latlon[0])
self.location = geos.fromstr(point)
super(Architect, self).save()