• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Opensource gis development - part 4

Opensource gis development - part 4



Fourth part of the Course "Java Open Source GIS Development - From the building blocks to extending an existing GIS application." held at the University of Potsdam in August 2011

Fourth part of the Course "Java Open Source GIS Development - From the building blocks to extending an existing GIS application." held at the University of Potsdam in August 2011



Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

    Opensource gis development - part 4 Opensource gis development - part 4 Presentation Transcript

    • Java Open Source GIS DevelopmentFrom the building blocks to extending an existing GIS application. Geoinformation Research Group, Department of Geography University of Potsdam August 2011 Part 4: Raster data Tutor: Andrea Antonello ydroloGIS nvironmental ngineeringHydroloGIS S.r.l. - Via Siemens, 19 - 39100 Bolzano www.hydrologis.com
    • Working with Raster dataWhen we talk about raster data in GIS we usually mean digitalelevation/terrain/surface models (DEM/DTM/DSM). DEMs can be used toextract various attributes useful for hydrologic, geomorphologic analyses.From the DEM maps like aspect, flowdirections, curvatures, gradient andextracted network can be calculated.As seen in part 1, a raster is composed of cells and has a value in every cell.A DEM is a raster that has in every cell the elevation value in that position.Handling raster data is on one hand trickier than vector data in GeoTools, theupside is that raster data are so simple, that there is few we need to learn tobe able to process them.
    • Reading a raster mapThe perhaps simplest format for raster data is the ascii grid. An ascii grid is acleartext format that contains: • a header with: • the information of the position of the raster (lower left corner) • the size of the cells • the number used as novalue • the matrix of the dataThe dataset we will use for our tests is the spearfish dataset. Pleasedownload it and unzip it in /home/moovida/giscourse/data.
    • While creating a raster from scratch is not all that easy in GeoTools, readingit from a map file, is quite easy. All the hard work is done by the coveragereaders, as in the following case by the ArcGridReader: ArcGridReader asciiGridReader = new ArcGridReader(file); GridCoverage2D readRaster = asciiGridReader.read(null); // make sure to get the actual data readRaster = readRaster.view(ViewType.GEOPHYSICS); asciiGridReader.dispose();The same concept applies to the writing of raster maps. Once we have theGridCoverage2D that we want to write to file, we just need the appropriatewriter class: ArcGridWriter asciiGridWriter = new ArcGridWriter(file); asciiGridWriter.write(readRaster, null); asciiGridWriter.dispose();This obviously makes it easy to create a tool to transform between formats.
    • To view the newly written geotiff raster map, we first need to read it again: GeoTiffReader geoTiffReader = new GeoTiffReader(file); readRaster = geoTiffReader.read(null); // readRaster = readRaster.view(ViewType.GEOPHYSICS); geoTiffReader.dispose();and pass it with a default style to the map viewer: MapContext map = new MapContext(); map.setTitle("Grid"); map.setCoordinateReferenceSystem(readRaster.getCoordinateReferenceSystem()); StyleFactory sf = CommonFactoryFinder.getStyleFactory(GeoTools.getDefaultHints()); Style style = SLD.wrapSymbolizers(sf.createRasterSymbolizer()); map.addLayer(readRaster, style); JMapFrame.showMap(map);You should see something like:
    • Processing a raster mapProcessing a raster map basically means doing something with the valuescontained in every cell of the map.To do so we need to be able to iterate over the cells. But first we need tohave the concept of image space and world space clear. Assuming we areplaced north of the equator, the following holds: cols grid space 0,0 1 rows 2 value easting northing y x world space
    • In the grid spaceAccessing the raster in the grid/image space is usually easier understood.Most of the times the origin of a raster map is in row = 0 and col = 0 and hasa well defined width and height. Attributes like these can be easily obtainedfrom the GridCoverage2D through the JGrasstools API: RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(readRaster); int rows = regionMap.getRows(); int cols = regionMap.getCols();Everything boils down to an iteration over cols and rows to access every cellthrough the evaluate method. As an example lets calculate the sum of allthe values and the average elevation of the test DEM: double sum = 0; double[] values = new double[1]; for( int c = 0; c < cols; c++ ) { for( int r = 0; r < rows; r++ ) { readRaster.evaluate(new GridCoordinates2D(c, r), values); sum = sum + values[0]; } } double avg = sum / (rows * cols);
    • In the world spaceWhen working in the world space, the only thing that changes, is that wheniterating over the position, the bounds and resolution of the raster has to beconsidered. They can be obtained from the RegionMap object already usedfor the rows and cols: double west = regionMap.getWest(); double east = regionMap.getEast(); double south = regionMap.getSouth(); double north = regionMap.getNorth(); double xres = regionMap.getXres(); double yres = regionMap.getYres();Then, we can move cell by cell through the world coordinates: sum = 0; values = new double[1]; for( double easting = west + xres / 2.0; easting < east; easting = easting + xres ) { for( double northing = south + yres / 2.0; northing < north; northing = northing + yres ) { readRaster.evaluate(new Point2D.Double(easting, northing), values); sum = sum + values[0]; } } avg = sum / (rows * cols);
    • Writing a raster mapIn the previous examples we calculated some simple statistics. Most of thetime the result of a GIS elaboration will be a new raster map that we alsoneed to write to a file.As an exercise, lets bring the spearfish mountains to the sea. This basicallymeans to:1. search the minimum value of the map2. create a new raster into which to put the result3. subtract the minimum to every value and write the result into the new raster4. write the raster to disk
    • Find minimum: double min = Double.POSITIVE_INFINITY; for( int c = 0; c < cols; c++ ) { for( int r = 0; r < rows; r++ ) { readRaster.evaluate(new GridCoordinates2D(c, r), values); min = Math.min(values[0], min); } }Create an empty new raster to put the result in: WritableRaster newWritableRaster = CoverageUtilities.createDoubleWritableRaster(// cols, rows, null, null, null);Note that the raster has been defined only by rows and cols, it lives in theimage space and has no idea were on the world it will be placed.Make mountains crumble to the sea: for( int c = 0; c < cols; c++ ) { for( int r = 0; r < rows; r++ ) { readRaster.evaluate(new GridCoordinates2D(c, r), values); newWritableRaster.setSample(c, r, 0, values[0] - min); } }
    • Give the resulting raster a geographic context: CoordinateReferenceSystem crs = readRaster.getCoordinateReferenceSystem(); GridCoverage2D newRaster = CoverageUtilities.buildCoverage(// "raster", newWritableRaster, regionMap, crs);Check the result by loading the read and processed raster in a viewer andquering the elevation.
    • From rows/cols to easting/northing and backThe transformation between the two domanis can be done directly from theGridGeometry. GridGeometry2D gridGeometry = readRaster.getGridGeometry();Image -> World int row = 100; int col = 50; DirectPosition world = gridGeometry.gridToWorld(new GridCoordinates2D(col, row)); double[] worldArray = world.getCoordinate(); Coordinate worldCoord = new Coordinate(worldArray[0], worldArray[1]);World -> Image double easting = 591825.0; double northing = 4924635.0; GridCoordinates2D grid = gridGeometry.worldToGrid(new DirectPosition2D(easting, northing)); col = grid.x; row = grid.y;
    • Exercises • reclassify the spearfish elevation map to have • nv: min - 1200.0 • 1: 1200.0 - 1500.0 • 2: 1500.0 - 1800.0 • 3: 1800.0 - max • create a map that contains only the values between 1200.0 and 1400.0Advanced exercises with mixed raster/vector flavour: • create the profile of the raster, based on a horizontal LineString that passes through the middle of the map • create a raster map that has the spearfish elevation values only inside a rectangle that is given by the original raster bounding box shrinked by a quarter on each side
    • This work is released under Creative Commons Attribution ShareAlike (CC-BY-SA)Much of the knowledge needed to create this training material hasbeen produced by the sparkling knights of the GeoTools, JTS anduDig community. Another essential source has been the Wikipediacommunity effort.Particular thanks go to those friends that directly or indirectly helpedout in the creation and review of this developers handbook: JodyGarnett from the uDig/GeoTools community and the TANTO team.This tutorial was written with the support of the GeoinformationResearch Group of the University of Potsdam and HydroloGIS.