All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotools.gce.grassraster.JGrassMapEnvironment Maven / Gradle / Ivy

/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2006-2011, Open Source Geospatial Foundation (OSGeo)
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.gce.grassraster;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import org.geotools.gce.grassraster.core.color.AttributeTable;
import org.geotools.gce.grassraster.core.color.AttributeTable.CellAttribute;
import org.geotools.gce.grassraster.core.color.JGrassColorTable;
import org.geotools.gce.grassraster.core.color.JlsTokenizer;
import org.geotools.gce.grassraster.metadata.GrassBinaryImageMetadata;
import org.geotools.gce.grassraster.spi.GrassBinaryImageReaderSpi;
import org.geotools.referencing.CRS;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;

/**
 * Represents the structure around a map inside a grass database.
 *
 * 

Given a map file path, all the related files to that map in the GRASS Location/Mapset are * defined. * * @author Andrea Antonello (www.hydrologis.com) * @since 3.0 * @see {@link JGrassConstants} * @see {@link JGrassRegion} */ public class JGrassMapEnvironment { /** A minimum value to be used when no range is available for a map. */ public static double defaultMapMin = 0.0; /** A maximum value to be used when no range is available for a map. */ public static double defaultMapMax = 5000.0; /** The default, always existing Mapset inside a Location. */ private File PERMANENT_MAPSET = null; /** * The Mapset file of the map, through which the {@linkplain JGrassMapEnvironment} was built. */ private File MAPSET = null; /** * The Location file of the map, through which the {@linkplain JGrassMapEnvironment} was built. */ private File LOCATION = null; /** The DEFAULT_WIND file, that keeps the default region informations. */ private File DEFAULT_WIND = null; /** * The PROJ_INFO file, that keeps the projection informations as defined by GRASS through the * g.proj command. */ private File PROJ_INFO = null; /** * The PROJ_WKT file, that keeps the projection informations as defined by JGRASS to be * compatible with geotools. */ private File PROJ_WKT = null; /** The PROJ_WKT file, that keeps the projection units informations as defined by GRASS. */ private File PROJ_UNITS = null; /** * The WIND file, that keeps the current active region information, i.e. the region on which * calculations are executed. */ private File WIND = null; /** The FCELL file, i.e. the file that holds the raw data for floating value maps. */ private File FCELL = null; /** * The CELL file, i.e. the file that holds the raw data for integer value maps. This file also * always exist since it is placeholder also for floating point maps. */ private File CELL = null; /** The CATS file, holding the categories for the map. */ private File CATS = null; /** The HIST file, holding the history of the map. */ private File HIST = null; /** The CELLHD file, holding the native file region information of the file. */ private File CELLHD = null; /** The COLR file, holding the colortable for the map. */ private File COLR = null; /** The CELLMISC_FORMAT file, holding the format and compression information for the map. */ private File CELLMISC_FORMAT = null; /** * The CELLMISC_QUANT file, holding quantization rules for passing from floating points to * integers. */ private File CELLMISC_QUANT = null; /** The CELLMISC_RANGE file, holding the range values for the map. */ private File CELLMISC_RANGE = null; /** The CELLMISC_NULL file, holding bitmap for novalues for the map. */ private File CELLMISC_NULL = null; /** * The {@linkplain JGrassMapEnvironment} that is created in the case a raster map was reclassed. */ private JGrassMapEnvironment RECLASSEDENVIRONMENT = null; /** The name of the map to which the environment refers to. */ private String mapName; private GrassBinaryImageReader coverageReader; private HashMap coverageMetadataMap; /** * Constructs an instance of {@linkplain JGrassMapEnvironment}. * * @param cellFile the absolute path to a grass raster map, through which the environment is * defined. */ public JGrassMapEnvironment(File cellFile) { CELL = cellFile; mapName = CELL.getName(); MAPSET = CELL.getParentFile().getParentFile(); LOCATION = MAPSET.getParentFile(); String permanentFolderPath = LOCATION.getAbsolutePath() + File.separator + JGrassConstants.PERMANENT_MAPSET; PERMANENT_MAPSET = new File(permanentFolderPath); DEFAULT_WIND = new File(permanentFolderPath + File.separator + JGrassConstants.DEFAULT_WIND); PROJ_INFO = new File(permanentFolderPath + File.separator + JGrassConstants.PROJ_INFO); PROJ_WKT = new File(permanentFolderPath + File.separator + JGrassConstants.PROJ_WKT); PROJ_UNITS = new File(permanentFolderPath + File.separator + JGrassConstants.PROJ_UNITS); String mapsetPath = MAPSET.getAbsolutePath(); WIND = new File(mapsetPath + File.separator + JGrassConstants.WIND); FCELL = new File( mapsetPath + File.separator + JGrassConstants.FCELL + File.separator + mapName); CELLHD = new File( mapsetPath + File.separator + JGrassConstants.CELLHD + File.separator + mapName); CATS = new File( mapsetPath + File.separator + JGrassConstants.CATS + File.separator + mapName); COLR = new File( mapsetPath + File.separator + JGrassConstants.COLR + File.separator + mapName); HIST = new File( mapsetPath + File.separator + JGrassConstants.HIST + File.separator + mapName); String cellMiscPath = mapsetPath + File.separator + JGrassConstants.CELL_MISC + File.separator + mapName + File.separator; CELLMISC_NULL = new File(cellMiscPath + JGrassConstants.CELLMISC_NULL); CELLMISC_FORMAT = new File(cellMiscPath + JGrassConstants.CELLMISC_FORMAT); CELLMISC_QUANT = new File(cellMiscPath + JGrassConstants.CELLMISC_QUANT); CELLMISC_RANGE = new File(cellMiscPath + JGrassConstants.CELLMISC_RANGE); } /** * Constructs an instance of {@linkplain JGrassMapEnvironment}. * *

This constructor is a facility method in the case the mapset file and the name of the * GRASS raster map are passed. * * @param mapsetFile file of the mapset path * @param mapName name of the GRASS raster map */ public JGrassMapEnvironment(File mapsetFile, String mapName) { this( new File( mapsetFile.getAbsolutePath() + File.separator + JGrassConstants.CELL + File.separator + mapName)); } /** * Reclasses the environment. * *

In the case a reclassed map was found, this method has to be called, in order to set the * current environment to the new reclassed one. * * @param reclassedMapset the name of the mapset holding the reclassed map * @param reclassedMap the name of the reclassed map */ public void setReclassed(String reclassedMapset, String reclassedMap) { String reclassedCell = LOCATION.getAbsolutePath() + File.separator + reclassedMapset + File.separator + JGrassConstants.CELL + File.separator + reclassedMap; CELL = new File(reclassedCell); mapName = CELL.getName(); MAPSET = CELL.getParentFile().getParentFile(); LOCATION = MAPSET.getParentFile(); String permanentFolderPath = LOCATION.getAbsolutePath() + File.separator + JGrassConstants.PERMANENT_MAPSET; PERMANENT_MAPSET = new File(permanentFolderPath); DEFAULT_WIND = new File(permanentFolderPath + File.separator + JGrassConstants.DEFAULT_WIND); PROJ_INFO = new File(permanentFolderPath + File.separator + JGrassConstants.PROJ_INFO); PROJ_WKT = new File(permanentFolderPath + File.separator + JGrassConstants.PROJ_WKT); PROJ_UNITS = new File(permanentFolderPath + File.separator + JGrassConstants.PROJ_UNITS); String mapsetPath = MAPSET.getAbsolutePath(); WIND = new File(mapsetPath + File.separator + JGrassConstants.WIND); FCELL = new File( mapsetPath + File.separator + JGrassConstants.FCELL + File.separator + mapName); CELLHD = new File( mapsetPath + File.separator + JGrassConstants.CELLHD + File.separator + mapName); CATS = new File( mapsetPath + File.separator + JGrassConstants.CATS + File.separator + mapName); COLR = new File( mapsetPath + File.separator + JGrassConstants.COLR + File.separator + mapName); HIST = new File( mapsetPath + File.separator + JGrassConstants.HIST + File.separator + mapName); String cellMiscPath = mapsetPath + File.separator + JGrassConstants.CELL_MISC + File.separator + mapName + File.separator; CELLMISC_NULL = new File(cellMiscPath + JGrassConstants.CELLMISC_NULL); CELLMISC_FORMAT = new File(cellMiscPath + JGrassConstants.CELLMISC_FORMAT); CELLMISC_QUANT = new File(cellMiscPath + JGrassConstants.CELLMISC_QUANT); CELLMISC_RANGE = new File(cellMiscPath + JGrassConstants.CELLMISC_RANGE); RECLASSEDENVIRONMENT = this; } /** * Getter for mapName. * * @return the map name. */ public String getMapName() { return mapName; } /** * Getter for PERMANENT MAPSET folder. * * @return the PERMANENT MAPSET folder file. */ public File getPERMANENT_MAPSET() { return PERMANENT_MAPSET; } /** * Getter for MAPSET folder. * * @return the MAPSET folder file. */ public File getMAPSET() { return MAPSET; } /** * Getter for LOCATION folder. * * @return the LOCATION file folder. */ public File getLOCATION() { return LOCATION; } /** * Getter for DEFAULT_WIND file. * * @return the DEFAULT_WIND file. */ public File getDEFAULT_WIND() { return DEFAULT_WIND; } /** * Getter for PROJ_INFO file. * * @return the PROJ_INFO file. */ public File getPROJ_INFO() { return PROJ_INFO; } /** * Getter for PROJ_WKT file. * * @return the PROJ_WKT file. */ public File getPROJ_WKT() { return PROJ_WKT; } /** * Getter for PROJ_UNITS file. * * @return the PROJ_UNITS file. */ public File getPROJ_UNITS() { return PROJ_UNITS; } /** * Getter for WIND file. * * @return the WIND file. */ public File getWIND() { return WIND; } /** * Getter for FCELL file. * * @return the FCELL file. */ public File getFCELL() { return FCELL; } /** * Getter for FCELL folder. * * @return the FCELL folder file. */ public File getFcellFolder() { return FCELL.getParentFile(); } /** * Getter for CELL file, i.e. the main map file. * * @return the CELL file. */ public File getCELL() { return CELL; } /** * Getter for the main map file. * * @return the main map file. */ public File getMapFile() { return CELL; } /** * Getter for CELL folder. * * @return the CELL folder file. */ public File getCellFolder() { return CELL.getParentFile(); } /** * Getter for CATS file. * * @return the CATS file. */ public File getCATS() { return CATS; } /** * Getter for CATS folder. * * @return the CATS folder file. */ public File getCatsFolder() { return CATS.getParentFile(); } /** * Getter for the history file. * * @return the HIST file. */ public File getHIST() { return HIST; } /** * Getter for CELLHD file. * * @return the CELLHD file. */ public File getCELLHD() { return CELLHD; } /** * Getter for COLR file. * * @return the COLR file. */ public File getCOLR() { return COLR; } /** * Getter for COLR folder. * * @return the COLR folder file. */ public File getColrFolder() { return COLR.getParentFile(); } /** * Getter for CELLMISC_FORMAT file. * * @return the CELLMISC_FORMAT file. */ public File getCELLMISC_FORMAT() { return CELLMISC_FORMAT; } /** * Getter for CELLMISC_QUANT file. * * @return the CELLMISC_QUANT file. */ public File getCELLMISC_QUANT() { return CELLMISC_QUANT; } /** * Getter for CELLMISC_RANGE file. * * @return the CELLMISC_RANGE file. */ public File getCELLMISC_RANGE() { return CELLMISC_RANGE; } /** * Getter for CELLMISC_NULL file. * * @return the CELLMISC_NULL file. */ public File getCELLMISC_NULL() { return CELLMISC_NULL; } /** * Getter for RECLASSEDENVIRONMENT. * * @return the RECLASSEDENVIRONMENT. */ public JGrassMapEnvironment getRECLASSEDENVIRONMENT() { return RECLASSEDENVIRONMENT; } /** * Read the colorrules for the map wrapped by this {@link JGrassMapEnvironment}. * * @param range the range to use for the default colortable, in the case of missing color file. * Can be null. * @return a {@link List} of color rules in string format. */ public List getColorRules(double[] range) throws IOException { if (range == null) { range = new double[] {defaultMapMin, defaultMapMax}; } JGrassColorTable colorTable = new JGrassColorTable(this, range); return colorTable.getColorRules(); } /** * Reads the categories for the map wrapped by this {@link JGrassMapEnvironment}. * *

The categories are returned in a {@link List} of strings that may be of two types:
* *

    *
  • value:categorytext *
  • value1-value2:categorytext *
* * @return the list of categories in text format. */ public List getCategories() throws IOException { List categoriesList = new ArrayList(); /* * File is a standard file where the categories values are stored in * the cats directory. */ BufferedReader rdr = new BufferedReader(new FileReader(getCATS())); try { /* Instantiate attribute table */ AttributeTable attTable = new AttributeTable(); /* Ignore first 4 lines. */ rdr.readLine(); rdr.readLine(); rdr.readLine(); rdr.readLine(); /* Read next n lines */ String line; while ((line = rdr.readLine()) != null) { /* All lines other than '0:no data' are processed */ // if (line.indexOf("0:no data") == -1) { //$NON-NLS-1$ JlsTokenizer tk = new JlsTokenizer(line, ":"); // $NON-NLS-1$ if (tk.countTokens() == 2) { float f = Float.parseFloat(tk.nextToken()); String att = tk.nextToken().trim(); attTable.addAttribute(f, att); } else if (tk.countTokens() == 3) { float f0 = Float.parseFloat(tk.nextToken()); float f1 = Float.parseFloat(tk.nextToken()); String att = tk.nextToken().trim(); attTable.addAttribute(f0, f1, att); } // } } Enumeration categories = attTable.getCategories(); while (categories.hasMoreElements()) { AttributeTable.CellAttribute object = categories.nextElement(); categoriesList.add(object.toString()); } } finally { rdr.close(); } return categoriesList; } /** * Read the {@link JGrassRegion} from the active region file. * * @return the active grass region. */ public JGrassRegion getActiveRegion() throws IOException { JGrassRegion jGrassRegion = new JGrassRegion(getWIND().getAbsolutePath()); return jGrassRegion; } /** * Reads the data range from a color table file, if existing. * * @return the data range or null if no range could be read. */ public double[] getRangeFromColorTable() throws IOException { double[] dataRange = new double[2]; JGrassColorTable colorTable = new JGrassColorTable(this, null); List rules = colorTable.getColorRules(); if (rules.size() == 0) { return null; } for (int i = 0; i < rules.size(); i++) { String rule = rules.get(i); double[] values = new double[2]; JGrassColorTable.parseColorRule(rule, values, null); if (i == 0) { dataRange[0] = values[0]; } if (i == rules.size() - 1) { dataRange[1] = values[1]; } } if (dataRange == null || Double.isNaN(dataRange[0]) || Double.isInfinite(dataRange[0]) || Double.isNaN(dataRange[1]) || Double.isInfinite(dataRange[1])) { return null; } return dataRange; } /** * Reads the data range from the GRASS range file. * * @return the data range or null if the content is infinite or NaN. */ public double[] getRangeFromRangeFile() throws IOException { double[] dataRange = null; /* * first check if there is a range file available */ File rangeFile = getCELLMISC_RANGE(); // if the file exists, read the range. if (rangeFile.exists()) { dataRange = new double[2]; try (InputStream is = new FileInputStream(rangeFile)) { byte[] numbers = new byte[16]; int testread = is.read(numbers); if (testread == 16) { ByteBuffer rangeBuffer = ByteBuffer.wrap(numbers); dataRange[0] = rangeBuffer.getDouble(); dataRange[1] = rangeBuffer.getDouble(); } } } if (dataRange == null || Double.isNaN(dataRange[0]) || Double.isInfinite(dataRange[0]) || Double.isNaN(dataRange[1]) || Double.isInfinite(dataRange[1])) { return null; } return dataRange; } /** * Reads the data range by reading the map. * * @return the data range. */ public double[] getRangeFromMapScan() throws IOException { /* * if the range file doesn't exist, the only way is to scan the whole map. */ GrassCoverageReader coverageReader = new GrassCoverageReader(getCELL()); coverageReader.setParams(PixelInCell.CELL_CENTER, null, false, false, null); coverageReader.read(null); double[] dataRange = coverageReader.getRange(); // write the range to disk try (OutputStream cell_miscRangeStream = new FileOutputStream(getCELLMISC_RANGE())) { cell_miscRangeStream.write(double2bytearray(dataRange[0])); cell_miscRangeStream.write(double2bytearray(dataRange[1])); } return dataRange; } /** * Getter for the legend string. * * @return the legendstring. */ public String getLegendString() throws IOException { checkReader(); String legendString = coverageMetadataMap.get(GrassBinaryImageMetadata.COLOR_RULES_DESCRIPTOR); return legendString; } /** * Getter for the categories string. * * @return the categories string. */ public String getCategoriesString() throws IOException { checkReader(); String categoriesString = coverageMetadataMap.get(GrassBinaryImageMetadata.CATEGORIES_DESCRIPTOR); return categoriesString; } /** * Read the {@link CoordinateReferenceSystem crs} from the location. * * @return the crs of the location containing the map. */ public CoordinateReferenceSystem getCoordinateReferenceSystem() throws Exception { File projWtkFile = getPROJ_WKT(); if (projWtkFile.exists()) { BufferedReader crsReader = new BufferedReader(new FileReader(projWtkFile)); StringBuffer wtkString = new StringBuffer(); try { String line = null; while ((line = crsReader.readLine()) != null) { wtkString.append(line.trim()); } } finally { crsReader.close(); } CoordinateReferenceSystem readCrs = null; try { readCrs = CRS.parseWKT(wtkString.toString()); } catch (FactoryException e) { throw new IOException(e.getLocalizedMessage()); } return readCrs; } else { return null; } } /** * Read the file region of the map. * * @return the {@link JGrassRegion} of the file. */ public JGrassRegion getFileRegion() throws IOException { // checkReader(); // double fileNorth = Double.parseDouble(coverageMetadataMap // .get(GrassBinaryImageMetadata.NORTH)); // double fileSouth = Double.parseDouble(coverageMetadataMap // .get(GrassBinaryImageMetadata.SOUTH)); // double fileEast = Double // .parseDouble(coverageMetadataMap.get(GrassBinaryImageMetadata.EAST)); // double fileWest = Double // .parseDouble(coverageMetadataMap.get(GrassBinaryImageMetadata.WEST)); // int fileRows = Integer.parseInt(coverageMetadataMap.get(GrassBinaryImageMetadata.NROWS)); // int fileCols = Integer.parseInt(coverageMetadataMap.get(GrassBinaryImageMetadata.NCOLS)); // JGrassRegion fileRegion = new JGrassRegion(fileWest, fileEast, fileSouth, fileNorth, // fileRows, fileCols); File cellhdFile = getCELLHD(); JGrassRegion fileRegion = new JGrassRegion(cellhdFile.getAbsolutePath()); return fileRegion; } private void checkReader() throws IOException { if (coverageReader == null) { coverageReader = new GrassBinaryImageReader(new GrassBinaryImageReaderSpi()); coverageReader.setInput(getCELL()); coverageMetadataMap = ((GrassBinaryImageMetadata) coverageReader.getImageMetadata(0)).toHashMap(); } } private static byte[] double2bytearray(double doubleValue) { long l = Double.doubleToLongBits(doubleValue); byte[] b = new byte[8]; int shift = 64 - 8; for (int k = 0; k < 8; k++, shift -= 8) { b[k] = (byte) (l >>> shift); } return b; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy