【问题标题】:AppEngine GeoPt Data UploadAppEngine GeoPt 数据上传
【发布时间】:2010-12-08 00:00:36
【问题描述】:

我正在用 Java 编写一个 GAE 应用程序,并且只使用 Python 来处理数据 上传。我正在尝试导入如下所示的 CSV 文件:

POSTAL_CODE_ID,PostalCode,City,Province,ProvinceCode,CityType,Latitude,Longitude
1,A0E2Z0,Monkstown,Newfoundland,NL,D,47.150300000000001,-55.299500000000002

如果我导入 Latitude,我可以在我的数据存储中导入此文件 和经度作为浮动,但我无法弄清楚如何 将 lat 和 lng 作为 GeoPt 导入。这是我的 loader.py 文件:

import datetime
from google.appengine.ext import db
from google.appengine.tools import bulkloader

class PostalCode(db.Model):
  id = db.IntegerProperty()
  postal_code = db.PostalAddressProperty()
  city = db.StringProperty()
  province = db.StringProperty()
  province_code = db.StringProperty()
  city_type = db.StringProperty()
  lat = db.FloatProperty()
  lng = db.FloatProperty()

class PostalCodeLoader(bulkloader.Loader):
  def __init__(self):
    bulkloader.Loader.__init__(self, 'PostalCode',
                               [('id', int),
                                ('postal_code', str),
                                ('city', str),
                                ('province', str),
                                ('province_code', str),
                                ('city_type', str),
                                ('lat', float),
                                ('lng', float)
                               ])

loaders = [PostalCodeLoader]

我认为这两行 db.FloatProperty() 应该替换为 db.GeoPtProperty(),但这就是我的足迹的终点。我很陌生 Python 所以任何帮助将不胜感激。

【问题讨论】:

标签: python google-app-engine upload csv


【解决方案1】:

这个问题应该被删除/弃用。 Python 不再用于bulkloader。现在只使用 yaml 文件。有关使用现代散装装载机的这个问题的答案,请参阅: Importing GeoPt data with the Google AppEngine BulkLoader YAML

【讨论】:

  • 也使用python
【解决方案2】:

您可以定义自己的加载器,将 cvs 中的两列合并为一个值,然后编写一个转换器函数,将该值解析为 db.GeoPt。在此解决方案中,您无需更改 csv 文件。这是一个示例(假设 csv 文件只有三列 - lat、lng 和一些名称):

import csv
from google.appengine.ext import db
from google.appengine.tools import bulkloader

class GeoPoint(db.Model):
    name = db.StringProperty()
    location = db.GeoProperty()


class GeoFileLoader(bulkloader.Loader):
    '''
    Loader class processing input csv file and merging two columns into one
    '''
    def __init__(self, kind_name, converters):
        bulkloader.Loader.__init__(self, kind_name, converters)

    def generate_records(self, filename):
        csv_reader = csv.reader(open(filename), delimiter=',')
        for row in csv_reader:
            if row:
                lat = row[0]
                lng = row[1]
                # Here we yield only one value for geo coordinates and name unchanged
                yield '%s,%s' % (lat, lng), row[2]


def geo_converter(geo_str):
    '''
    Converter function - return db.GeoPt from str
    '''
    if geo_str:
        lat, lng = geo_str.split(',')
        return db.GeoPt(lat=float(lat), lon=float(lng))
    return None

# Loader that uses our GeoFileLoader to load data from csv
class PointLoader(GeoFileLoader):
    def __init__(self):
        GeoFileLoader.__init__(self, 'GeoPoint', 
                                [('location', geo_converter),
                                 ('name', str)])

loaders = [PointLoader]

您可以在Nick Johnson's blog找到更多详细信息

【讨论】:

    【解决方案3】:

    好的,我从 Google 网上论坛得到了答案(感谢 Takashi Matsuo 和 Mike Armstrong)。解决方案是修改我的 CSV 文件并将 lat 和 lng 组合在双引号字符串中。双引号字符串中的逗号将不计为 CSV 分隔符。

    POSTAL_CODE_ID,PostalCode,City,Province,ProvinceCode,CityType,Point
    1,A0E 2Z0,Monkstown,Newfoundland,NL,D,"47.150300000000001,-55.299500000000002"
    

    另外,这是我的新 loader.py。请注意,GeoPtProperty 采用带有“00.0000,00.0000”的字符串:

    import datetime
    from google.appengine.ext import db
    from google.appengine.tools import bulkloader
    
    
    class PostalCode(db.Model):
      id = db.IntegerProperty()
      postal_code = db.PostalAddressProperty()
      city = db.StringProperty()
      province = db.StringProperty()
      province_code = db.StringProperty()
      city_type = db.StringProperty()
      geo_pt = db.GeoPtProperty()
    
    class PostalCodeLoader(bulkloader.Loader):
      def __init__(self):
        bulkloader.Loader.__init__(self, 'PostalCode',
                                   [('id', int),
                                    ('postal_code', str),
                                    ('city', str),
                                    ('province', str),
                                    ('province_code', str),
                                    ('city_type', str),
                                    ('geo_pt', str)
                                   ])
    
    loaders = [PostalCodeLoader]
    

    【讨论】:

    • 很高兴听到你弄明白了 :)
    【解决方案4】:

    避免类型转换和实例化测试。我同时使用 geopt 和 geohash http 张贴,在推荐使用默认值的地方非常相似:

        geopt=db.GeoPtProperty(verbose_name="geopt") 
    

    ...

            article.geopt = db.GeoPt(self.request.POST.get('lat'),self.request.POST.get('lng'))
            article.geohash = Geohash.encode(float(lat),float(lng), precision=2)#evalu8 precision variable
    

    code disponible

    demo app

    【讨论】:

      【解决方案5】:

      我不知道你的加载器代码是什么,但是...

      # given this
      class PostalCode(db.Model):
        id = db.IntegerProperty()
        postal_code = db.PostalAddressProperty()
        city = db.StringProperty()
        province = db.StringProperty()
        province_code = db.StringProperty()
        city_type = db.StringProperty()
        geoLocation = db.GeoPtProperty()
      
      
      # you should be able to do this
      myPostalCode.geoLocation = db.GeoPt(-44.22, -33.55)
      

      更多here

      【讨论】:

      • 感谢您的回答。我仍然想知道如何调用 bulkloader 以便它解析我的 CSV 文件并创建一个 GeoPt。我需要解析 2 个 CSV 列并将这 2 个值传递给 GeoPt 构造函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多