예제 #1
0
def getDEMForBoundingBox(config,
                         outputDir,
                         outDEMFilename,
                         bbox,
                         srs='EPSG:4326',
                         overwrite=True):
    """ Extract tile of HYDRO1k digital elevation model (DEM) for bounding box.
    
        @param config Python ConfigParser containing the following sections and options:
            'GDAL/OGR', 'PATH_OF_GDAL_TRANSLATE'
            'HYDRO1k', 'PATH_OF_HYDRO1k_DEM'
        @param outputDir String representing the absolute/relative path of the directory into which output DEM should be written
        @param outDEMFilename String representing the name of the DEM file to be written
        @param bbox Dict representing the lat/long coordinates and spatial reference of the bounding box area
            for which the DEM is to be extracted.  The following keys must be specified: minX, minY, maxX, maxY, srs.
        @param srs String representing the spatial reference of the raster to be returned.
        @param overwrite Boolean value indicating whether or not the file indicated by filename should be overwritten.
            If False and filename exists, IOError exception will be thrown with errno.EEXIST
    
        @return True if DEM tile was created and False if not.
    """
    tileCreated = False
    assert ('minX' in bbox)
    assert ('minY' in bbox)
    assert ('maxX' in bbox)
    assert ('maxY' in bbox)
    assert ('srs' in bbox)

    if not os.path.isdir(outputDir):
        raise IOError(errno.ENOTDIR,
                      "Output directory %s is not a directory" % (outputDir, ))
    if not os.access(outputDir, os.W_OK):
        raise IOError(
            errno.EACCES,
            "Not allowed to write to output directory %s" % (outputDir, ))
    outputDir = os.path.abspath(outputDir)

    outDEMFilepath = os.path.join(outputDir, outDEMFilename)

    if os.path.exists(outDEMFilepath):
        if overwrite:
            deleteGeoTiff(outDEMFilepath)
        else:
            raise IOError(errno.EEXIST,
                          "DEM file %s already exists" % outDEMFilepath)

    hydro1kDEMFilePath = config.get('HYDRO1k', 'PATH_OF_HYDRO1k_DEM')
    if not os.access(hydro1kDEMFilePath, os.R_OK):
        raise IOError(
            errno.EACCES, "Unable to read HYDRO1k DEM located at %s" %
            (hydro1kDEMFilePath, ))

    extractTileFromRaster(config, outputDir, hydro1kDEMFilePath,
                          outDEMFilepath, bbox)
    tileCreated = os.path.exists(outDEMFilepath)

    return tileCreated
예제 #2
0
def deleteSoilRasters(context, manifest):
    """ Delete soil raster maps stored in a project
    
        @param context Context object containing projectDir, the path of the project whose 
        metadata store is to be read from
        @param manifest Dict containing manifest entries.  Files associted with entries
        whose key begins with 'soil_raster_' will be deleted
    """
    for entry in list(manifest.keys()):
        if entry.find('soil_raster_') == 0:
            filePath = os.path.join(context.projectDir, manifest[entry])
            deleteGeoTiff(filePath)
예제 #3
0
def getDEMForBoundingBox(config, outputDir, outDEMFilename, bbox, srs='EPSG:4326', overwrite=True):
    """ Extract tile of HYDRO1k digital elevation model (DEM) for bounding box.
    
        @param config Python ConfigParser containing the following sections and options:
            'GDAL/OGR', 'PATH_OF_GDAL_TRANSLATE'
            'HYDRO1k', 'PATH_OF_HYDRO1k_DEM'
        @param outputDir String representing the absolute/relative path of the directory into which output DEM should be written
        @param outDEMFilename String representing the name of the DEM file to be written
        @param bbox Dict representing the lat/long coordinates and spatial reference of the bounding box area
            for which the DEM is to be extracted.  The following keys must be specified: minX, minY, maxX, maxY, srs.
        @param srs String representing the spatial reference of the raster to be returned.
        @param overwrite Boolean value indicating whether or not the file indicated by filename should be overwritten.
            If False and filename exists, IOError exception will be thrown with errno.EEXIST
    
        @return True if DEM tile was created and False if not.
    """
    tileCreated = False
    assert('minX' in bbox)
    assert('minY' in bbox)
    assert('maxX' in bbox)
    assert('maxY' in bbox)
    assert('srs' in bbox)
    
    if not os.path.isdir(outputDir):
        raise IOError(errno.ENOTDIR, "Output directory %s is not a directory" % (outputDir,))
    if not os.access(outputDir, os.W_OK):
        raise IOError(errno.EACCES, "Not allowed to write to output directory %s" % (outputDir,))
    outputDir = os.path.abspath(outputDir)
    
    outDEMFilepath = os.path.join(outputDir, outDEMFilename)
    
    if os.path.exists(outDEMFilepath):
        if overwrite: 
            deleteGeoTiff(outDEMFilepath)
        else:
            raise IOError(errno.EEXIST, "DEM file %s already exists" % outDEMFilepath)
    
    hydro1kDEMFilePath = config.get('HYDRO1k', 'PATH_OF_HYDRO1k_DEM')
    if not os.access(hydro1kDEMFilePath, os.R_OK):
        raise IOError(errno.EACCES, "Unable to read HYDRO1k DEM located at %s" % (hydro1kDEMFilePath,))
    
    extractTileFromRaster(config, outputDir, hydro1kDEMFilePath, outDEMFilepath, bbox)
    tileCreated = os.path.exists(outDEMFilepath)
    
    return tileCreated
