示例#1
0
def get_transformed_extent(extent, source_projection, target_projection):
    """
    Return extent transformed from source projection to target projection.
    """
    polygon = vectors.Geometry.fromextent(*extent).envelope
    transformation = osr.CoordinateTransformation(
        projections.get_spatial_reference(source_projection),
        projections.get_spatial_reference(target_projection),
    )
    polygon.Transform(transformation)
    return vectors.Geometry(geometry=polygon).extent
示例#2
0
def get_bounds(dataset, projection):
    """
    Return dictionary.

    Dictionary contains the boundaries of the dataset and its first pixel,
    transformed to projection when necessary.

    Transformation is considered unnecessary if the outline changes
    less then 1 % of the pixelsize by transformation.

    The outline is shrunk by 1% of the shortest pixelside, to prevent
    edge intersections.
    """
    transformation = osr.CoordinateTransformation(
        projections.get_spatial_reference(dataset.GetProjection()),
        projections.get_spatial_reference(projection),
    )

    # outline
    raster_org = dataset2outlinepolygon(dataset)
    raster_trf = raster_org.Clone()
    raster_trf.Transform(transformation)

    # pixel
    pixel_org = dataset2pixelpolygon(dataset)
    pixel_trf = pixel_org.Clone()
    pixel_trf.Transform(transformation)

    # verdict
    pixel_trf_size = geometry2envelopesize(pixel_trf)
    diff = max(map(lambda x, y: abs(x - y),
                   raster_trf.GetEnvelope(),
                   raster_org.GetEnvelope()))
    transform = 100 * diff > min(pixel_trf_size)

    # return
    if transform:
        pixel = pixel_trf
        raster = raster_trf.Buffer(-0.01 * min(pixel_trf_size))
    else:
        pixel = pixel_org
        raster = raster_org.Buffer(-0.01 * min(pixel_trf_size))

    return dict(raster=raster, pixel=pixel)
示例#3
0
def get_leafno(geometry):
    """ Return leafno based on geometry. """
    index = ogr.Open(os.path.join(settings.DATA_DIR, 'index'))
    layer = index[0]
    wkb = ogr.CreateGeometryFromWkt(geometry['wkt'])
    ct = osr.CoordinateTransformation(
        projections.get_spatial_reference(geometry['crs']),
        layer.GetSpatialRef(),
    )
    wkb.Transform(ct)
    layer.SetSpatialFilter(wkb)
    return layer.next().GetField(b'BLADNR')
示例#4
0
文件: rasters.py 项目: nens/gislib
    def _dataset(self, level, tile, mode='r'):
        """
        Return a gdal dataset.

        If the file corresponding to level and tile does not exist:
            In (r)ead mode, return mem dataset with nodata
            In (w)rite mode, create and return tif dataset with nodata
        """
        path = os.path.join(self.path, str(level), '{}_{}.tif'.format(*tile))
        if os.path.exists(path):
            # Open existing file with correct gdal access mode
            if mode == 'w':
                access = gdal.GA_Update
                logging.debug('Update {}'.format(path))
            else:
                access = gdal.GA_ReadOnly
            return gdal.Open(str(path), access)

        create_args = [str(path),
                       self.tilesize[0],
                       self.tilesize[1],
                       1,
                       self.datatype,
                       ['TILED=YES',
                        'COMPRESS={}'.format(self.compression)]]

        if mode == 'w':
            # Use gtiff driver
            driver = gdal.GetDriverByName(b'gtiff')
            logging.debug('Create {}'.format(path))

            # Create directory if necessary
            try:
                os.makedirs(os.path.dirname(path))
            except OSError:
                pass  # It existed.
        else:  # mode == 'r'
            # Use mem driver
            driver = gdal.GetDriverByName(b'mem')
            create_args.pop()  # No compression for mem driver

        # Actual create
        dataset = driver.Create(*create_args)
        dataset.SetProjection(
            projections.get_spatial_reference(self.projection).ExportToWkt(),
        )
        dataset.SetGeoTransform(
            self._geometry(level=level, tile=tile).geotransform(),
        )
        band = dataset.GetRasterBand(1)
        band.SetNoDataValue(self.nodatavalue)
        band.Fill(self.nodatavalue)
        return dataset
示例#5
0
文件: stores.py 项目: SiggyF/gislib
    def get_data_for_polygon(self, wkb, crs, size):
        """
        Return a numpy array for the data.
        """
        # Quick out if polygon bounds match polygon
        geometry = vectors.Geometry(wkb)
        envelope = geometry.envelope
        extent = geometry.extent
        nodatavalue = self.manager.no_data_value
        datatype = self.manager.data_type

        # Initialize resulting array to nodatavalue
        dtype = gdal_array.flip_code(datatype)
        array = np.ones(
            (1, size[1], size[0]),
            dtype=dtype,
        ) * dtype(nodatavalue)

        # Create dataset and use it to retrieve data from the store
        array_dict = dict(
            array=array,
            no_data_value=nodatavalue,
            projection=projections.get_wkt(crs),
            geo_transform=rasters.get_geotransform(
                extent=extent, width=size[0], height=size[1],
            ),
        )
        dataset = rasters.dict2dataset(array_dict)        
        self.warpinto(dataset)
        dataset.FlushCache()        

        # Cut when necessary
        if not envelope.Equals(wkb):            
            source = OGR_MEM_DRIVER.CreateDataSource('')
            sr = projections.get_spatial_reference(crs)
            layer = source.CreateLayer(b'', sr)
            defn = layer.GetLayerDefn()
            feature = ogr.Feature(defn)
            feature.SetGeometry(envelope.Difference(wkb))
            layer.CreateFeature(feature)
            gdal.RasterizeLayer(dataset, (1,), layer,
                                burn_values=(nodatavalue,))
            dataset.FlushCache()

        return np.ma.masked_equal(array, nodatavalue, copy=False)
