def gen(geo, geometry_type=None): features=geofeatures.geo_features(geo) geo_type_table = {'LineString':'LINESTRING', 'Point':'POINT'} type_name = { numbers.Integral:'INT', numbers.Real:'FLOAT', basestring:'TEXT'} type_rank = { numbers.Integral:1, numbers.Real:2, basestring:3 } def make_bigint_specs(specs, features, geometry_type): for (prop,type_name) in specs.items(): if type_name != 'INT': continue for feature in features: if feature['geometry']['type'] != geometry_type: continue if abs(feature['properties'].get(prop,0)) > 2**30: specs[prop] = 'BIGINT' break if not geometry_type: geometry_type = features[0]['geometry']['type'] specs = {} specs_rank = {} # auto create 'col types' based on python types of values # if attribute values not of same type, promote based on type_rank for feature in features: if feature['geometry']['type'] != geometry_type: continue for (prop,value) in feature['properties'].items(): if value==None: continue if isinstance(value,numbers.Integral): # includes int and long t = numbers.Integral elif isinstance(value,numbers.Real): t = numbers.Real elif isinstance(value,basestring): # includes unicode t = basestring else: t = basestring # anything weird goes to TEXT. if specs_rank.get(prop,0) >= type_rank[t]: continue specs[prop] = type_name[t] specs_rank[prop] = type_rank[t] # promote 'INT' attributes with large values to 'BIGINT' make_bigint_specs(specs, features, geometry_type) col_specs = sorted(specs.items()) # add geometry as last column col_specs.append(('geometry', geo_type_table[geometry_type])) return col_specs
def write_geo(self, geo, table_name, srid=None, geometry_type=None, col_specs=None): features = geofeatures.geo_features(geo) if len(features)==0 and not col_specs: log.warning('Could not write db table %s: zero length and no explicit col_specs', table_name) return if not geometry_type: geometry_type = features[0]['geometry']['type'] if not col_specs: col_specs = colspecs.gen(geo, geometry_type) #filter features for correct geometry_type rows = [] for feature in features: if feature['geometry']['type'] != geometry_type: continue row = {} row.update(feature['properties']) row['geometry'] = feature['geometry']['coordinates'] rows.append(row) #print 'DEBUG rows', rows # write the table self.write_table(table_name, col_specs, rows) self.commit()