예제 #4
0
def getDEMForBoundingBox(config, outputDir, outFilename, bbox, srs, coverage=DEFAULT_COVERAGE, 
                         resx=None, resy=None, interpolation=DEFAULT_RASTER_RESAMPLE_METHOD, scale=1.0, overwrite=True,
                         verbose=False, outfp=sys.stdout):
    """ Fetch U.S. 1/3 arcsecond DEM data hosted by U.S. Geological Survey using OGC WCS 1.1.1 query.
    
        @note Adapted from code provided by [email protected].
    
        @param config A Python ConfigParser (not currently used)
        @param outputDir String representing the absolute/relative path of the directory into which output raster should be written
        @param outFilename String representing the name of the raster file to be written
        @param bbox Dict representing the lat/long coordinates and spatial reference of the bounding box area
            for which the raster is to be extracted.  The following keys must be specified: minX, minY, maxX, maxY, srs.
        @param srs String representing the spatial reference of the raster to be returned.
        @param coverage String representing the raster source from which to get the raster coverage.  Must be one of: NHDPlus_hydroDEM, NED
        @param resx Float representing the X resolution of the raster(s) to be returned
        @param resy Float representing the Y resolution of the raster(s) to be returned
        @param interpolation String representing interpolation method.  Must be one of RASTER_RESAMPLE_METHOD.  Defaults to DEFAULT_RASTER_RESAMPLE_METHOD.
        @param scale Float representing factor by which to scale elevation data.  Defaults to 1.0.
        @param overwrite Boolean value indicating whether or not the file indicated by filename should be overwritten.
            If False and filename exists, IOError exception will be thrown with errno.EEXIST
        @param verbose Boolean True if detailed output information should be printed to outfp
        @param outfp File-like object to which verbose output should be printed
    
        @raise IOError if outputDir is not a writable directory
        @raise IOError if outFilename already exists and overwrite is False (see above)
        @raise Exception if there was an error making the WCS request
    
        @return Tuple(True if raster data were fetched and False if not, URL of raster fetched)
    """
    dataFetched = False
    assert(coverage in COVERAGES.keys())
    assert('minX' in bbox)
    assert('minY' in bbox)
    assert('maxX' in bbox)
    assert('maxY' in bbox)
    assert('srs' in bbox)
    assert(scale > 0.0)
    
    if not os.path.isdir(outputDir):
        raise IOError(errno.ENOTDIR, "Output directory %s is not a directory" % (outputDir,))
    if not os.access(outputDir, os.W_OK):
        raise IOError(errno.EACCES, "Not allowed to write to output directory %s" % (outputDir,))
    outputDir = os.path.abspath(outputDir)
    
    outFilepath = os.path.join(outputDir, outFilename)
    
    deleteOldfile = False
    if os.path.exists(outFilepath):
        if overwrite: 
            deleteOldfile = True
        else:
            raise IOError(errno.EEXIST, "Raster file %s already exists" % outFilepath)
     
    cov = COVERAGES[coverage]
    grid_origin = cov['grid_origin']
    grid_offset = cov['grid_offset']
    grid_extent = cov['grid_extent']
    s_srs = cov['srs']
    
    if resx is None:
        resx = abs(grid_offset[0])
    if resy is None:
        resy = abs(grid_offset[1])
    t_srs = srs

    # For requests, grid cell centers are used. Need to add half the grid_offset to the grid_origin
    grid_origin_0 = grid_origin[0] + grid_offset[0] / 2.0
    grid_origin_1 = grid_origin[1] + grid_offset[1] / 2.0
    
    p = Proj(init=DEFAULT_SRS)
    (x1, y1) = p(bbox['minX'], bbox['minY'])
    (x2, y2) = p(bbox['maxX'], bbox['maxY'])
    # Pad the width of the bounding box as the Albers transform results in regions of interest
    # that are a bit narrower than I would like, which risks watershed boundaries lying beyond
    # the DEM boundary.
    len_x = x2 - x1
    del_x = len_x * 0.30
    x1 = x1 - del_x
    x2 = x2 + del_x
    bbox_srs = DEFAULT_SRS
 
    # Find the number of grid cells from the grid origin to each edge of the request.
    # Multiply by the grid_offset and add the grid origin to get to the request location.
    xi1 = floor((x1 - grid_origin_0) / grid_offset[0]) * grid_offset[0] + grid_origin_0
    xi2 = ceil((x2 - grid_origin_0) / grid_offset[0]) * grid_offset[0] + grid_origin_0
    yi1 = floor((y1 - grid_origin_1) / grid_offset[1]) * grid_offset[1] + grid_origin_1
    yi2 = ceil((y2 - grid_origin_1) / grid_offset[1]) * grid_offset[1] + grid_origin_1
 
    # coverage, crs, bbox, format. May have the following fields: response_srs, store, resx, resy, interpolation
    url = URL_PROTO.format(coverage=coverage, x1=xi1, y1=yi1, x2=xi2, y2=yi2, bbox_srs=bbox_srs,
                           xoffset=grid_offset[0], yoffset=grid_offset[1])
    #ORG urlFetched = "http://%s%s" % (HOST, url)
    urlFetched = "https://%s%s" % (HOST, url)

    if verbose:
        outfp.write("Acquiring DEM data from {0} ...\n".format(urlFetched))

    # Make initial request, which will return the URL of our clipped coverage
    r = requests.get(urlFetched)
    if r.status_code != 200:
        raise Exception("Error fetching {url}, HTTP status code was {code} {reason}".format(urlFetched,
                                                                                            r.status_code,
                                                                                            r.reason))
    usgs_dem_coverage_handler = USGSDEMCoverageHandler()
    xml.sax.parseString(r.text, usgs_dem_coverage_handler)
    coverage_url = usgs_dem_coverage_handler.coverage_url
    if coverage_url is None:
        raise Exception("Unable to deteremine coverage URL from WCS server response.  Response text was: {0}".format(r.text))
    parsed_coverage_url = urlparse.urlparse(coverage_url)
    
    if verbose:
        outfp.write("Downloading DEM coverage from {0} ...\n".format(coverage_url))
    
    # Download coverage to tempfile
    tmp_dir = tempfile.mkdtemp()
    tmp_cov_name = os.path.join(tmp_dir, 'usgswcsdemtmp')
    tmp_out = open(tmp_cov_name, mode='w+b')
    
    #ORG conn = httplib.HTTPConnection(parsed_coverage_url.netloc)
    conn = httplib.HTTPSConnection(parsed_coverage_url.netloc)
    try:
        conn.request('GET', parsed_coverage_url.path)
        res = conn.getresponse(buffering=True)
    except socket.error as e:
        msg = "Encountered the following error when trying to read raster from %s. Error: %s.  Please try again later or contact the developer." % \
            (urlFetched, str(e) )
        raise Exception(msg)
  
    if 200 != res.status:
        msg = "HTTP response %d %s encountered when querying %s.  Please try again later or contact the developer." % \
            (res.status, res.reason, urlFetched)
        raise Exception(msg) 
     
    contentType = res.getheader('Content-Type')
    
    mimeType = 'image/tiff'
    if contentType.startswith(mimeType):
        # The data returned were of the type expected, read the data
        data = res.read(_BUFF_LEN)
        if data: 
            dataFetched = True
            while data:
                tmp_out.write(data)
                data = res.read(_BUFF_LEN)
            tmp_out.close()
    elif contentType.startswith(CONTENT_TYPE_ERRORS):
        # Read the error and print to stderr
        msg = "The following error was encountered reading WCS coverage URL %s\n\n" %\
            (coverage_url, )
        data = res.read(_BUFF_LEN)
        while data:
            msg += data 
        raise Exception(msg)
    else:
        msg = "Query for raster from URL %s returned content type %s, was expecting type %s. " + \
              " Operation failed." % \
            (coverage_url, contentType, mimeType)
        raise Exception(msg)

    # Rescale raster values if requested        
    if scale != 1.0:
        # Rescale values in raster
        if verbose:
            outfp.write("Rescaling raster values by factor {0}".format(scale))
        rescale_out = os.path.basename("{0}_rescale".format(tmp_cov_name))
        rescaleRaster(config, tmp_dir, tmp_cov_name, rescale_out, scale)
        tmp_cov_name = os.path.join(tmp_dir, rescale_out)
    
    if deleteOldfile:
        deleteGeoTiff(outFilepath)
    
    if verbose:
        msg = "Resampling raster from {s_srs} to {t_srs} " + \
              "with X resolution {resx} and Y resolution {resy}\n"
        outfp.write(msg.format(s_srs=s_srs,
                               t_srs=t_srs,
                               resx=resx,
                               resy=resy))
    
    # Re-sample to target spatial reference and resolution
    resampleRaster(config, outputDir, tmp_cov_name,  outFilename,
                   s_srs, t_srs, resx, resy, interpolation)
    
    # Delete temp directory
    shutil.rmtree(tmp_dir)
        
    return ( dataFetched, urlFetched )
                   trX=demResolutionX, trY=demResolutionY)
    sys.stdout.write('done\n')
