Changeset 1666


Ignore:
Timestamp:
Aug 1, 2005, 12:57:53 PM (19 years ago)
Author:
hitchman
Message:

added function decimate_dem

Location:
inundation/ga/storm_surge/pyvolution
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • inundation/ga/storm_surge/pyvolution/data_manager.py

    r1665 r1666  
    23852385
    23862386
     2387def decimate_dem(basename_in, stencil, cellsize_new, basename_out=None,
     2388                 verbose=False):
     2389    """Read Digitial Elevation model from the following NetCDF format (.dem)
     2390
     2391    Example:
     2392
     2393    ncols         3121
     2394    nrows         1800
     2395    xllcorner     722000
     2396    yllcorner     5893000
     2397    cellsize      25
     2398    NODATA_value  -9999
     2399    138.3698 137.4194 136.5062 135.5558 ..........
     2400
     2401    Decimate data to cellsize_new using stencil and write to NetCDF dem format.
     2402    """
     2403
     2404    import os
     2405    from Scientific.IO.NetCDF import NetCDFFile
     2406    from Numeric import Float, zeros, sum, reshape
     2407
     2408    root = basename_in
     2409    inname = root + '.dem'
     2410
     2411    #Open existing netcdf file to read
     2412    infile = NetCDFFile(inname, 'r')
     2413    if verbose: print 'Reading DEM from %s' %inname
     2414
     2415    #Read metadata
     2416    ncols = infile.ncols[0]
     2417    nrows = infile.nrows[0]
     2418    xllcorner = infile.xllcorner[0]
     2419    yllcorner = infile.yllcorner[0]
     2420    cellsize = infile.cellsize[0]
     2421    NODATA_value = infile.NODATA_value[0]
     2422    zone = infile.zone[0]
     2423    false_easting = infile.false_easting[0]
     2424    false_northing = infile.false_northing[0]
     2425    projection = infile.projection
     2426    datum = infile.datum
     2427    units = infile.units
     2428
     2429    dem_elevation = infile.variables['elevation']
     2430
     2431    assert len(dem_elevation) == nrows * ncols, 'elevation data do not match nrows*ncols'
     2432
     2433    #Get output file name
     2434    if basename_out == None:
     2435        outname = root + '_' + repr(cellsize_new) + '.dem'
     2436    else:
     2437        outname = basename_out + '.dem'
     2438
     2439    if verbose: print 'Write decimated NetCDF file to %s' %outname
     2440
     2441    #Determine some dimensions for decimated grid
     2442    (nrows_stencil, ncols_stencil) = stencil.shape
     2443    x_offset = ncols_stencil / 2
     2444    y_offset = nrows_stencil / 2
     2445    cellsize_ratio = cellsize_new / cellsize
     2446    ncols_new = 1 + (ncols - ncols_stencil) / cellsize_ratio
     2447    nrows_new = 1 + (nrows - nrows_stencil) / cellsize_ratio
     2448
     2449    #Open netcdf file for output
     2450    outfile = NetCDFFile(outname, 'w')
     2451
     2452    #Create new file
     2453    outfile.institution = 'Geoscience Australia'
     2454    outfile.description = 'NetCDF DEM format for compact and portable storage ' +\
     2455                           'of spatial point data'
     2456    #Georeferencing
     2457    outfile.zone = zone
     2458    outfile.projection = projection
     2459    outfile.datum = datum
     2460    outfile.units = units
     2461
     2462    outfile.cellsize = cellsize_new
     2463    outfile.NODATA_value = NODATA_value
     2464    outfile.false_easting = false_easting
     2465    outfile.false_northing = false_northing
     2466
     2467    outfile.xllcorner = xllcorner + (x_offset * cellsize)
     2468    outfile.yllcorner = yllcorner + (y_offset * cellsize)
     2469    outfile.ncols = ncols_new
     2470    outfile.nrows = nrows_new
     2471
     2472
     2473    # dimension definition
     2474    outfile.createDimension('number_of_points', nrows_new*ncols_new)
     2475
     2476    # variable definition
     2477    outfile.createVariable('elevation', Float, ('number_of_points',))
     2478
     2479    # Get handle to the variable
     2480    elevation = outfile.variables['elevation']
     2481
     2482    dem_elevation_r = reshape(dem_elevation, (nrows, ncols))
     2483
     2484    #Store data
     2485    global_index = 0
     2486    for i in range(nrows_new):
     2487        if verbose: print 'Processing row %d of %d' %(i, nrows)
     2488        lower_index = global_index
     2489        telev =  zeros(ncols_new, Float)
     2490        local_index = 0
     2491        trow = i * cellsize_ratio
     2492
     2493        for j in range(ncols_new):
     2494            tcol = j * cellsize_ratio
     2495            telev[local_index] = \
     2496             sum(sum(dem_elevation_r[trow:trow+nrows_stencil, tcol:tcol+ncols_stencil] * stencil))
     2497            global_index += 1
     2498            local_index += 1
     2499
     2500        upper_index = global_index
     2501
     2502        elevation[lower_index:upper_index] = telev
     2503
     2504    assert global_index == nrows_new*ncols_new, 'index not equal to number of points'
     2505
     2506    infile.close()
     2507    outfile.close()
     2508
  • inundation/ga/storm_surge/pyvolution/test_data_manager.py

    r1660 r1666  
    18191819
    18201820
     1821    def test_decimate_dem(self):
     1822        """Test decimation of dem file
     1823        """
     1824
     1825        import os
     1826        from Numeric import ones, allclose, Float, arange
     1827        from Scientific.IO.NetCDF import NetCDFFile
     1828
     1829        #Write test dem file
     1830        root = 'decdemtest'
     1831
     1832        filename = root + '.dem'
     1833        fid = NetCDFFile(filename, 'w')
     1834
     1835        fid.institution = 'Geoscience Australia'
     1836        fid.description = 'NetCDF DEM format for compact and portable ' +\
     1837                          'storage of spatial point data'
     1838
     1839        nrows = 15
     1840        ncols = 18
     1841
     1842        fid.ncols = ncols
     1843        fid.nrows = nrows
     1844        fid.xllcorner = 2000.5
     1845        fid.yllcorner = 3000.5
     1846        fid.cellsize = 25
     1847        fid.NODATA_value = -9999
     1848
     1849        fid.zone = 56
     1850        fid.false_easting = 0.0
     1851        fid.false_northing = 0.0
     1852        fid.projection = 'UTM'
     1853        fid.datum = 'WGS84'
     1854        fid.units = 'METERS'
     1855
     1856        fid.createDimension('number_of_points', nrows*ncols)
     1857
     1858        fid.createVariable('elevation', Float, ('number_of_points',))
     1859
     1860        elevation = fid.variables['elevation']
     1861
     1862        elevation[:] = (arange(nrows*ncols))
     1863
     1864        fid.close()
     1865
     1866        #generate the elevation values expected in the decimated file
     1867        ref_elevation = [(  0+  1+  2+ 18+ 19+ 20+ 36+ 37+ 38) / 9.0,
     1868                         (  4+  5+  6+ 22+ 23+ 24+ 40+ 41+ 42) / 9.0,
     1869                         (  8+  9+ 10+ 26+ 27+ 28+ 44+ 45+ 46) / 9.0,
     1870                         ( 12+ 13+ 14+ 30+ 31+ 32+ 48+ 49+ 50) / 9.0,
     1871                         ( 72+ 73+ 74+ 90+ 91+ 92+108+109+110) / 9.0,
     1872                         ( 76+ 77+ 78+ 94+ 95+ 96+112+113+114) / 9.0,
     1873                         ( 80+ 81+ 82+ 98+ 99+100+116+117+118) / 9.0,
     1874                         ( 84+ 85+ 86+102+103+104+120+121+122) / 9.0,
     1875                         (144+145+146+162+163+164+180+181+182) / 9.0,
     1876                         (148+149+150+166+167+168+184+185+186) / 9.0,
     1877                         (152+153+154+170+171+172+188+189+190) / 9.0,
     1878                         (156+157+158+174+175+176+192+193+194) / 9.0,
     1879                         (216+217+218+234+235+236+252+253+254) / 9.0,
     1880                         (220+221+222+238+239+240+256+257+258) / 9.0,
     1881                         (224+225+226+242+243+244+260+261+262) / 9.0,
     1882                         (228+229+230+246+247+248+264+265+266) / 9.0]
     1883
     1884        #generate a stencil for computing the decimated values
     1885        stencil = ones((3,3), Float) / 9.0
     1886
     1887        decimate_dem(root, stencil=stencil, cellsize_new=100)
     1888
     1889        #Open decimated NetCDF file
     1890        fid = NetCDFFile(root + '_100.dem', 'r')
     1891
     1892        # Get decimated elevation
     1893        elevation = fid.variables['elevation']
     1894
     1895        #Check values
     1896        assert allclose(elevation, ref_elevation)
     1897
     1898        #Cleanup
     1899        fid.close()
     1900
     1901        os.remove(root + '.dem')
     1902        os.remove(root + '_100.dem')
     1903
    18211904
    18221905#-------------------------------------------------------------
     
    18241907    #suite = unittest.makeSuite(Test_Data_Manager,'test')
    18251908    #suite = unittest.makeSuite(Test_Data_Manager,'test_dem2pts_bounding_box')
    1826     #suite = unittest.makeSuite(Test_Data_Manager,'test_decimate_dem')
     1909    suite = unittest.makeSuite(Test_Data_Manager,'test_decimate_dem')
    18271910    runner = unittest.TextTestRunner()
    18281911    runner.run(suite)
Note: See TracChangeset for help on using the changeset viewer.