def set_simple_polylines(self, target_field_name='simple_mpoly', tolerance=2, srid=4326): """ Ben Welsh method Simplifies the source polygons so they don't use so many points. Provide a tolerance score the indicates how sharply the the lines should be redrawn. Returns True if successful. """ # Fetch the source polygon source_field_name = 'geom' source = getattr(self, source_field_name) # Fetch the target polygon where the result will be saved #target_field_name = 'simple_mpoly' target = getattr(self, target_field_name) # Simplify the source simple = source.transform(srid, True).simplify(tolerance, True) # If it's a polyline, convert it to a MultiPolyline if simple.geom_type == 'LineString': mp = OGRGeometry(OGRGeomType('MultiLineString')) mp.add(simple.wkt) target = mp.wkt # Otherwise just save out right away else: target = simple.wkt # Set the attribute setattr(self, target_field_name, target) # Save out self.save() return True
def area_shapefile(filename, year): """Import the area units""" census = models.Census.objects.get_or_create(year=year)[0] ds = DataSource(filename) lyr = ds[0] spatial_backend = connections[router.db_for_write(models.Meshblock)].ops SpatialRefSys = spatial_backend.spatial_ref_sys() target_srs = SpatialRefSys.objects.get(srid=models.Area._meta.get_field_by_name("area")[0].srid).srs transform = CoordTransform(lyr.srs, target_srs) for mb_item in lyr: with transaction.atomic(): area = models.Area(census=census) g = OGRGeometry(OGRGeomType("MultiPolygon")) g.add(mb_item.geom) g.transform(transform) mpg = MultiPolygon( [ Polygon(*[[(x, y) for (x, y, z) in inner] for inner in middle], srid=lyr.srs.srid) for middle in g.coords ], srid=lyr.srs.srid, ) area.area = mpg.ewkt area.area_name = mb_item["AU2013_NAM"] area.save()
def handle(self, *args, **kwargs): shape_file = args[0] ds = DataSource(shape_file) layer = ds[0] for feat in layer: try: area_id = feat['ID_0'].value except: area_id = feat['GADMID'].value area_name = unicode(feat['NAME_ENGLI'].value, 'iso-8859-1') area_varname = unicode(feat['NAME_LOCAL'].value, 'iso-8859-1') mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s %s %s" % (area_id, area_name, area_varname) area = Area() area.shape_id = area_id area.name = area_name area.varname = area_varname area.type = 'Country' area.save() area.update_path() area.save() print "Tree ID: %d" % (area.tree_id,) areageom = Geom(area=area) areageom.geom = area_geom areageom.save()
def region_shapefile(filename, year): '''Import the regions''' census = models.Census.objects.get_or_create(year=year)[0] ds = DataSource(filename) lyr = ds[0] spatial_backend = connections[router.db_for_write(models.Meshblock)].ops SpatialRefSys = spatial_backend.spatial_ref_sys() target_srs = SpatialRefSys.objects.get(srid=models.Region._meta.get_field_by_name('area')[0].srid).srs transform = CoordTransform(lyr.srs, target_srs) for mb_item in lyr: with transaction.atomic(): region = models.Region(census=census) g = OGRGeometry(OGRGeomType('MultiPolygon')) g.add(mb_item.geom) g.transform(transform) mpg = MultiPolygon([Polygon(*[[(x, y) for (x, y, z) in inner] for inner in middle], srid=lyr.srs.srid) for middle in g.coords], srid=lyr.srs.srid) region.area = mpg.ewkt region.region_name = mb_item['REGC2013_N'] region.save()
def verify_geom(self, geom, model_field): """ Verifies the geometry -- will construct and return a GeometryCollection if necessary (for example if the model field is MultiPolygonField while the mapped shapefile only contains Polygons). """ # Downgrade a 3D geom to a 2D one, if necessary. if self.coord_dim != geom.coord_dim: geom.coord_dim = self.coord_dim if self.make_multi(geom.geom_type, model_field): # Constructing a multi-geometry type to contain the single geometry multi_type = self.MULTI_TYPES[geom.geom_type.num] g = OGRGeometry(multi_type) g.add(geom) else: g = geom # Transforming the geometry with our Coordinate Transformation object, # but only if the class variable `transform` is set w/a CoordTransform # object. if self.transform: g.transform(self.transform) # Returning the WKT of the geometry. return g.wkt
def handle(self, *args, **kwargs): shape_file = args[0] ds = DataSource(shape_file) layer = ds[0] for feat in layer: try: area_id = feat['ID_0'].value except: area_id = feat['GADMID'].value area_name = unicode(feat['NAME_ENGLI'].value, 'iso-8859-1') area_varname = unicode(feat['NAME_LOCAL'].value, 'iso-8859-1') mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s %s %s" % (area_id, area_name, area_varname) area = Area() area.shape_id = area_id area.name = area_name area.varname = area_varname area.type = 'Country' area.save() area.update_path() area.save() print "Tree ID: %d" % (area.tree_id, ) areageom = Geom(area=area) areageom.geom = area_geom areageom.save()
def verify_geom(self, geom, model_field): """ Verifies the geometry -- will construct and return a GeometryCollection if necessary (for example if the model field is MultiPolygonField while the mapped shapefile only contains Polygons). """ # Downgrade a 3D geom to a 2D one, if necessary. if self.coord_dim != geom.coord_dim: geom.coord_dim = self.coord_dim if self.make_multi(geom.geom_type, model_field): # Constructing a multi-geometry type to contain the single geometry multi_type = self.MULTI_TYPES[geom.geom_type.num] g = OGRGeometry(multi_type) g.add(geom) else: g = geom # Transforming the geometry with our Coordinate Transformation object, # but only if the class variable `transform` is set w/a CoordTransform # object. if self.transform: g.transform(self.transform) # Returning the WKT of the geometry. return g.wkt
def _get_multipolygon_geometry_from_row(self, row): if row.geom_type.django == 'PolygonField': geom = OGRGeometry(OGRGeomType('MultiPolygon')) geom.add(row.geom) return geom elif row.geom_type.django == 'MultiPolygonField': return geom
def set_simple_linestrings(self, tolerance=500): """ Simplifies the source linestrings so they don't use so many points. Provide a tolerance score the indicates how sharply the the lines should be redrawn. Returns True if successful. """ # Get the list of SRIDs we need to update srid_list = self.get_srid_list() # Loop through each for srid in srid_list: # Fetch the source polygon source_field_name = 'linestring_%s' % str(srid) source = getattr(self, source_field_name) # Fetch the target polygon where the result will be saved target_field_name = 'simple_%s' % source_field_name # If there's nothing to transform, drop out now. if not source: setattr(self, target_field_name, None) continue if srid != 900913: # Transform the source out of lng/lat before the simplification copy = source.transform(900913, clone=True) else: copy = deepcopy(source) # Simplify the source simple = copy.simplify(tolerance, True) # If the result is a polygon ... if simple.geom_type == 'LineString': # Create a new Multipolygon shell ml = OGRGeometry(OGRGeomType('MultiLineString')) # Transform the new poly back to its SRID simple.transform(srid) # Stuff it in the shell ml.add(simple.wkt) # Grab the WKT target = ml.wkt # If it's not a polygon... else: # It should be ready to go, so transform simple.transform(srid) # And grab the WKT target = simple.wkt # Stuff the WKT into the field setattr(self, target_field_name, target) return True
def handle(self, *args, **kwargs): tree_id = int(args[0]) level = int(args[1]) shape_file = args[2] ds = DataSource(shape_file) layer = ds[0] with Area.objects.delay_mptt_updates(): for feat in layer: parent_id = feat['ID_%s' % (level - 1, )].value area_id = feat['ID_%s' % level].value area_name = unicode(feat['NAME_%s' % level].value, 'iso-8859-1') try: area_varname = unicode(feat['VARNAME_%s' % level].value, 'iso-8859-1') except: area_varname = '' area_type = unicode(feat['TYPE_%s' % level].value, 'iso-8859-1') try: Area.objects.get(tree_id=tree_id, level=level, shape_id=area_id) except Area.DoesNotExist: pass else: continue mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s (%s): %s (%s)" % (area_id, parent_id, area_name, area_type) area = Area() area.shape_id = area_id area.parent_id = Area.objects.get(tree_id=tree_id, level=(level - 1), shape_id=parent_id).pk area.name = area_name area.varname = area_varname area.type = area_type area.save() areageom = Geom(area=area) areageom.geom = area_geom areageom.save()
def geometry_to_multipolygon(geometry): """ Converts a Polygon to a MultiPolygon. """ if geometry.__class__.__name__ == 'MultiPolygon': return geometry elif geometry.__class__.__name__ == 'Polygon': multipolygon = OGRGeometry(OGRGeomType('MultiPolygon')) multipolygon.add(geometry) return multipolygon else: raise ValueError(_('The geometry is neither a Polygon nor a MultiPolygon.'))
def polygon_to_multipolygon(geom): """ Convert polygons to multipolygons so all features are homogenous in the database. """ if geom.__class__.__name__ == 'Polygon': g = OGRGeometry(OGRGeomType('MultiPolygon')) g.add(geom) return g elif geom.__class__.__name__ == 'MultiPolygon': return geom else: raise ValueError('Geom is neither Polygon nor MultiPolygon.')
def polygon_to_multipolygon(self, geom): """ Convert polygons to multipolygons so all features are homogenous in the database. """ if geom.__class__.__name__ == 'Polygon': g = OGRGeometry(OGRGeomType('MultiPolygon')) g.add(geom) return g elif geom.__class__.__name__ == 'MultiPolygon': return geom else: raise ValueError('Geom is neither Polygon nor MultiPolygon.')
def merge(self, other): """ Creates a new MultiPolygon from the Polygons of two MultiPolygons. """ if hasattr(other, 'geometry'): other = other.geometry geometry = OGRGeometry(OGRGeomType('MultiPolygon')) for polygon in self.geometry: geometry.add(polygon) for polygon in other: geometry.add(polygon) return Geometry(geometry)
def geometry_to_multipolygon(geometry): """ Converts a Polygon to a MultiPolygon. """ value = geometry.__class__.__name__ if value == 'MultiPolygon': return geometry elif value == 'Polygon': multipolygon = OGRGeometry(OGRGeomType('MultiPolygon')) multipolygon.add(geometry) return multipolygon else: raise ValueError(_('The geometry is a %(value)s but must be a Polygon or a MultiPolygon.') % {'value': value})
def geometry_to_multipolygon(geometry): """ Converts a Polygon to a MultiPolygon. """ value = geometry.__class__.__name__ if value == 'MultiPolygon': return geometry elif value == 'Polygon': multipolygon = OGRGeometry(OGRGeomType('MultiPolygon')) multipolygon.add(geometry) return multipolygon else: raise ValueError(_('The geometry is a %(value)s but must be a Polygon or a MultiPolygon.') % {'value': value})
def merge(self, other): """ Creates a new MultiPolygon from the Polygons of two MultiPolygons. """ if hasattr(other, 'geometry'): other = other.geometry geometry = OGRGeometry(OGRGeomType('MultiPolygon')) for polygon in self.geometry: geometry.add(polygon) for polygon in other: geometry.add(polygon) return Geometry(geometry)
def test_multipoints(self): "Testing MultiPoint objects." for mp in self.geometries.multipoints: mgeom1 = OGRGeometry(mp.wkt) # First one from WKT self.assertEqual(4, mgeom1.geom_type) self.assertEqual("MULTIPOINT", mgeom1.geom_name) mgeom2 = OGRGeometry("MULTIPOINT") # Creating empty multipoint mgeom3 = OGRGeometry("MULTIPOINT") for g in mgeom1: mgeom2.add(g) # adding each point from the multipoints mgeom3.add(g.wkt) # should take WKT as well self.assertEqual(mgeom1, mgeom2) # they should equal self.assertEqual(mgeom1, mgeom3) self.assertEqual(mp.coords, mgeom2.coords) self.assertEqual(mp.n_p, mgeom2.point_count)
def test03_multipoints(self): "Testing MultiPoint objects." for mp in self.geometries.multipoints: mgeom1 = OGRGeometry(mp.wkt) # First one from WKT self.assertEqual(4, mgeom1.geom_type) self.assertEqual('MULTIPOINT', mgeom1.geom_name) mgeom2 = OGRGeometry('MULTIPOINT') # Creating empty multipoint mgeom3 = OGRGeometry('MULTIPOINT') for g in mgeom1: mgeom2.add(g) # adding each point from the multipoints mgeom3.add(g.wkt) # should take WKT as well self.assertEqual(mgeom1, mgeom2) # they should equal self.assertEqual(mgeom1, mgeom3) self.assertEqual(mp.coords, mgeom2.coords) self.assertEqual(mp.n_p, mgeom2.point_count)
def verify_geom(geom, model_field): """ Verifies the geometry -- will construct and return a GeometryCollection if necessary (for example if the model field is MultiPolygonField while the mapped shapefile only contains Polygons). """ if make_multi(geom.geom_type, model_field): # Constructing a multi-geometry type to contain the single geometry multi_type = MULTI_TYPES[geom.geom_type.num] g = OGRGeometry(multi_type) g.add(geom) else: g = geom # Returning the WKT of the geometry. return g.wkt
def handle(self, *args, **kwargs): tree_id = int(args[0]) level = int(args[1]) shape_file = args[2] ds = DataSource(shape_file) layer = ds[0] with Area.objects.delay_mptt_updates(): for feat in layer: parent_id = feat['ID_%s' % (level-1,)].value area_id = feat['ID_%s' % level].value area_name = unicode(feat['NAME_%s' % level].value, 'iso-8859-1') try: area_varname = unicode(feat['VARNAME_%s' % level].value, 'iso-8859-1') except: area_varname = '' area_type = unicode(feat['TYPE_%s' % level].value, 'iso-8859-1') try: Area.objects.get(tree_id=tree_id, level=level, shape_id=area_id) except Area.DoesNotExist: pass else: continue mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s (%s): %s (%s)" % (area_id, parent_id, area_name, area_type) area = Area() area.shape_id = area_id area.parent_id = Area.objects.get(tree_id=tree_id, level=(level-1), shape_id=parent_id).pk area.name = area_name area.varname = area_varname area.type = area_type area.save() areageom = Geom(area=area) areageom.geom = area_geom areageom.save()
def verify_geom(geom, model_field): """ Verifies the geometry -- will construct and return a GeometryCollection if necessary (for example if the model field is MultiPolygonField while the mapped shapefile only contains Polygons). """ if make_multi(geom.geom_type, model_field): # Constructing a multi-geometry type to contain the single geometry multi_type = MULTI_TYPES[geom.geom_type.num] g = OGRGeometry(multi_type) g.add(geom) else: g = geom # Returning the WKT of the geometry. return g.wkt
def handle(self, shapefile, **options): if options['name']: name_field = options['name'] else: name_field = 'NAME' layer = DataSource(shapefile)[0] Location.objects.filter(type=layer.name).delete() for feature in layer: print feature if feature.geom.geom_type.name != 'MultiPolygon': geom = OGRGeometry(OGRGeomType('MultiPolygon')) geom.add(feature.geom) else: geom = feature.geom Location.objects.create(name=feature[name_field], type=layer.name, area=geom.area, geometry=geom.wkt)
def handle(self, shapefile, **options): if options['name']: name_field = options['name'] else: name_field = 'NAME' layer = DataSource(shapefile)[0] Location.objects.filter(type=layer.name).delete() for feature in layer: print feature if feature.geom.geom_type.name != 'MultiPolygon': geom = OGRGeometry(OGRGeomType('MultiPolygon')) geom.add(feature.geom) else: geom = feature.geom Location.objects.create(name=feature[name_field], type=layer.name, area=geom.area, geometry=geom.wkt)
def set_simple_polygons(self, tolerance=200): """ Simplifies the source polygons so they don't use so many points. Provide a tolerance score the indicates how sharply the the lines should be redrawn. Returns True if successful. """ from django.contrib.gis.gdal import OGRGeometry, OGRGeomType srid_list = [4269, 900913] for srid in srid_list: # Fetch the source polygon source_field_name = 'polygon_%s' % str(srid) source = getattr(self, source_field_name) # Fetch the target polygon where the result will be saved target_field_name = 'simple_%s' % source_field_name target = getattr(self, target_field_name) # Transform the source out of lng/lat before the simplification copy = source.transform(900913, clone=True) # Simplify the source simple = copy.simplify(tolerance, True) # If it's a polygon, convert it to a MultiPolygon if simple.geom_type == 'Polygon': mp = OGRGeometry(OGRGeomType('MultiPolygon')) simple.transform(srid) mp.add(simple.wkt) target = mp.wkt # Otherwise just save out right away else: simple.transform(srid) target = simple.wkt # Set the attribute setattr(self, target_field_name, target) # Save out self.save() return True
def test_add(self): "Testing GeometryCollection.add()." # Can't insert a Point into a MultiPolygon. mp = OGRGeometry('MultiPolygon') pnt = OGRGeometry('POINT(5 23)') with self.assertRaises(GDALException): mp.add(pnt) # GeometryCollection.add may take an OGRGeometry (if another collection # of the same type all child geoms will be added individually) or WKT. for mp in self.geometries.multipolygons: mpoly = OGRGeometry(mp.wkt) mp1 = OGRGeometry('MultiPolygon') mp2 = OGRGeometry('MultiPolygon') mp3 = OGRGeometry('MultiPolygon') for poly in mpoly: mp1.add(poly) # Adding a geometry at a time mp2.add(poly.wkt) # Adding WKT mp3.add(mpoly) # Adding a MultiPolygon's entire contents at once. for tmp in (mp1, mp2, mp3): self.assertEqual(mpoly, tmp)
def test_add(self): "Testing GeometryCollection.add()." # Can't insert a Point into a MultiPolygon. mp = OGRGeometry('MultiPolygon') pnt = OGRGeometry('POINT(5 23)') with self.assertRaises(GDALException): mp.add(pnt) # GeometryCollection.add may take an OGRGeometry (if another collection # of the same type all child geoms will be added individually) or WKT. for mp in self.geometries.multipolygons: mpoly = OGRGeometry(mp.wkt) mp1 = OGRGeometry('MultiPolygon') mp2 = OGRGeometry('MultiPolygon') mp3 = OGRGeometry('MultiPolygon') for poly in mpoly: mp1.add(poly) # Adding a geometry at a time mp2.add(poly.wkt) # Adding WKT mp3.add(mpoly) # Adding a MultiPolygon's entire contents at once. for tmp in (mp1, mp2, mp3): self.assertEqual(mpoly, tmp)
# LayerMapping -- A Django Model/OGR Layer Mapping Utility
def add_boundaries_for_layer(self, config, layer, bset, options): # Get spatial reference system for the postgis geometry field geometry_field = Boundary._meta.get_field_by_name(GEOMETRY_COLUMN)[0] SpatialRefSys = connections[options["database"]].ops.spatial_ref_sys() db_srs = SpatialRefSys.objects.using(options["database"]).get(srid=geometry_field.srid).srs if 'srid' in config and config['srid']: layer_srs = SpatialRefSys.objects.get(srid=config['srid']).srs else: layer_srs = layer.srs # Create a convertor to turn the source data into transformer = CoordTransform(layer_srs, db_srs) for feature in layer: geometry = feature.geom feature = UnicodeFeature(feature, encoding=config.get('encoding', 'ascii')) feature.layer = layer # add additional attribute so definition file can trace back to filename if not config.get('is_valid_func', lambda feature : True)(feature): continue # Transform the geometry to the correct SRS geometry = self.polygon_to_multipolygon(geometry) geometry.transform(transformer) # Create simplified geometry field by collapsing points within 1/1000th of a degree. # Since Chicago is at approx. 42 degrees latitude this works out to an margin of # roughly 80 meters latitude and 112 meters longitude. # Preserve topology prevents a shape from ever crossing over itself. simple_geometry = geometry.geos.simplify(app_settings.SIMPLE_SHAPE_TOLERANCE, preserve_topology=True) # Conversion may force multipolygons back to being polygons simple_geometry = self.polygon_to_multipolygon(simple_geometry.ogr) # Extract metadata into a dictionary metadata = dict( ( (field, feature.get(field)) for field in layer.fields ) ) external_id = str(config['id_func'](feature)) feature_name = config['name_func'](feature) feature_slug = slugify(config['slug_func'](feature).replace(u'—', '-')) log.info('%s...' % feature_slug) if options["merge"]: try: b0 = Boundary.objects.get(set=bset, slug=feature_slug) g = OGRGeometry(OGRGeomType('MultiPolygon')) for p in b0.shape: g.add(p.ogr) for p in geometry: g.add(p) b0.shape = g.wkt if options["merge"] == "union": # take a union of the shapes g = self.polygon_to_multipolygon(b0.shape.cascaded_union.ogr) b0.shape = g.wkt # re-create the simple_shape by simplifying the union b0.simple_shape = self.polygon_to_multipolygon(g.geos.simplify(app_settings.SIMPLE_SHAPE_TOLERANCE, preserve_topology=True).ogr).wkt elif options["merge"] == "combine": # extend the previous simple_shape with the new simple_shape g = OGRGeometry(OGRGeomType('MultiPolygon')) for p in b0.simple_shape: g.add(p.ogr) for p in simple_geometry: g.add(p) b0.simple_shape = g.wkt else: raise ValueError("Invalid value for merge option.") b0.centroid = b0.shape.centroid b0.extent = b0.shape.extent b0.save() continue except Boundary.DoesNotExist: pass bdry = Boundary.objects.create( set=bset, set_name=bset.singular, external_id=external_id, name=feature_name, slug=feature_slug, metadata=metadata, shape=geometry.wkt, simple_shape=simple_geometry.wkt, centroid=geometry.geos.centroid, extent=geometry.extent, label_point=config.get("label_point_func", lambda x : None)(feature) ) if bset.extent[0] == None or bdry.extent[0] < bset.extent[0]: bset.extent[0] = bdry.extent[0] if bset.extent[1] == None or bdry.extent[1] < bset.extent[1]: bset.extent[1] = bdry.extent[1] if bset.extent[2] == None or bdry.extent[2] > bset.extent[2]: bset.extent[2] = bdry.extent[2] if bset.extent[3] == None or bdry.extent[3] > bset.extent[3]: bset.extent[3] = bdry.extent[3]
def _save(feat_range=default_range, num_feat=0, num_saved=0): if feat_range: layer_iter = self.layer[feat_range] else: layer_iter = self.layer for feat in layer_iter: num_feat += 1 # Getting the keyword arguments try: kwargs = self.feature_kwargs(feat) except LayerMapError as msg: # Something borked the validation if strict: raise elif not silent: stream.write('Ignoring Feature ID %s because: %s\n' % (feat.fid, msg)) else: # Constructing the model using the keyword args is_update = False if self.unique: # If we want unique models on a particular field, handle the # geometry appropriately. try: # Getting the keyword arguments and retrieving # the unique model. u_kwargs = self.unique_kwargs(kwargs) m = self.model.objects.using(self.using).get(**u_kwargs) is_update = True # Getting the geometry (in OGR form), creating # one from the kwargs WKT, adding in additional # geometries, and update the attribute with the # just-updated geometry WKT. geom_value = getattr(m, self.geom_field) if geom_value is None: geom = OGRGeometry(kwargs[self.geom_field]) else: geom = geom_value.ogr new = OGRGeometry(kwargs[self.geom_field]) for g in new: geom.add(g) setattr(m, self.geom_field, geom.wkt) except ObjectDoesNotExist: # No unique model exists yet, create. m = self.model(**kwargs) else: m = self.model(**kwargs) try: # Attempting to save. m.save(using=self.using) num_saved += 1 if verbose: stream.write('%s: %s\n' % ('Updated' if is_update else 'Saved', m)) except Exception as msg: if strict: # Bailing out if the `strict` keyword is set. if not silent: stream.write( 'Failed to save the feature (id: %s) into the ' 'model with the keyword arguments:\n' % feat.fid ) stream.write('%s\n' % kwargs) raise elif not silent: stream.write('Failed to save %s:\n %s\nContinuing\n' % (kwargs, msg)) # Printing progress information, if requested. if progress and num_feat % progress_interval == 0: stream.write('Processed %d features, saved %d ...\n' % (num_feat, num_saved)) # Only used for status output purposes -- incremental saving uses the # values returned here. return num_saved, num_feat
def handle(self, *args, **kwargs): level = int(args[0]) shape_file = args[1] ds = DataSource(shape_file) layer = ds[0] print layer.fields if level == 0: for feat in layer: area_id = feat['GADMID'].value area_name = feat['NAME_ENGLI'].value area_varname = feat['NAME_LOCAL'].value mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s %s %s" % (area_id, area_name, area_varname) area = Area() area.id = area_id area.name = area_name area.varname = area_varname area.type = 'Country' area.save() areageom = Geom(area=area) areageom.geom = area_geom areageom.save() else: for feat in layer: parent_id = feat['ID_%s' % (level-1,)].value area_id = feat['ID_%s' % level].value area_name = unicode(feat['NAME_%s' % level].value, 'iso-8859-1') area_varname = unicode(feat['VARNAME_%s' % level].value, 'iso-8859-1') area_type = unicode(feat['TYPE_%s' % level].value, 'iso-8859-1') mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s (%s): %s (%s)" % (area_id, parent_id, area_name, area_type) area = Area() area.id = area_id area.parent_id = parent_id area.name = area_name area.varname = area_varname area.type = area_type area.save() areageom = Geom(area=area) areageom.geom = area_geom areageom.save()
def convert_shapefile(shapefilename, srid=4674): """ shapefilename: considera nomenclatura de shapefile do IBGE para determinar se é UF ou Municípios. ex. 55UF2500GC_SIR.shp para UF e 55MU2500GC_SIR.shp para Municípios srid: 4674 (Projeção SIRGAS 2000) """ # /home/nando/Desktop/IBGE/2010/55MU2500GC_SIR.shp ds = DataSource(shapefilename) is_uf = shapefilename.upper().find('UF') != -1 transform_coord = None if srid != SRID: transform_coord = CoordTransform(SpatialReference(srid), SpatialReference(SRID)) if is_uf: model = UF else: model = Municipio ct = 0 for f in ds[0]: # 3D para 2D se necessário if f.geom.coord_dim != 2: f.geom.coord_dim = 2 # converte para MultiPolygon se necessário if isinstance(f.geom, Polygon): g = OGRGeometry(OGRGeomType('MultiPolygon')) g.add(f.geom) else: g = f.geom # transforma coordenadas se necessário if transform_coord: g.transform(transform_coord) # força 2D g.coord_dim = 2 kwargs = {} if is_uf: kwargs['nome'] = capitalize_name(unicode(f.get(CAMPO_NOME_UF),'latin1')) kwargs['geom'] = g.ewkt kwargs['id_ibge'] = f.get(CAMPO_GEOCODIGO_UF) kwargs['regiao'] = capitalize_name(unicode(f.get(CAMPO_REGIAO_UF), 'latin1')) kwargs['uf'] = UF_SIGLAS_DICT.get(kwargs['id_ibge']) else: kwargs['nome'] = capitalize_name(unicode(f.get(CAMPO_NOME_MU),'latin1')) kwargs['geom'] = g.ewkt kwargs['id_ibge'] = f.get(CAMPO_GEOCODIGO_MU) kwargs['uf'] = UF.objects.get(pk=f.get(CAMPO_GEOCODIGO_MU)[:2]) kwargs['uf_sigla'] = kwargs['uf'].uf kwargs['nome_abreviado'] = slugify(kwargs['nome']) # tenta corrigir nomes duplicados, são em torno de 242 nomes repetidos # adicionando a sigla do estado no final if Municipio.objects.filter(nome_abreviado=kwargs['nome_abreviado']).count() > 0: kwargs['nome_abreviado'] = u'%s-%s' % (kwargs['nome_abreviado'], kwargs['uf_sigla'].lower()) instance = model(**kwargs) instance.save() ct += 1 print(ct, (is_uf and "Unidades Federativas criadas" or "Municipios criados"))
def handle(self, *args, **kwargs): level = int(args[0]) shape_file = args[1] ds = DataSource(shape_file) layer = ds[0] print layer.fields if level == 0: for feat in layer: area_id = feat['GADMID'].value area_name = feat['NAME_ENGLI'].value area_varname = feat['NAME_LOCAL'].value mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s %s %s" % (area_id, area_name, area_varname) area = Area() area.id = area_id area.name = area_name area.varname = area_varname area.type = 'Country' area.save() areageom = Geom(area=area) areageom.geom = area_geom areageom.save() else: for feat in layer: parent_id = feat['ID_%s' % (level - 1, )].value area_id = feat['ID_%s' % level].value area_name = unicode(feat['NAME_%s' % level].value, 'iso-8859-1') area_varname = unicode(feat['VARNAME_%s' % level].value, 'iso-8859-1') area_type = unicode(feat['TYPE_%s' % level].value, 'iso-8859-1') mpgeom = OGRGeometry('MultiPolygon') mpgeom.add(feat.geom) area_geom = GEOSGeometry(mpgeom.wkt) print "%s (%s): %s (%s)" % (area_id, parent_id, area_name, area_type) area = Area() area.id = area_id area.parent_id = parent_id area.name = area_name area.varname = area_varname area.type = area_type area.save() areageom = Geom(area=area) areageom.geom = area_geom areageom.save()
def import_geodata(data_files, data_path, catalog): """ Imports the geospatial data into the database. Note, in the case of this data, there's data attached to the multipolygon that we want in the datastore. Will also convert Polygons to MulitPolygons. Not idempotent! (get_or_create doesn't really work with geometry objects.) Args: data_files (list(str)): List of source files. data_path (path): Path to the source files. catalog (Catalog): Catalog that this geodata belongs to. """ geometry_data_mapping = { 'CUSEC': 'cusec', 'CUMUN': 'cumun', 'CSEC': 'secc', 'CDIS': 'dist', 'CMUN': 'cmun', 'CPRO': 'cpro', 'CCA': 'ccaa', 'CUDIS': 'cudis', 'OBS': 'obs', 'CNUT0': 'cnut0', 'CNUT1': 'cnut1', 'CNUT2': 'cnut2', 'CNUT3': 'cnut3', 'CLAU2': 'clau2', 'NPRO': 'npro', 'NCA': 'nca', 'NMUN': 'nmun' } metadata_map = { "OBJECTID": "obj_id", "Shape_len": "perimeter", "Shape_area": "area", } ignore = ["Shape_Leng"] field_skip = list(metadata_map.keys()) + ignore metadata_skip = list(geometry_data_mapping.keys()) + ignore shp = [s for s in data_files if ".shp" == s[-4:]][0] shape_file = path.join(data_path, shp) ds = DataSource(shape_file) layer = ds[0] fields = layer.fields source_srid = SpatialReference(layer.srs.srid) our_srid = SpatialReference(4326) transform = CoordTransform(source_srid, our_srid) for shape in layer: geom = shape.geom geom.transform(transform) field_data = { geometry_data_mapping[k]: shape.get(v) for k, v in zip(fields, range(len(fields))) if k not in field_skip } metadata = { metadata_map[k]: shape.get(v) for k, v in zip(fields, range(len(fields))) if k not in metadata_skip } # Normalise all Polygons to Multipolygons for ease of use later. if geom.geom_type.name == "Polygon": mp = OGRGeometry(OGRGeomType('MultiPolygon')) mp.add(geom) geom = mp g = GeometryStore(catalog=catalog, geom=geom.geos, metadata=metadata) g.save() d = DataStore(catalog=catalog, parent_geometry=g, data=field_data) d.save()
def _save(feat_range=default_range, num_feat=0, num_saved=0): if feat_range: layer_iter = self.layer[feat_range] else: layer_iter = self.layer for feat in layer_iter: num_feat += 1 # Getting the keyword arguments try: kwargs = self.feature_kwargs(feat) except LayerMapError as msg: # Something borked the validation if strict: raise elif not silent: stream.write('Ignoring Feature ID %s because: %s\n' % (feat.fid, msg)) else: # Constructing the model using the keyword args is_update = False if self.unique: # If we want unique models on a particular field, handle the # geometry appropriately. try: # Getting the keyword arguments and retrieving # the unique model. u_kwargs = self.unique_kwargs(kwargs) m = self.model.objects.using( self.using).get(**u_kwargs) is_update = True # Getting the geometry (in OGR form), creating # one from the kwargs WKT, adding in additional # geometries, and update the attribute with the # just-updated geometry WKT. geom_value = getattr(m, self.geom_field) if geom_value is None: geom = OGRGeometry(kwargs[self.geom_field]) else: geom = geom_value.ogr new = OGRGeometry(kwargs[self.geom_field]) for g in new: geom.add(g) setattr(m, self.geom_field, geom.wkt) except ObjectDoesNotExist: # No unique model exists yet, create. m = self.model(**kwargs) else: m = self.model(**kwargs) try: # Attempting to save. m.save(using=self.using) num_saved += 1 if verbose: stream.write( '%s: %s\n' % ('Updated' if is_update else 'Saved', m)) except Exception as msg: if strict: # Bailing out if the `strict` keyword is set. if not silent: stream.write( 'Failed to save the feature (id: %s) into the ' 'model with the keyword arguments:\n' % feat.fid) stream.write('%s\n' % kwargs) raise elif not silent: stream.write( 'Failed to save %s:\n %s\nContinuing\n' % (kwargs, msg)) # Printing progress information, if requested. if progress and num_feat % progress_interval == 0: stream.write('Processed %d features, saved %d ...\n' % (num_feat, num_saved)) # Only used for status output purposes -- incremental saving uses the # values returned here. return num_saved, num_feat