else:
    shutil.move(tmpDEMFilepath, demFilepath)

# Write metadata
GenericMetadata.writeStudyAreaEntry(context, 'dem_res_x', demResolutionX)
GenericMetadata.writeStudyAreaEntry(context, 'dem_res_y', demResolutionY)
GenericMetadata.writeStudyAreaEntry(context, 'dem_srs', t_srs)

# Get rows and columns for DEM
(columns, rows) = getDimensionsForRaster(demFilepath)
GenericMetadata.writeStudyAreaEntry(context, 'dem_columns', columns)
GenericMetadata.writeStudyAreaEntry(context, 'dem_rows', rows)

# Write provenance
asset = AssetProvenance(GenericMetadata.MANIFEST_SECTION)
asset.name = 'dem'
asset.dcIdentifier = demFilename
asset.dcSource = demURL
asset.dcTitle = 'Digital Elevation Model'
asset.dcPublisher = 'GeoBrain'
asset.dcDescription = cmdline
asset.writeToMetadata(context)

# Write processing history
GenericMetadata.appendProcessingHistoryItem(context, cmdline)

# Clean-up
deleteGeoTiff(tmpDEMFilepath)
예제 #6
0
def getDEMForBoundingBox(config,
                         outputDir,
                         outFilename,
                         bbox,
                         srs,
                         coverage=DEFAULT_COVERAGE,
                         resx=None,
                         resy=None,
                         interpolation=DEFAULT_RASTER_RESAMPLE_METHOD,
                         scale=1.0,
                         overwrite=True,
                         verbose=False,
                         outfp=sys.stdout):
    """ Fetch U.S. 1/3 arcsecond DEM data hosted by U.S. Geological Survey using OGC WCS 1.1.1 query.
    
        @note Adapted from code provided by [email protected].
    
        @param config A Python ConfigParser (not currently used)
        @param outputDir String representing the absolute/relative path of the directory into which output raster should be written
        @param outFilename String representing the name of the raster file to be written
        @param bbox Dict representing the lat/long coordinates and spatial reference of the bounding box area
            for which the raster is to be extracted.  The following keys must be specified: minX, minY, maxX, maxY, srs.
        @param srs String representing the spatial reference of the raster to be returned.
        @param coverage String representing the raster source from which to get the raster coverage.  Must be one of: NHDPlus_hydroDEM, NED
        @param resx Float representing the X resolution of the raster(s) to be returned
        @param resy Float representing the Y resolution of the raster(s) to be returned
        @param interpolation String representing interpolation method.  Must be one of RASTER_RESAMPLE_METHOD.  Defaults to DEFAULT_RASTER_RESAMPLE_METHOD.
        @param scale Float representing factor by which to scale elevation data.  Defaults to 1.0.
        @param overwrite Boolean value indicating whether or not the file indicated by filename should be overwritten.
            If False and filename exists, IOError exception will be thrown with errno.EEXIST
        @param verbose Boolean True if detailed output information should be printed to outfp
        @param outfp File-like object to which verbose output should be printed
    
        @raise IOError if outputDir is not a writable directory
        @raise IOError if outFilename already exists and overwrite is False (see above)
        @raise Exception if there was an error making the WCS request
    
        @return Tuple(True if raster data were fetched and False if not, URL of raster fetched)
    """
    dataFetched = False
    assert (coverage in list(COVERAGES.keys()))
    assert ('minX' in bbox)
    assert ('minY' in bbox)
    assert ('maxX' in bbox)
    assert ('maxY' in bbox)
    assert ('srs' in bbox)
    assert (scale > 0.0)

    if not os.path.isdir(outputDir):
        raise IOError(errno.ENOTDIR,
                      "Output directory %s is not a directory" % (outputDir, ))
    if not os.access(outputDir, os.W_OK):
        raise IOError(
            errno.EACCES,
            "Not allowed to write to output directory %s" % (outputDir, ))
    outputDir = os.path.abspath(outputDir)

    outFilepath = os.path.join(outputDir, outFilename)

    deleteOldfile = False
    if os.path.exists(outFilepath):
        if overwrite:
            deleteOldfile = True
        else:
            raise IOError(errno.EEXIST,
                          "Raster file %s already exists" % outFilepath)

    cov = COVERAGES[coverage]
    grid_origin = cov['grid_origin']
    grid_offset = cov['grid_offset']
    grid_extent = cov['grid_extent']
    s_srs = cov['srs']

    if resx is None:
        resx = abs(grid_offset[0])
    if resy is None:
        resy = abs(grid_offset[1])
    t_srs = srs

    # For requests, grid cell centers are used. Need to add half the grid_offset to the grid_origin
    grid_origin_0 = grid_origin[0] + grid_offset[0] / 2.0
    grid_origin_1 = grid_origin[1] + grid_offset[1] / 2.0

    p = Proj(init=DEFAULT_SRS)
    (x1, y1) = p(bbox['minX'], bbox['minY'])
    (x2, y2) = p(bbox['maxX'], bbox['maxY'])
    # Pad the width of the bounding box as the Albers transform results in regions of interest
    # that are a bit narrower than I would like, which risks watershed boundaries lying beyond
    # the DEM boundary.
    len_x = x2 - x1
    del_x = len_x * 0.30
    x1 = x1 - del_x
    x2 = x2 + del_x
    bbox_srs = DEFAULT_SRS

    # Find the number of grid cells from the grid origin to each edge of the request.
    # Multiply by the grid_offset and add the grid origin to get to the request location.
    xi1 = floor(
        (x1 - grid_origin_0) / grid_offset[0]) * grid_offset[0] + grid_origin_0
    xi2 = ceil(
        (x2 - grid_origin_0) / grid_offset[0]) * grid_offset[0] + grid_origin_0
    yi1 = floor(
        (y1 - grid_origin_1) / grid_offset[1]) * grid_offset[1] + grid_origin_1
    yi2 = ceil(
        (y2 - grid_origin_1) / grid_offset[1]) * grid_offset[1] + grid_origin_1

    # coverage, crs, bbox, format. May have the following fields: response_srs, store, resx, resy, interpolation
    url = URL_PROTO.format(coverage=coverage,
                           x1=xi1,
                           y1=yi1,
                           x2=xi2,
                           y2=yi2,
                           bbox_srs=bbox_srs,
                           xoffset=grid_offset[0],
                           yoffset=grid_offset[1])
    #ORG urlFetched = "http://%s%s" % (HOST, url)
    urlFetched = "https://%s%s" % (HOST, url)

    if verbose:
        outfp.write("Acquiring DEM data from {0} ...\n".format(urlFetched))

    # Make initial request, which will return the URL of our clipped coverage
    r = requests.get(urlFetched)
    if r.status_code != 200:
        raise Exception(
            "Error fetching {url}, HTTP status code was {code} {reason}".
            format(urlFetched, r.status_code, r.reason))
    usgs_dem_coverage_handler = USGSDEMCoverageHandler()
    xml.sax.parseString(r.text, usgs_dem_coverage_handler)
    coverage_url = usgs_dem_coverage_handler.coverage_url
    if coverage_url is None:
        raise Exception(
            "Unable to deteremine coverage URL from WCS server response.  Response text was: {0}"
            .format(r.text))
    parsed_coverage_url = urllib.parse.urlparse(coverage_url)

    if verbose:
        outfp.write(
            "Downloading DEM coverage from {0} ...\n".format(coverage_url))

    # Download coverage to tempfile
    tmp_dir = tempfile.mkdtemp()
    tmp_cov_name = os.path.join(tmp_dir, 'usgswcsdemtmp')
    tmp_out = open(tmp_cov_name, mode='w+b')

    #ORG conn = httplib.HTTPConnection(parsed_coverage_url.netloc)
    conn = http.client.HTTPSConnection(parsed_coverage_url.netloc)
    try:
        conn.request('GET', parsed_coverage_url.path)
        res = conn.getresponse(buffering=True)
    except socket.error as e:
        msg = "Encountered the following error when trying to read raster from %s. Error: %s.  Please try again later or contact the developer." % \
            (urlFetched, str(e) )
        raise Exception(msg)

    if 200 != res.status:
        msg = "HTTP response %d %s encountered when querying %s.  Please try again later or contact the developer." % \
            (res.status, res.reason, urlFetched)
        raise Exception(msg)

    contentType = res.getheader('Content-Type')

    mimeType = 'image/tiff'
    if contentType.startswith(mimeType):
        # The data returned were of the type expected, read the data
        data = res.read(_BUFF_LEN)
        if data:
            dataFetched = True
            while data:
                tmp_out.write(data)
                data = res.read(_BUFF_LEN)
            tmp_out.close()
    elif contentType.startswith(CONTENT_TYPE_ERRORS):
        # Read the error and print to stderr
        msg = "The following error was encountered reading WCS coverage URL %s\n\n" %\
            (coverage_url, )
        data = res.read(_BUFF_LEN)
        while data:
            msg += data
        raise Exception(msg)
    else:
        msg = "Query for raster from URL %s returned content type %s, was expecting type %s. " + \
              " Operation failed." % \
            (coverage_url, contentType, mimeType)
        raise Exception(msg)

    # Rescale raster values if requested
    if scale != 1.0:
        # Rescale values in raster
        if verbose:
            outfp.write("Rescaling raster values by factor {0}".format(scale))
        rescale_out = os.path.basename("{0}_rescale".format(tmp_cov_name))
        rescaleRaster(config, tmp_dir, tmp_cov_name, rescale_out, scale)
        tmp_cov_name = os.path.join(tmp_dir, rescale_out)

    if deleteOldfile:
        deleteGeoTiff(outFilepath)

    if verbose:
        msg = "Resampling raster from {s_srs} to {t_srs} " + \
              "with X resolution {resx} and Y resolution {resy}\n"
        outfp.write(msg.format(s_srs=s_srs, t_srs=t_srs, resx=resx, resy=resy))

    # Re-sample to target spatial reference and resolution
    resampleRaster(config, outputDir, tmp_cov_name, outFilename, s_srs, t_srs,
                   resx, resy, interpolation)

    # Delete temp directory
    shutil.rmtree(tmp_dir)

    return (dataFetched, urlFetched)
                   trX=demResolutionX, trY=demResolutionY)
    sys.stdout.write('done\n')