示例#6
0
def get_profile(wktline, src_srs=900913, rastersize=512):
    """
    get raster values for pixels under linestring for Pyramid as
    set in PYRAMID_PATH in config file

    :param wktline: WKT linestring for which profile should be extracted
    :param src_srs: spatial reference system EPSG code
    :param rastersize: size of longest side of raster subset

    :returns: list with pairs of [cumlength, rastervalue]
    """
    # setup pyramid
    pyramid = pyramids.Pyramid(config.PYRAMID_PATH)

    # setup srs
    try:
        srs = projections.get_spatial_reference(src_srs)
    except:
        return "Malformed EPSG code: %s" % (src_srs)

    # convert linestring to geometric object with shapely
    try:
        linestring = wkt.loads(wktline)
    except:
        return "Malformed geometry: %s" % (wktline)
    bounds = linestring.bounds
    points = list(linestring.coords)

    # set longest side to fixed size
    width = bounds[2] - bounds[0]
    length = bounds[3] - bounds[1]
    longside = max(width, length)
    if longside == width:
        xsize = rastersize
        cellsize = width / rastersize
        ysize = int(max(math.ceil(length / cellsize), 1))
    else:
        ysize = rastersize
        cellsize = length / rastersize
        xsize = int(max(math.ceil(width / cellsize), 1))

    # setup dataset in memory based on bounds
    mem_drv = gdal.GetDriverByName('MEM')
    mem_ds = mem_drv.Create(b'', xsize, ysize, 1, GDT_Float32)
    geotransform = (bounds[0], cellsize, 0, bounds[3], 0, -cellsize)
    mem_ds.SetGeoTransform(geotransform)
    mem_ds.SetProjection(srs.ExportToWkt())
    origin = np.array([[mem_ds.GetGeoTransform()[0],
                        mem_ds.GetGeoTransform()[3]]])

    # warp values from pyramid into mem dataset
    pyramid.warpinto(mem_ds)

    # make magicline from linestring vertices
    magicline = MagicLine(points)
    magicline = magicline.pixelize(cellsize)

    # Determine indices for these points
    indices = tuple(np.uint64((magicline.centers - origin) / cellsize,
                              ).transpose())[::-1]
    values = mem_ds.ReadAsArray()[indices]

    # set nodata values to empty
    nodata = mem_ds.GetRasterBand(1).GetNoDataValue()
    values = np.where(values == nodata, None, values)

    # make array with distance from origin (x values for graph)
    distances = map(float, np.arange(len(values)) *
                    linestring.length / len(values))
    profile_data = [list(a) for a in zip(distances, values)]

    mem_ds = None

    return profile_data
示例#7
0
def get_profile(wktline, src_srs=900913, rastersize=512):
    """
    get raster values for pixels under linestring for Pyramid as
    set in PYRAMID_PATH in config file

    :param wktline: WKT linestring for which profile should be extracted
    :param src_srs: spatial reference system EPSG code
    :param rastersize: size of longest side of raster subset

    :returns: list with pairs of [cumlength, rastervalue]
    """
    # setup pyramid
    pyramid = pyramids.Pyramid(config.PYRAMID_PATH)

    # setup srs
    try:
        srs = projections.get_spatial_reference(src_srs)
    except:
        return "Malformed EPSG code: %s" % (src_srs)

    # convert linestring to geometric object with shapely
    try:
        linestring = wkt.loads(wktline)
    except:
        return "Malformed geometry: %s" % (wktline)
    bounds = linestring.bounds
    points = list(linestring.coords)

    # set longest side to fixed size
    width = bounds[2] - bounds[0]
    length = bounds[3] - bounds[1]
    longside = max(width, length)
    if longside == width:
        xsize = rastersize
        cellsize = width / rastersize
        ysize = int(max(math.ceil(length / cellsize), 1))
    else:
        ysize = rastersize
        cellsize = length / rastersize
        xsize = int(max(math.ceil(width / cellsize), 1))

    # setup dataset in memory based on bounds
    mem_drv = gdal.GetDriverByName('MEM')
    mem_ds = mem_drv.Create(b'', xsize, ysize, 1, GDT_Float32)
    geotransform = (bounds[0], cellsize, 0, bounds[3], 0, -cellsize)
    mem_ds.SetGeoTransform(geotransform)
    mem_ds.SetProjection(srs.ExportToWkt())
    origin = np.array(
        [[mem_ds.GetGeoTransform()[0],
          mem_ds.GetGeoTransform()[3]]])

    # warp values from pyramid into mem dataset
    pyramid.warpinto(mem_ds)

    # make magicline from linestring vertices
    magicline = MagicLine(points)
    magicline = magicline.pixelize(cellsize)

    # Determine indices for these points
    indices = tuple(
        np.uint64((magicline.centers - origin) / cellsize, ).transpose())[::-1]
    values = mem_ds.ReadAsArray()[indices]

    # set nodata values to empty
    nodata = mem_ds.GetRasterBand(1).GetNoDataValue()
    values = np.where(values == nodata, None, values)

    # make array with distance from origin (x values for graph)
    distances = map(float,
                    np.arange(len(values)) * linestring.length / len(values))
    profile_data = [list(a) for a in zip(distances, values)]

    mem_ds = None

    return profile_data