Beispiel #1
0
def load_mrlc(f):
    # pale green background by default
    sfcinfo, surfacelayers = load_raster(f)
    surface = surfacelayers[0]

    # nearest-neighbor upsampling creates chunky pixels - smooth
    #  the edges with a median filter since we're in index space.
    # doing this in the index space keeps sharp edges on the
    # landcover areas, but rounded rather than blocky.
    # compare image resolution to 30m.
    # mrlc is actually 1 arcsecond but 30m is close enough
    # for choosing a filter parameter.
    scale = 30.0 / sfcinfo.grid.meters_per_grid()
    do_median = 1
    if do_median and scale > 2.0:
        # kernel size, an odd number that is near the diameter of an mrlc cell in the image grid
        ksize = 2 * int(scale / 2) + 1
        if ksize > 21:
            # arbitrary limit so we can scale up without blowing up
            ksize = 21
        surface = ndimage.median_filter(surface, size=(ksize,ksize))

    # build the colormap
    cmap = N.zeros((256,3), N.float32)
    for code,info in landcover_info.iteritems():
        cmap[int(code),:] = [int(cc,16)
                             for cc in re.match('#(..)(..)(..)',
                                                info['natural']).groups()]

    # apply the colormap and transform to 0..1
    surface = cmap[surface] / 255.0

    return sfcinfo, surface
Beispiel #2
0
def load_quarters(fns):
    """join four quadrants downsampled from the previous (larger) zoom level.

    this has better locality and requires less warping than extracting from
    the source data repeatedly at different zooms.

    the quadrants have overlap for processing reasons, these need to
    be removed in the middle +

    the only problem is that the margin for each zoom level decreases
    by a factor of two, but we don't want to start with a huge margin at the
    largest zoom.  so at some point we have to go into neighboring quarters.
    """
    (swinfo, sw), (seinfo, se), (nwinfo, nw), (neinfo, ne) = (load_raster(fn) for fn in fns)

    # assume all quarters have the same projection, and compatible geoxf
    # assume that they are symmetrically arranged, so we can just use sw and ne
    _, _, ebound, nbound = swinfo.grid.extent()
    wbound, sbound, _, _ = neinfo.grid.extent()
    cx = (ebound + wbound) / 2
    cy = (nbound + sbound) / 2

    # geoxf and srs are the same as swinfo,
    # but the shape doubles

    # note assumes meters but extent() returns lat/lon

    sy, sx = swinfo.grid.shape

    print "swshape %s" % swinfo.grid.shape

    ixmin, iymin = N.dot(neinfo.grid.inv_s, (cx, cy))
    ixmax, iymax = N.dot(swinfo.grid.inv_s, (cx, cy))

    print "overlapped %s pixels in x" % (ixmin + sx - ixmax)
    print "overlapped %s pixels in y" % (iymin + sy - iymax)

    big = N.vstack(
        N.hstack(sw[:iymax, :ixmax, :], se[:iymax, ixmin:, :]), N.hstack(nw[iymin:, :ixmax, :], ne[iymin:, ixmin:, :])
    )

    print "bigshape %s" % big.shape

    return biginfo, big
Beispiel #3
0
def doit(workdir, grid):
    extract_all(workdir, grid)

    # create surface 
    lcf = '%s/mrlc' % (workdir,)
    if os.path.exists(lcf + '.tif'):
        sfcinfo, surface = load_mrlc(lcf + '.tif')
    else:
        sfcinfo, surface = load_quarters(lcf)
    #print 'SFCI', sfcinfo

    # get the hydrography
    #water = map_nhd(sfcinfo.grid)
    #print 'WWWWS', water.shape
    #glumpy_loop(water)

    demf = '%s/dem' % (workdir,)
    demtif = demf + '.tif'
    if os.path.exists(demtif):
        deminfo, demlayers = load_raster(demtif)
    else:
        deminfo, demlayers = load_quarters(lcf)
    dem = demlayers[0]
    # XXX handle missing values

    #glumpy_loop(surface)

    shaded = reliefshade(deminfo, dem, surface)

    #glumpy_loop(shaded)

    # test of grid tiling
    #for (z,ix,iy) in sfcinfo.grid.itertiles():
    #    print 'TILE %d %d %d' % (z, ix, iy)
    #print 'TIFF_HISTO', N.histogram(img, new=True)

    # if we don't have the DEM in a file (because we just composited it from quadrants),
    #  save it to a file so it can be fed to gdal_contour
    if not os.path.exists(demtif):
        save_raster(deminfo, demtif, dem)

    if not os.path.isdir('%s/contour' % workdir):
        contour_find(demtif, '%s/contour' % workdir)

    if not os.path.isdir('%s/contourft' % (workdir,)):
        ContourTweaker().filter('%s/contour' % (workdir,), '%s/contourft' % (workdir,))

    feats = render_layer(workdir, 'features', grid, ['nhd_flowline', 'nhd_waterbody', 'nhd_area', 'osm_line', 'contours'])

    fills = render_layer(workdir, 'fills', grid, ['contours', 'nhd_flowline', 'nhd_waterbody', 'nhd_area', 'osm_line'])

    labels = render_layer(workdir, 'labels', grid, ['contours', 'nhd_flowline', 'nhd_waterbody', 'nhd_area', 'osm_line'])

    # add contour labels and features
    img = asum(shaded, halo_mask(feats, labels))
    img = asum(img, fills)
    img = asum(img, labels)

    # build half-resolution versions for next zoom level
    #if not os.path.isdir('%s/quarter' % (workdir,)):
    #    os.mkdir('%s/quarter' % (workdir,))
    # XXX doesn't do anything right now
    parentgrid = sfcinfo.grid

    # XXX need to figure these out based on ix%2, iy%2 at some zoom?
    is_east = 0
    is_north = 0

    quadrant = [['sw', 'se'], ['nw', 'ne']][is_north][is_east]

    mrlcdir = request_workdir(parentgrid, 'mrlc')
    build_quarter('%s/%s.tif' % (mrlcdir,quadrant), sfcinfo, surface)

    demdir = request_workdir(parentgrid, 'dem')
    build_quarter('%s/%s.tif' % (demdir,quadrant), deminfo, dem)

    return img