else:
    shutil.move(tmpDEMFilepath, demFilepath)

# Write metadata
GenericMetadata.writeStudyAreaEntry(context, 'dem_res_x', demResolutionX)
GenericMetadata.writeStudyAreaEntry(context, 'dem_res_y', demResolutionY)
GenericMetadata.writeStudyAreaEntry(context, 'dem_srs', t_srs)

# Get rows and columns for DEM
(columns, rows) = getDimensionsForRaster(demFilepath)
GenericMetadata.writeStudyAreaEntry(context, 'dem_columns', columns)
GenericMetadata.writeStudyAreaEntry(context, 'dem_rows', rows)

# Write provenance
asset = AssetProvenance(GenericMetadata.MANIFEST_SECTION)
asset.name = 'dem'
asset.dcIdentifier = demFilename
asset.dcSource = demURL
asset.dcTitle = demwcs.COVERAGE_DESC[args.demType]
asset.dcPublisher = 'Geoscience Australia'
asset.dcDescription = cmdline
asset.writeToMetadata(context)

# Write processing history
GenericMetadata.appendProcessingHistoryItem(context, cmdline)

# Clean-up
deleteGeoTiff(tmpDEMFilepath)
예제 #8
0
def getRasterForBoundingBox(config, outputDir, outFilename, host, urlProto, mimeType, bbox, coverage, srs, format, 
                            response_crs=None, store=None, resx=None, resy=None, interpolation=None, overwrite=True):
    """ Fetch a rater from WCS-compliant web service.
        Will write any error returned by query to sys.stderr.
    
        @param config A Python ConfigParser (not currently used)
        @param outputDir String representing the absolute/relative path of the directory into which output raster should be written
        @param outFilename String representing the name of the raster file to be written
        @param host String representing the host (e.g. 'webmap.ornl.gov', 'geobrain.laits.gmu.edu')
        @param urlProto String representing WCS service URL, must contain the following replacement fields:
            coverage, crs, bbox, format. May have the following fields: response_srs, store, resx, resy, interpolation
        @param mimeType String representing the MIME type expected for the response data
        @param bbox Dict representing the lat/long coordinates and spatial reference of the bounding box area
            for which the raster is to be extracted.  The following keys must be specified: minX, minY, maxX, maxY, srs.
        @param coverage String representing the raster source from which to get the raster coverage.  Must be a value listed in SUPPORTED_COVERAGE
        @param srs String representing the spatial reference of the raster to be returned.
        @param format String representing the MIME type of the raster format to be returned.  Must be a value listed in 
            SUPPORTED_FORMATS
        @param response_srs String representing the spatial reference of the raster to be returned.  
            Present for compatibility purposes and is ignored; only srs is used.
        @param store String present for compatibility with WCS4DEM.
        @param resx Float representing the X resolution of the raster(s) to be returned
        @param resy Float representing the Y resolution of the raster(s) to be returned
        @param interpolation String representing interpolation method.
            
        @param overwrite Boolean value indicating whether or not the file indicated by filename should be overwritten.
            If False and filename exists, IOError exception will be thrown with errno.EEXIST
    
        @raise IOError if outputDir is not a writable directory
        @raise IOError if outFilename already exists and overwrite is False (see above)
    
        @return Tuple(True if raster data were fetched and False if not, URL of raster fetched)
    """
    dataFetched = False
    assert(format)
    assert(coverage)
    assert('minX' in bbox)
    assert('minY' in bbox)
    assert('maxX' in bbox)
    assert('maxY' in bbox)
    assert('srs' in bbox)
    
    if not os.path.isdir(outputDir):
        raise IOError(errno.ENOTDIR, "Output directory %s is not a directory" % (outputDir,))
    if not os.access(outputDir, os.W_OK):
        raise IOError(errno.EACCES, "Not allowed to write to output directory %s" % (outputDir,))
    outputDir = os.path.abspath(outputDir)
    
    outFilepath = os.path.join(outputDir, outFilename)
    
    if os.path.exists(outFilepath):
        if overwrite: 
            deleteGeoTiff(outFilepath)
        else:
            raise IOError(errno.EEXIST, "Raster file %s already exists" % outFilepath)
    
    crs = bbox['srs']
    bboxStr = "%f,%f,%f,%f" % (bbox['minX'], bbox['minY'], bbox['maxX'], bbox['maxY'])
 
    # coverage, crs, bbox, format. May have the following fields: response_srs, store, resx, resy, interpolation
    url = urlProto.format(coverage=coverage, crs=crs, bbox=bboxStr, format=format, 
                          response_crs=srs, store=store, resx=resx, resy=resy, interpolation=interpolation)
    urlFetched = "http://%s%s" % (host, url)

    conn = httplib.HTTPConnection(host)
    try:
        conn.request('GET', url)
        res = conn.getresponse(buffering=True)
    except socket.error as e:
        msg = "Encountered the following error when trying to read raster from %s. Error: %s.  Please try again later or contact the developer." % \
            (urlFetched, str(e) )
        sys.stderr.write( textwrap.fill(msg) )
        return ( dataFetched, urlFetched )
  
    if 200 != res.status:
        msg = "HTTP response %d %s encountered when querying %s.  Please try again later or contact the developer." % \
            (res.status, res.reason, urlFetched)
        sys.stderr.write( textwrap.fill(msg) ) 
        return ( dataFetched, urlFetched )
     
    contentType = res.getheader('Content-Type')
    
    if contentType == mimeType:
        # The data returned were of the type expected, read the data
        data = res.read(_BUFF_LEN)
        if data: 
            demOut = open(outFilepath, 'wb')
            dataFetched = True
            while data:
                demOut.write(data)
                data = res.read(_BUFF_LEN)
            demOut.close()
    elif contentType in CONTENT_TYPE_ERRORS:
        # Read the error and print to stderr
        msg = "The following error was encountered reading URL %s\n" %\
            (urlFetched, )
        sys.stderr.write( textwrap.fill(msg) )
        data = res.read(_BUFF_LEN)
        while data: 
            sys.stderr.write(data)
            sys.stderr.flush()
            data = res.read(_BUFF_LEN)
        sys.stderr.write('\n')
    else:
        msg = "Query for raster from URL %s returned content type %s, was expecting type %s.  Operation failed." % \
            (urlFetched, contentType, mimeType)
        sys.stderr.write( textwrap.fill(msg) )
        
    return ( dataFetched, urlFetched )
