Esempio n. 1
0
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
Esempio n. 2
0
    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()