AppEngine GeoPt数据上传

时间:2009-10-19 13:21:25

标签: python google-app-engine upload csv

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

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

如果我导入谷歌纵横,我可以在我的数据存储中导入此文件 和经度作为花车,但我很难搞清楚如何 将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所以任何帮助都将非常感激。

5 个答案:

答案 0 :(得分: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]

答案 1 :(得分:0)

我不知道你的加载程序代码是什么......

# 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

答案 2 :(得分:0)

避免类型转换和instanceof-tests。我使用geopt和geohash http发布,相当类似建议启用deafult值:

    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

答案 3 :(得分:0)

您可以定义自己的加载器,它将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

找到更多详细信息

答案 4 :(得分:0)

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