def get_wkt(value, srid=DEFAULT_PROJ): """ `value` is either a WKT string or a geometry field. Returns WKT in the projection for the given SRID. """ ogr = None if value: if isinstance(value, OGRGeometry): ogr = value elif isinstance(value, GEOSGeometry): ogr = value.ogr elif isinstance(value, basestring): match = ewkt_re.match(value) if match: ogr = OGRGeometry(match.group('wkt'), match.group('srid')) else: ogr = OGRGeometry(value) wkt = '' if ogr: # Workaround for Django bug #12312. GEOSGeometry types don't support 3D wkt; # OGRGeometry types output 3D for linestrings even if they should do 2D, causing # IntegrityError's. if ogr.dimension == 2: geos = ogr.geos geos.transform(srid) wkt = geos.wkt else: ogr.transform(srid) wkt = ogr.wkt return wkt
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 compute_max_zoom(self): """ Set max zoom property based on rasterlayer metadata. """ # Return manual override value if provided if self.rasterlayer.max_zoom is not None: return self.rasterlayer.max_zoom if self.dataset.srs.srid == WEB_MERCATOR_SRID: # For rasters in web mercator, use the scale directly scale = abs(self.dataset.scale.x) else: # Create a line from the center of the raster to a point that is # one pixel width away from the center. xcenter = self.dataset.extent[0] + (self.dataset.extent[2] - self.dataset.extent[0]) / 2 ycenter = self.dataset.extent[1] + (self.dataset.extent[3] - self.dataset.extent[1]) / 2 linestring = 'LINESTRING({} {}, {} {})'.format( xcenter, ycenter, xcenter + self.dataset.scale.x, ycenter) line = OGRGeometry(linestring, srs=self.dataset.srs) # Tansform the line into web mercator. line.transform(WEB_MERCATOR_SRID) # Use the lenght of the transformed line as scale. scale = line.geos.length return utils.closest_zoomlevel(scale)
def transform_rd(point): ''' Please note this returns an OGRGeometry, not a point ''' src_string = '+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +units=m +towgs84=565.2369,50.0087,465.658,-0.406857330322398,0.350732676542563,-1.8703473836068,4.0812 +no_defs no_defs <>' src_srs = SpatialReference(src_string) geom = OGRGeometry(point.wkt, src_srs) geom.transform(4326) return geom
def transform(self, ct, clone=False): """ Requires GDAL. Transforms the geometry according to the given transformation object, which may be an integer SRID, and WKT or PROJ.4 string. By default, the geometry is transformed in-place and nothing is returned. However if the `clone` keyword is set, then this geometry will not be modified and a transformed clone will be returned instead. """ srid = self.srid if HAS_GDAL and srid: g = OGRGeometry(self.wkb, srid) g.transform(ct) wkb = str(g.wkb) ptr = from_wkb(wkb, len(wkb)) if clone: # User wants a cloned transformed geometry returned. return GEOSGeometry(ptr, srid=g.srid) if ptr: # Reassigning pointer, and performing post-initialization setup # again due to the reassignment. destroy_geom(self.ptr) self._ptr = ptr self._post_init(g.srid) else: raise GEOSException('Transformed WKB was invalid.')
def extent(self, srid=WEB_MERCATOR_SRID): """ Returns bbox for layer. """ if not self._bbox or self._bbox_srid != srid: # Get bbox for raster in original coordinates meta = self.metadata xmin = meta.uperleftx ymax = meta.uperlefty xmax = xmin + meta.width * meta.scalex ymin = ymax + meta.height * meta.scaley # Create Polygon box geom = OGRGeometry(Envelope((xmin, ymin, xmax, ymax)).wkt) # Set original srs if meta.srs_wkt: geom.srs = SpatialReference(meta.srs_wkt) else: geom.srid = meta.srid # Transform to requested srid geom.transform(srid) # Calculate value range for bbox coords = geom.coords[0] xvals = [x[0] for x in coords] yvals = [x[1] for x in coords] # Set bbox self._bbox = (min(xvals), min(yvals), max(xvals), max(yvals)) self._bbox_srid = srid return self._bbox
def latlon2city(lon, lat): west = -122.515003 east = -122.355684 north = 37.832365 south = 37.706032 lon_range = abs(abs(west) - abs(east)) lat_range = north - south west_coord = 5979762.107179 east_coord = 6024890.063509 north_coord = 2130875.573550 south_coord = 2085798.824452 ew_range = east_coord - west_coord ns_range = north_coord - south_coord lat_pct = (north - lat) / lat_range lon_pct = (abs(west) - abs(lon)) / lon_range x = west_coord + (lon_pct * ew_range) y = (lat_pct * ns_range) point = "POINT(" + str(lon) + " " + str(lat) + ")" geom = OGRGeometry(point) geom.transform(ct) res = geom.ewkt r = re.compile('([0-9\.]+)') (x, y) = r.findall(res) return ((x, y))
def extent(self, srid=WEB_MERCATOR_SRID): """ Returns bbox for layer. """ if not self._bbox or self._bbox_srid != srid: # Get bbox for raster in original coordinates meta = self.metadata xmin = meta.uperleftx ymax = meta.uperlefty xmax = xmin + meta.width * meta.scalex ymin = ymax + meta.height * meta.scaley # Create Polygon box geom = OGRGeometry(Envelope((xmin, ymin, xmax, ymax)).wkt) # Set original srs if meta.srs_wkt: geom.srs = SpatialReference(meta.srs_wkt) else: geom.srid = meta.srid # Transform to requested srid geom.transform(srid) # Calculate value range for bbox coords = geom.coords[0] xvals = [x[0] for x in coords] yvals = [x[1] for x in coords] # Set bbox self._bbox = (min(xvals), min(yvals), max(xvals), max(yvals)) self._bbox_srid = srid return self._bbox
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 compute_max_zoom(self): """ Set max zoom property based on rasterlayer metadata. """ # Return manual override value if provided if self.rasterlayer.max_zoom is not None: return self.rasterlayer.max_zoom if self.dataset.srs.srid == WEB_MERCATOR_SRID: # For rasters in web mercator, use the scale directly scale = abs(self.dataset.scale.x) else: # Create a line from the center of the raster to a point that is # one pixel width away from the center. xcenter = self.dataset.extent[0] + (self.dataset.extent[2] - self.dataset.extent[0]) / 2 ycenter = self.dataset.extent[1] + (self.dataset.extent[3] - self.dataset.extent[1]) / 2 linestring = 'LINESTRING({} {}, {} {})'.format( xcenter, ycenter, xcenter + self.dataset.scale.x, ycenter ) line = OGRGeometry(linestring, srs=self.dataset.srs) # Tansform the line into web mercator. line.transform(WEB_MERCATOR_SRID) # Use the lenght of the transformed line as scale. scale = line.geos.length return utils.closest_zoomlevel(scale)
def transform(self, ct, clone=False): """ Requires GDAL. Transforms the geometry according to the given transformation object, which may be an integer SRID, and WKT or PROJ.4 string. By default, the geometry is transformed in-place and nothing is returned. However if the `clone` keyword is set, then this geometry will not be modified and a transformed clone will be returned instead. """ srid = self.srid if HAS_GDAL and srid: g = OGRGeometry(self.wkb, srid) g.transform(ct) wkb = str(g.wkb) ptr = from_wkb(wkb, len(wkb)) if clone: # User wants a cloned transformed geometry returned. return GEOSGeometry(ptr, srid=g.srid) if ptr: # Reassigning pointer, and performing post-initialization setup # again due to the reassignment. destroy_geom(self.ptr) self._ptr = ptr self._post_init(g.srid) else: raise GEOSException('Transformed WKB was invalid.')
def get_wkt(value, srid=DEFAULT_PROJ): """ `value` is either a WKT string or a geometry field. Returns WKT in the projection for the given SRID. """ ogr = None if value: if isinstance(value, OGRGeometry): ogr = value elif isinstance(value, GEOSGeometry): ogr = value.ogr elif isinstance(value, basestring): match = ewkt_re.match(value) if match: ogr = OGRGeometry(match.group('wkt'), match.group('srid')) else: ogr = OGRGeometry(value) wkt = '' if ogr: # Workaround for Django bug #12312. GEOSGeometry types don't support 3D wkt; # OGRGeometry types output 3D for linestrings even if they should do 2D, causing # IntegrityError's. if ogr.dimension == 2: geos = ogr.geos geos.transform(srid) wkt = geos.wkt else: ogr.transform(srid) wkt = ogr.wkt return wkt
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 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 test09c_transform_dim(self): "Testing coordinate dimension is the same on transformed geometries." ls_orig = OGRGeometry('LINESTRING(-104.609 38.255)', 4326) ls_trans = OGRGeometry('LINESTRING(992385.4472045 481455.4944650)', 2774) prec = 3 ls_orig.transform(ls_trans.srs) # Making sure the coordinate dimension is still 2D. self.assertEqual(2, ls_orig.coord_dim) self.assertAlmostEqual(ls_trans.x[0], ls_orig.x[0], prec) self.assertAlmostEqual(ls_trans.y[0], ls_orig.y[0], prec)
def test_transform_dim(self): "Testing coordinate dimension is the same on transformed geometries." ls_orig = OGRGeometry("LINESTRING(-104.609 38.255)", 4326) ls_trans = OGRGeometry("LINESTRING(992385.4472045 481455.4944650)", 2774) prec = 3 ls_orig.transform(ls_trans.srs) # Making sure the coordinate dimension is still 2D. self.assertEqual(2, ls_orig.coord_dim) self.assertAlmostEqual(ls_trans.x[0], ls_orig.x[0], prec) self.assertAlmostEqual(ls_trans.y[0], ls_orig.y[0], prec)
def rasterize(geom, rast, burn_value=1, all_touched=False, add=False): """ Rasterize a geometry. The result is aligned with the input raster. """ # Create in memory target raster rasterized = rast.warp({'name': 'rasterized.MEM', 'driver': 'MEM'}) # Set all values to zero if add option is off. if not add: rasterized.bands[0].data(numpy.zeros(rast.width * rast.height)) # Set zero as nodata rasterized.bands[0].nodata_value = 0 # Make sure geom is an OGR geometry if not isinstance(geom, OGRGeometry): geom = OGRGeometry(geom.ewkt) geom.transform(rast.srs) # Set rasterization parameters nr_of_bands_to_rasterize = 1 band_indices_to_rasterize = (c_int * 1)(1) nr_of_geometries = 1 burn_value = (c_double * 1)(burn_value) geometry_list = (c_void_p * 1)(geom.ptr) # Setup papsz options papsz_options = [] if all_touched: papsz_options.append('ALL_TOUCHED=TRUE'.encode()) if add: papsz_options.append('MERGE_ALG=ADD'.encode()) papsz_options = (c_char_p * len(papsz_options))(*papsz_options) # Rasterize this geometry rasterize_geometries( rasterized.ptr, nr_of_bands_to_rasterize, band_indices_to_rasterize, nr_of_geometries, geometry_list, None, None, # Transform parameters burn_value, papsz_options, None, None # Progress functions ) return rasterized
def rasterize(geom, rast, burn_value=1, all_touched=False, add=False): """ Rasterize a geometry. The result is aligned with the input raster. """ # Create in memory target raster rasterized = rast.warp({'name': 'rasterized.MEM', 'driver': 'MEM'}) # Set all values to zero if add option is off. if not add: rasterized.bands[0].data(numpy.zeros(rast.width * rast.height)) # Set zero as nodata rasterized.bands[0].nodata_value = 0 # Make sure geom is an OGR geometry if not isinstance(geom, OGRGeometry): geom = OGRGeometry(geom.ewkt) geom.transform(rast.srs) # Set rasterization parameters nr_of_bands_to_rasterize = 1 band_indices_to_rasterize = (c_int * 1)(1) nr_of_geometries = 1 burn_value = (c_double * 1)(burn_value) geometry_list = (c_void_p * 1)(geom.ptr) # Setup papsz options papsz_options = [] if all_touched: papsz_options.append('ALL_TOUCHED=TRUE'.encode()) if add: papsz_options.append('MERGE_ALG=ADD'.encode()) papsz_options = (c_char_p * len(papsz_options))(*papsz_options) # Rasterize this geometry rasterize_geometries( rasterized.ptr, nr_of_bands_to_rasterize, band_indices_to_rasterize, nr_of_geometries, geometry_list, None, None, # Transform parameters burn_value, papsz_options, None, None # Progress functions ) return rasterized
def test_transform_dim(self): "Testing coordinate dimension is the same on transformed geometries." ls_orig = OGRGeometry('LINESTRING(-104.609 38.255)', 4326) ls_trans = OGRGeometry('LINESTRING(992385.4472045 481455.4944650)', 2774) # Different PROJ versions use different transformations, all are # correct as having a 1 meter accuracy. prec = -1 ls_orig.transform(ls_trans.srs) # Making sure the coordinate dimension is still 2D. self.assertEqual(2, ls_orig.coord_dim) self.assertAlmostEqual(ls_trans.x[0], ls_orig.x[0], prec) self.assertAlmostEqual(ls_trans.y[0], ls_orig.y[0], prec)
def get_ogr(value, srid=DEFAULT_PROJ): ogr = None if value: if isinstance(value, OGRGeometry): ogr = value elif isinstance(value, GEOSGeometry): ogr = value.ogr elif isinstance(value, basestring): match = _ewkt_re.match(value) if match: ogr = OGRGeometry(match.group('wkt'), match.group('srid')) else: ogr = OGRGeometry(value) if ogr and srid: ogr.transform(srid) return ogr
def latlon2city(lon,lat): lat = float(lat) lon = float(lon) west = -122.515003 east = -122.355684 north = 37.832365 south = 37.706032 west_coord_1 = 5973058 east_coord_1 = 6022571 north_coord_1 = 2132800 south_coord_1 = 2085080 west_coord = 5979762.107179 east_coord = 6024890.063509 north_coord = 2130875.573550 south_coord = 2085798.824452 west_delta = west_coord - west_coord_1 east_delta = east_coord - east_coord_1 north_delta = north_coord - north_coord_1 south_delta = south_coord - south_coord_1 lon_range = abs(abs(west) - abs(east)) lat_range = north - south ew_range = (east_coord - west_coord) ns_range = (north_coord - south_coord) lat_pct = (north - lat)/lat_range lon_pct = (abs(west) - abs(lon))/lon_range #x = west_coord + (lon_pct * ew_range) #y = south_coord + (lat_pct * ns_range) x = west_coord + (lon_pct * ew_range) y = north_coord - (lat_pct * ns_range) point = "POINT("+str(lon)+" "+str(lat)+")" geom = OGRGeometry(point) geom.transform(ct) res = geom.ewkt r = re.compile('([0-9\.]+)') (x,y) = r.findall(res) return((x,y)) return((float(x),float(y)))
def pixel_value_from_point(raster, point, band=0): """ Returns the pixel value for the coordinate of the input point from selected band. The input can be a point or tuple, if its a tuple it is assumed to be coordinates in the reference system of the raster. """ if isinstance(point, (tuple, list)): point = OGRGeometry('POINT({0} {1})'.format(*point)) point.srid = raster.srid elif not point.srs or not raster.srs: raise ValueError( 'Both the point and the raster are required to have a reference system specified.' ) elif point.srs != raster.srs: # Ensure the projection of the point is the same as of the raster. point.transform(raster.srid) # Return if point and raster do not touch. bbox = OGRGeometry.from_bbox(raster.extent) bbox.srs = raster.srs if not point.intersects(bbox): return # Compute position of point relative to raster origin. offset = (abs(raster.origin.x - point.coords[0]), abs(raster.origin.y - point.coords[1])) # Compute pixel index value based on offset. offset_index = [ int(offset[0] / abs(raster.scale.x)), int(offset[1] / abs(raster.scale.y)) ] # If the point is exactly on the boundary, the offset_index is rounded to # a pixel index over the edge of the pixel. The index needs to be reduced # by one pixel for those cases. if offset_index[0] == raster.width: offset_index[0] -= 1 if offset_index[1] == raster.height: offset_index[1] -= 1 return raster.bands[band].data(offset=offset_index, size=(1, 1))[0, 0]
def pixel_value_from_point(raster, point, band=0): """ Returns the pixel value for the coordinate of the input point from selected band. The input can be a point or tuple, if its a tuple it is assumed to be coordinates in the reference system of the raster. """ if isinstance(point, (tuple, list)): point = OGRGeometry('POINT({0} {1})'.format(*point)) point.srid = raster.srid elif not point.srs or not raster.srs: raise ValueError('Both the point and the raster are required to have a reference system specified.') elif point.srs != raster.srs: # Ensure the projection of the point is the same as of the raster. point.transform(raster.srid) # Return if point and raster do not touch. bbox = OGRGeometry.from_bbox(raster.extent) bbox.srs = raster.srs if not point.intersects(bbox): return # Compute position of point relative to raster origin. offset = (abs(raster.origin.x - point.coords[0]), abs(raster.origin.y - point.coords[1])) # Compute pixel index value based on offset. offset_index = [int(offset[0] / abs(raster.scale.x)), int(offset[1] / abs(raster.scale.y))] # If the point is exactly on the boundary, the offset_index is rounded to # a pixel index over the edge of the pixel. The index needs to be reduced # by one pixel for those cases. if offset_index[0] == raster.width: offset_index[0] -= 1 if offset_index[1] == raster.height: offset_index[1] -= 1 return raster.bands[band].data(offset=offset_index, size=(1, 1))[0, 0]
def rasterize(geom, rast, burn_value=1): """ Rasterize a geometry. The result is aligned with the input raster. """ # Create in memory target raster rasterized = rast.warp({'name': 'rasterized.MEM', 'driver': 'MEM'}) rasterized.bands[0].data(numpy.zeros(rast.width * rast.height)) # Set zero as nodata rasterized.bands[0].nodata_value = 0 # Make sure geom is an OGR geometry if not isinstance(geom, OGRGeometry): geom = OGRGeometry(geom.ewkt) geom.transform(rast.srs) # Set rasterization parameters nr_of_bands_to_rasterize = 1 band_indices_to_rasterize = (c_int * 1)(1) nr_of_geometries = 1 burn_value = (c_double * 1)(burn_value) geometry_list = (c_void_p * 1)(geom.ptr) # Rasterize this geometry rasterize_geometries( rasterized.ptr, nr_of_bands_to_rasterize, band_indices_to_rasterize, nr_of_geometries, geometry_list, None, None, # Transform parameters burn_value, None, None, None # Progress functions ) return rasterized
def test_ogrgeometry_transform_workaround(self): "Testing coordinate dimensions on geometries after transformation." # A bug in GDAL versions prior to 1.7 changes the coordinate # dimension of a geometry after it has been transformed. # This test ensures that the bug workarounds employed within # `OGRGeometry.transform` indeed work. wkt_2d = "MULTILINESTRING ((0 0,1 1,2 2))" wkt_3d = "MULTILINESTRING ((0 0 0,1 1 1,2 2 2))" srid = 4326 # For both the 2D and 3D MultiLineString, ensure _both_ the dimension # of the collection and the component LineString have the expected # coordinate dimension after transform. geom = OGRGeometry(wkt_2d, srid) geom.transform(srid) self.assertEqual(2, geom.coord_dim) self.assertEqual(2, geom[0].coord_dim) self.assertEqual(wkt_2d, geom.wkt) geom = OGRGeometry(wkt_3d, srid) geom.transform(srid) self.assertEqual(3, geom.coord_dim) self.assertEqual(3, geom[0].coord_dim) self.assertEqual(wkt_3d, geom.wkt)
def test18_ogrgeometry_transform_workaround(self): "Testing coordinate dimensions on geometries after transformation." # A bug in GDAL versions prior to 1.7 changes the coordinate # dimension of a geometry after it has been transformed. # This test ensures that the bug workarounds employed within # `OGRGeometry.transform` indeed work. wkt_2d = "MULTILINESTRING ((0 0,1 1,2 2))" wkt_3d = "MULTILINESTRING ((0 0 0,1 1 1,2 2 2))" srid = 4326 # For both the 2D and 3D MultiLineString, ensure _both_ the dimension # of the collection and the component LineString have the expected # coordinate dimension after transform. geom = OGRGeometry(wkt_2d, srid) geom.transform(srid) self.assertEqual(2, geom.coord_dim) self.assertEqual(2, geom[0].coord_dim) self.assertEqual(wkt_2d, geom.wkt) geom = OGRGeometry(wkt_3d, srid) geom.transform(srid) self.assertEqual(3, geom.coord_dim) self.assertEqual(3, geom[0].coord_dim) self.assertEqual(wkt_3d, geom.wkt)
def rasterize(geom, rast, burn_value=1): """ Rasterize a geometry. The result is aligned with the input raster. """ # Create in memory target raster rasterized = rast.warp({'name': 'rasterized.MEM', 'driver': 'MEM'}) rasterized.bands[0].data(numpy.zeros(rast.width * rast.height)) # Set zero as nodata rasterized.bands[0].nodata_value = 0 # Make sure geom is an OGR geometry if not isinstance(geom, OGRGeometry): geom = OGRGeometry(geom.ewkt) geom.transform(rast.srs) # Set rasterization parameters nr_of_bands_to_rasterize = 1 band_indices_to_rasterize = (c_int * 1)(1) nr_of_geometries = 1 burn_value = (c_double * 1)(burn_value) geometry_list = (c_void_p * 1)(geom.ptr) # Rasterize this geometry rasterize_geometries( rasterized.ptr, nr_of_bands_to_rasterize, band_indices_to_rasterize, nr_of_geometries, geometry_list, None, None, # Transform parameters burn_value, None, None, None # Progress functions ) return rasterized
def import_from_shape(upload, start_row=0, max_rows=200000, create_int_style_cols=True): """ a shapeUpload object max_rows - any more than this is ignored centroid - if it's a (multi)polygon, should we also create a geometry_centroid field """ upload.status = 2 #set this right away so it doesn't get reprocessed upload.save() ds = DataSource(upload.shapefile) layer = ds[0] fields = layer.fields num_features = len(layer) #set max # of _style features max_distinct_style_vals = max(min(num_features / 100, 50), 10) print 'there are %d features' % num_features upload.total_rows = num_features if not num_features: print 'no rows, returning' upload.status = 6 upload.save() return rows = [] #get field types field_map = { 'OFTString': 'STRING', 'OFTReal': 'NUMBER', 'OFTInteger': 'NUMBER', 'OFTDate': 'DATETIME' } field_types = [field_map[f.__name__] for f in layer.field_types] field_layers = layer.fields #insert geometry layers first field_layers.insert(0, 'geometry') field_types.insert(0, 'LOCATION') field_layers.insert(1, 'geometry_vertex_count') field_types.insert(1, 'NUMBER') if upload.create_simplify: field_layers.insert(0, 'geometry_simplified') field_types.insert(0, 'LOCATION') field_layers.insert(1, 'geometry_simplified_vertex_count') field_types.insert(1, 'NUMBER') #use sorted dict so we can ensure table has geom columns upfront field_dict = SortedDict(zip(field_layers, field_types)) #set up extra fields if creating int/style cols if create_int_style_cols: int_style_dict = {} for field, field_type in field_dict.items(): if field_type == 'STRING': field_dict[field + '_ft_style'] = 'NUMBER' int_style_dict[field] = {} print field_dict #add some custom import fields field_dict['import_notes'] = 'STRING' print 'FIELD DICT', field_dict print 'starting to process' for i, feat in enumerate(layer): if i > max_rows: continue if start_row and i < start_row: continue upload.rows_processed = i + 1 if not i % ((num_features / 50) or 5): print upload.rows_processed, 'rp' upload.save() upload.save() rd = {} #geom = fromstr(feat.geom.wkt,srid=srid) if layer.srs: try: geom = OGRGeometry(feat.geom.wkt, layer.srs.proj4) geom.transform(4326) except Exception, e: print 'FAIL GEOM' print e, geom = None else: geom = OGRGeometry(feat.geom.wkt) if geom: geom = fromstr(geom.wkt) #create optional centroid for polys if upload.create_centroid and 'oly' in geom.geom_type: field_dict['geometry_pos'] = 'LOCATION' rd['geometry_pos'] = geom.point_on_surface.kml if upload.create_centroid_poly and 'oly' in geom.geom_type: field_dict['geometry_pos_poly_2'] = 'LOCATION' field_dict['geometry_pos_poly_3'] = 'LOCATION' rd['geometry_pos_poly_2'] = geom.point_on_surface.buffer( .0001, 10).kml rd['geometry_pos_poly_3'] = geom.point_on_surface.buffer( .0005, 10).kml #if it's > 1M characters, we need to simplify it for FT simplify_tolerance = .0001 while len(geom.kml) > 1000000: geom = geom.simplify(simplify_tolerance) print 'simplified to %f' % simplify_tolerance rd['import_notes'] = 'simplified to %d DD' % simplify_tolerance simplify_tolerance = simplify_tolerance * 1.5 if not geom.valid: rd['import_notes'] = '<br>Geometry not valid' kml = geom.kml rd['geometry'] = kml rd['geometry_vertex_count'] = geom.num_coords if upload.create_simplify and not 'oint' in geom.geom_type: amt = .002 if 'oly' in geom.geom_type: buffer_geom = geom.buffer(amt) buffer_geom = buffer_geom.buffer(amt * -1) simple_geom = buffer_geom.simplify(amt) else: simple_geom = geom.simplify(amt) rd['geometry_simplified'] = simple_geom.kml rd['geometry_simplified_vertex_count'] = simple_geom.num_coords for f in fields: val = feat.get(f) #make sure we have proper null type for diff fields if val == '<Null>': continue if not val: continue if field_dict[f] == 'DATETIME': val = val.isoformat().split('T')[0] if field_dict[f] == 'STRING' \ and create_int_style_cols \ and field_dict.has_key(f + '_ft_style'): #check to see if we have a number for this yet try: rd[f + '_ft_style'] = int_style_dict[f][val] except: int_style_dict[f][val] = len(int_style_dict[f]) rd[f + '_ft_style'] = int_style_dict[f][val] #however if we have too many distinct vals, let's just not do this anymore if len(int_style_dict[f]) > max_distinct_style_vals: print 'DELETING FD %s' % f del field_dict[f + '_ft_style'] del rd[f + '_ft_style'] #sucks, but now we should just remove all these fields from previous rows for srow in rows: try: del srow[f + '_ft_style'] except: pass #probably this was a null value? rd[f] = val rows.append(rd) #let's process 10k rows at a time.. not keep everything in memory if len(rows) > 10000: uploadRows(upload, field_dict, rows) rows = []
def write_with_ctypes_bindings(self,tmp_name,queryset,geo_field): """ Write a shapefile out to a file from a geoqueryset. Uses GeoDjangos ctypes wrapper to ogr in libgdal. """ # Get the shapefile driver dr = Driver('ESRI Shapefile') # Creating the datasource ds = lgdal.OGR_Dr_CreateDataSource(dr._ptr, tmp_name, None) if ds is None: raise Exception('Could not create file!') # Get the right geometry type number for ogr if hasattr(geo_field,'geom_type'): ogr_type = OGRGeomType(geo_field.geom_type).num else: ogr_type = OGRGeomType(geo_field._geom).num # Set up the native spatial reference of the geometry field using the srid if hasattr(geo_field,'srid'): native_srs = SpatialReference(geo_field.srid) else: native_srs = SpatialReference(geo_field._srid) if self.proj_transform: output_srs = SpatialReference(self.proj_transform) else: output_srs = native_srs # create the layer # this is crashing python26 on osx and ubuntu layer = lgdal.OGR_DS_CreateLayer(ds, 'lyr', output_srs._ptr, ogr_type, None) # Create the fields attributes = self.get_attributes() for field in attributes: fld = lgdal.OGR_Fld_Create(str(field.name), 4) added = lgdal.OGR_L_CreateField(layer, fld, 0) check_err(added) # Getting the Layer feature definition. feature_def = lgdal.OGR_L_GetLayerDefn(layer) # Loop through queryset creating features for item in self.queryset: feat = lgdal.OGR_F_Create(feature_def) # For now, set all fields as strings # TODO: catch model types and convert to ogr fields # http://www.gdal.org/ogr/classOGRFeature.html # OGR_F_SetFieldDouble #OFTReal => FloatField DecimalField # OGR_F_SetFieldInteger #OFTInteger => IntegerField #OGR_F_SetFieldStrin #OFTString => CharField # OGR_F_SetFieldDateTime() #OFTDateTime => DateTimeField #OFTDate => TimeField #OFTDate => DateField for idx,field in enumerate(attributes): value = getattr(item,field.name) try: string_value = str(value) except UnicodeEncodeError, E: # pass for now.... # http://trac.osgeo.org/gdal/ticket/882 string_value = '' lgdal.OGR_F_SetFieldString(feat, idx, string_value) # Transforming & setting the geometry geom = getattr(item,geo_field.name) # if requested we transform the input geometry # to match the shapefiles projection 'to-be' if geom: ogr_geom = OGRGeometry(geom.wkt,output_srs) if self.proj_transform: ct = CoordTransform(native_srs, output_srs) ogr_geom.transform(ct) # create the geometry check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr)) else: # Case where geometry object is not found because of null value for field # effectively looses whole record in shapefile if geometry does not exist pass # creat the feature in the layer. check_err(lgdal.OGR_L_SetFeature(layer, feat))
def write_with_ctypes_bindings(self, tmp_name, queryset, geo_field): """ Scrive un file in un formato geografico da un geoqueryset; questa funzione usa le librerie Python di GeoDjangos. """ # Get the shapefile driver dr = Driver(self.out_format) # Creating the datasource ds = lgdal.OGR_Dr_CreateDataSource(dr._ptr, tmp_name, None) if ds is None: raise Exception('Could not create file!') # Get the right geometry type number for ogr if hasattr(geo_field, 'geom_type'): ogr_type = OGRGeomType(geo_field.geom_type).num else: ogr_type = OGRGeomType(geo_field._geom).num # Set up the native spatial reference of geometry field using the srid if hasattr(geo_field, 'srid'): native_srs = SpatialReference(geo_field.srid) else: native_srs = SpatialReference(geo_field._srid) if self.proj_transform: output_srs = SpatialReference(self.proj_transform) else: output_srs = native_srs # create the layer # this is crashing python26 on osx and ubuntu layer = lgdal.OGR_DS_CreateLayer(ds, 'lyr', output_srs._ptr, ogr_type, None) # Create the fields attributes = self.get_attributes() for field in attributes: fld = lgdal.OGR_Fld_Create(str(field.name), 4) added = lgdal.OGR_L_CreateField(layer, fld, 0) check_err(added) # Getting the Layer feature definition. feature_def = lgdal.OGR_L_GetLayerDefn(layer) # Loop through queryset creating features for item in self.queryset: feat = lgdal.OGR_F_Create(feature_def) # For now, set all fields as strings # TODO: catch model types and convert to ogr fields # http://www.gdal.org/ogr/classOGRFeature.html # OGR_F_SetFieldDouble #OFTReal => FloatField DecimalField # OGR_F_SetFieldInteger #OFTInteger => IntegerField #OGR_F_SetFieldStrin #OFTString => CharField # OGR_F_SetFieldDateTime() #OFTDateTime => DateTimeField #OFTDate => TimeField #OFTDate => DateField for idx, field in enumerate(attributes): value = getattr(item, field.name) try: string_value = str(value) except UnicodeEncodeError, E: # pass for now.... # http://trac.osgeo.org/gdal/ticket/882 string_value = '' lgdal.OGR_F_SetFieldString(feat, idx, string_value) # Transforming & setting the geometry geom = getattr(item, geo_field.name) # if requested we transform the input geometry # to match the shapefiles projection 'to-be' if geom: ogr_geom = OGRGeometry(geom.wkt, output_srs) if self.proj_transform: ct = CoordTransform(native_srs, output_srs) ogr_geom.transform(ct) # create the geometry check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr)) else: # Case where geometry object is not found because of null # value for field effectively looses whole record in shapefile # if geometry does not exist pass # creat the feature in the layer. check_err(lgdal.OGR_L_SetFeature(layer, feat))
# LayerMapping -- A Django Model/OGR Layer Mapping Utility
def write_with_ctypes_bindings(self,tmp_name,queryset,geo_field): """ Write a shapefile out to a file from a geoqueryset. Uses GeoDjangos ctypes wrapper to ogr in libgdal. """ # Get the shapefile driver dr = Driver('ESRI Shapefile') # Creating the datasource ds = lgdal.OGR_Dr_CreateDataSource(dr._ptr, tmp_name, None) if ds is None: raise Exception('Could not create file!') # Get the right geometry type number for ogr if hasattr(geo_field,'geom_type'): ogr_type = OGRGeomType(geo_field.geom_type).num else: ogr_type = OGRGeomType(geo_field._geom).num # Set up the native spatial reference of the geometry field using the srid if hasattr(geo_field,'srid'): native_srs = SpatialReference(geo_field.srid) else: native_srs = SpatialReference(geo_field._srid) if self.proj_transform: output_srs = SpatialReference(self.proj_transform) else: output_srs = native_srs # create the layer # this is crashing python26 on osx and ubuntu layer = lgdal.OGR_DS_CreateLayer(ds, 'lyr', output_srs._ptr, ogr_type, None) # Create the fields attributes = self.get_attributes() for field in attributes: fld = lgdal.OGR_Fld_Create(str(field.name), 4) added = lgdal.OGR_L_CreateField(layer, fld, 0) check_err(added) # Getting the Layer feature definition. feature_def = lgdal.OGR_L_GetLayerDefn(layer) # Loop through queryset creating features for item in self.queryset: feat = lgdal.OGR_F_Create(feature_def) for idx,field in enumerate(attributes): value = getattr(item,field.name) try: string_value = str(value) except UnicodeEncodeError, E: string_value = '' lgdal.OGR_F_SetFieldString(feat, idx, string_value) # Transforming & setting the geometry geom = getattr(item,geo_field.name) # if requested we transform the input geometry # to match the shapefiles projection 'to-be' if geom: ogr_geom = OGRGeometry(geom.wkt,output_srs) if self.proj_transform: ct = CoordTransform(native_srs, output_srs) ogr_geom.transform(ct) # create the geometry check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr)) else: pass # creat the feature in the layer. check_err(lgdal.OGR_L_SetFeature(layer, feat))
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 get_geom(self, list_record): ogrgeom = OGRGeometry('POINT(%s %s)' % (list_record['X_COORD'], list_record['Y_COORD']), srs) ogrgeom.transform(4326) return ogrgeom.geos
def import_from_shape(upload, start_row=0, max_rows=200000, create_int_style_cols=True): """ a shapeUpload object max_rows - any more than this is ignored centroid - if it's a (multi)polygon, should we also create a geometry_centroid field """ upload.status = 2 #set this right away so it doesn't get reprocessed upload.save() ds = DataSource(upload.shapefile) layer = ds[0] fields = layer.fields num_features = len(layer) #set max # of _style features max_distinct_style_vals = max(min(num_features / 100, 50),10) print 'there are %d features' % num_features upload.total_rows = num_features if not num_features: print 'no rows, returning' upload.status = 6 upload.save() return rows = [] #get field types field_map = { 'OFTString':'STRING', 'OFTReal':'NUMBER', 'OFTInteger':'NUMBER', 'OFTDate':'DATETIME' } field_types = [field_map[f.__name__] for f in layer.field_types] field_layers = layer.fields #insert geometry layers first field_layers.insert(0,'geometry') field_types.insert(0,'LOCATION') field_layers.insert(1,'geometry_vertex_count') field_types.insert(1,'NUMBER') if upload.create_simplify: field_layers.insert(0,'geometry_simplified') field_types.insert(0,'LOCATION') field_layers.insert(1,'geometry_simplified_vertex_count') field_types.insert(1,'NUMBER') #use sorted dict so we can ensure table has geom columns upfront field_dict = SortedDict(zip(field_layers, field_types)) #set up extra fields if creating int/style cols if create_int_style_cols: int_style_dict = {} for field,field_type in field_dict.items(): if field_type == 'STRING': field_dict[field + '_ft_style'] = 'NUMBER' int_style_dict[field] = {} print field_dict #add some custom import fields field_dict['import_notes'] = 'STRING' print 'FIELD DICT', field_dict print 'starting to process' for i, feat in enumerate(layer): if i > max_rows: continue if start_row and i < start_row: continue upload.rows_processed = i + 1 if not i % ((num_features / 50) or 5): print upload.rows_processed,'rp' upload.save() upload.save() rd = {} #geom = fromstr(feat.geom.wkt,srid=srid) if layer.srs: try: geom = OGRGeometry(feat.geom.wkt, layer.srs.proj4) geom.transform(4326) except Exception, e: print 'FAIL GEOM' print e, geom = None else: geom = OGRGeometry(feat.geom.wkt) if geom: geom = fromstr(geom.wkt) #create optional centroid for polys if upload.create_centroid and 'oly' in geom.geom_type: field_dict['geometry_pos'] = 'LOCATION' rd['geometry_pos'] = geom.point_on_surface.kml if upload.create_centroid_poly and 'oly' in geom.geom_type: field_dict['geometry_pos_poly_2'] = 'LOCATION' field_dict['geometry_pos_poly_3'] = 'LOCATION' rd['geometry_pos_poly_2'] = geom.point_on_surface.buffer(.0001,10).kml rd['geometry_pos_poly_3'] = geom.point_on_surface.buffer(.0005,10).kml #if it's > 1M characters, we need to simplify it for FT simplify_tolerance = .0001 while len(geom.kml) > 1000000: geom = geom.simplify(simplify_tolerance) print 'simplified to %f' % simplify_tolerance rd['import_notes'] = 'simplified to %d DD' % simplify_tolerance simplify_tolerance = simplify_tolerance * 1.5 if not geom.valid: rd['import_notes'] = '<br>Geometry not valid' kml = geom.kml rd['geometry'] = kml rd['geometry_vertex_count'] = geom.num_coords if upload.create_simplify and not 'oint' in geom.geom_type: amt = .002 if 'oly' in geom.geom_type: buffer_geom = geom.buffer(amt) buffer_geom = buffer_geom.buffer(amt * -1) simple_geom = buffer_geom.simplify(amt) else: simple_geom = geom.simplify(amt) rd['geometry_simplified'] = simple_geom.kml rd['geometry_simplified_vertex_count'] = simple_geom.num_coords for f in fields: val = feat.get(f) #make sure we have proper null type for diff fields if val == '<Null>': continue if not val: continue if field_dict[f] == 'DATETIME': val = val.isoformat().split('T')[0] if field_dict[f] == 'STRING' \ and create_int_style_cols \ and field_dict.has_key(f + '_ft_style'): #check to see if we have a number for this yet try: rd[f + '_ft_style'] = int_style_dict[f][val] except: int_style_dict[f][val] = len(int_style_dict[f]) rd[f + '_ft_style'] = int_style_dict[f][val] #however if we have too many distinct vals, let's just not do this anymore if len(int_style_dict[f]) > max_distinct_style_vals: print 'DELETING FD %s' % f del field_dict[f + '_ft_style'] del rd[f + '_ft_style'] #sucks, but now we should just remove all these fields from previous rows for srow in rows: try:del srow[f + '_ft_style'] except: pass #probably this was a null value? rd[f] = val rows.append(rd) #let's process 10k rows at a time.. not keep everything in memory if len(rows) > 10000: uploadRows(upload, field_dict, rows) rows = []
def get_geom(self, list_record): ogrgeom = OGRGeometry( 'POINT(%s %s)' % (list_record['X_COORD'], list_record['Y_COORD']), srs) ogrgeom.transform(4326) return ogrgeom.geos