예제 #9
0
def getRasterForBoundingBox(config,
                            outputDir,
                            outFilename,
                            host,
                            urlProto,
                            mimeType,
                            bbox,
                            coverage,
                            srs,
                            format,
                            response_crs=None,
                            store=None,
                            resx=None,
                            resy=None,
                            interpolation=None,
                            overwrite=True):
    """ Fetch a rater from WCS-compliant web service.
        Will write any error returned by query to sys.stderr.
    
        @param config A Python ConfigParser (not currently used)
        @param outputDir String representing the absolute/relative path of the directory into which output raster should be written
        @param outFilename String representing the name of the raster file to be written
        @param host String representing the host (e.g. 'webmap.ornl.gov', 'geobrain.laits.gmu.edu')
        @param urlProto String representing WCS service URL, must contain the following replacement fields:
            coverage, crs, bbox, format. May have the following fields: response_srs, store, resx, resy, interpolation
        @param mimeType String representing the MIME type expected for the response data
        @param bbox Dict representing the lat/long coordinates and spatial reference of the bounding box area
            for which the raster is to be extracted.  The following keys must be specified: minX, minY, maxX, maxY, srs.
        @param coverage String representing the raster source from which to get the raster coverage.  Must be a value listed in SUPPORTED_COVERAGE
        @param srs String representing the spatial reference of the raster to be returned.
        @param format String representing the MIME type of the raster format to be returned.  Must be a value listed in 
            SUPPORTED_FORMATS
        @param response_srs String representing the spatial reference of the raster to be returned.  
            Present for compatibility purposes and is ignored; only srs is used.
        @param store String present for compatibility with WCS4DEM.
        @param resx Float representing the X resolution of the raster(s) to be returned
        @param resy Float representing the Y resolution of the raster(s) to be returned
        @param interpolation String representing interpolation method.
            
        @param overwrite Boolean value indicating whether or not the file indicated by filename should be overwritten.
            If False and filename exists, IOError exception will be thrown with errno.EEXIST
    
        @raise IOError if outputDir is not a writable directory
        @raise IOError if outFilename already exists and overwrite is False (see above)
    
        @return Tuple(True if raster data were fetched and False if not, URL of raster fetched)
    """
    dataFetched = False
    assert (format)
    assert (coverage)
    assert ('minX' in bbox)
    assert ('minY' in bbox)
    assert ('maxX' in bbox)
    assert ('maxY' in bbox)
    assert ('srs' in bbox)

    if not os.path.isdir(outputDir):
        raise IOError(errno.ENOTDIR,
                      "Output directory %s is not a directory" % (outputDir, ))
    if not os.access(outputDir, os.W_OK):
        raise IOError(
            errno.EACCES,
            "Not allowed to write to output directory %s" % (outputDir, ))
    outputDir = os.path.abspath(outputDir)

    outFilepath = os.path.join(outputDir, outFilename)

    if os.path.exists(outFilepath):
        if overwrite:
            deleteGeoTiff(outFilepath)
        else:
            raise IOError(errno.EEXIST,
                          "Raster file %s already exists" % outFilepath)

    crs = bbox['srs']
    bboxStr = "%f,%f,%f,%f" % (bbox['minX'], bbox['minY'], bbox['maxX'],
                               bbox['maxY'])

    # coverage, crs, bbox, format. May have the following fields: response_srs, store, resx, resy, interpolation
    url = urlProto.format(coverage=coverage,
                          crs=crs,
                          bbox=bboxStr,
                          format=format,
                          response_crs=srs,
                          store=store,
                          resx=resx,
                          resy=resy,
                          interpolation=interpolation)
    urlFetched = "http://%s%s" % (host, url)

    conn = http.client.HTTPConnection(host)
    try:
        conn.request('GET', url)
        res = conn.getresponse(buffering=True)
    except socket.error as e:
        msg = "Encountered the following error when trying to read raster from %s. Error: %s.  Please try again later or contact the developer." % \
            (urlFetched, str(e) )
        sys.stderr.write(textwrap.fill(msg))
        return (dataFetched, urlFetched)

    if 200 != res.status:
        msg = "HTTP response %d %s encountered when querying %s.  Please try again later or contact the developer." % \
            (res.status, res.reason, urlFetched)
        sys.stderr.write(textwrap.fill(msg))
        return (dataFetched, urlFetched)

    contentType = res.getheader('Content-Type')

    if contentType == mimeType:
        # The data returned were of the type expected, read the data
        data = res.read(_BUFF_LEN)
        if data:
            demOut = open(outFilepath, 'wb')
            dataFetched = True
            while data:
                demOut.write(data)
                data = res.read(_BUFF_LEN)
            demOut.close()
    elif contentType in CONTENT_TYPE_ERRORS:
        # Read the error and print to stderr
        msg = "The following error was encountered reading URL %s\n" %\
            (urlFetched, )
        sys.stderr.write(textwrap.fill(msg))
        data = res.read(_BUFF_LEN)
        while data:
            sys.stderr.write(data)
            sys.stderr.flush()
            data = res.read(_BUFF_LEN)
        sys.stderr.write('\n')
    else:
        msg = "Query for raster from URL %s returned content type %s, was expecting type %s.  Operation failed." % \
            (urlFetched, contentType, mimeType)
        sys.stderr.write(textwrap.fill(msg))

    return (dataFetched, urlFetched)