Package org.locationtech.udig.style.jgrass.core

Source Code of org.locationtech.udig.style.jgrass.core.GrassColorTable

/*
* JGrass - Free Open Source Java GIS http://www.jgrass.org
* (C) HydroloGIS - www.hydrologis.com
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the HydroloGIS BSD
* License v1.0 (http://udig.refractions.net/files/hsd3-v10.html).
*/
package org.locationtech.udig.style.jgrass.core;

import static java.lang.Integer.parseInt;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.util.ArrayList;

import org.geotools.gce.grassraster.JGrassConstants;
import org.geotools.gce.grassraster.JGrassMapEnvironment;
import org.geotools.gce.grassraster.core.color.JlsTokenizer;

/**
* <p>
* Representation of a GRASS colortable for raster maps
* </p>
*
* @author Andrea Antonello - www.hydrologis.com
* @since 1.1.0
*/
public class GrassColorTable extends ColorTable {

    private File colrFile;

    private int alpha = 255;

    public GrassColorTable( String mapsetPath, String mapName, double[] dataRange ) throws IOException {
        this(mapsetPath + File.separator + JGrassConstants.COLR + File.separator + mapName, dataRange);
    }

    /** Creates a new instance of ColorTable */
    public GrassColorTable( String colorFilePath, double[] dataRange ) throws IOException {
        colrFile = new File(colorFilePath);
        if (colrFile.exists()) {
            BufferedReader rdr = null;
            try {
                rdr = new BufferedReader(new InputStreamReader(new FileInputStream(colrFile)));
                String line = rdr.readLine();
                if (line == null) {
                    colorTableEmpty = true;
                    rdr.close();
                    if (colrFile.delete()) {
                        System.out.println("removed empty color file"); //$NON-NLS-1$
                    }
                    return;
                }
                line = line.trim();
                /*
                 * Read first line and if it starts with # then it is a 3.x color map. If it starts with %
                 * then it it a 4.x/5.x color map
                 */
                if (line == null)
                    return;
                if (line.charAt(0) == '%') {
                    String[] stringValues = line.split("\\s+"); //$NON-NLS-1$
                    if (stringValues.length == 4) {
                        try {
                            alpha = Integer.parseInt(stringValues[3]);
                        } catch (NumberFormatException e) {
                            alpha = 255;
                        }
                    } else {
                        alpha = 255;
                    }
                    /* Read all the color rules */
                    while( (line = rdr.readLine()) != null ) {
                        if (line.charAt(0) != '%')
                            processGrass4ColorRule(line.trim());
                    }
                } else if (line.charAt(0) == '#') {
                    int catNumber = Integer.parseInt(line.substring(1, 2));
                    /* Read second line which is the background colour */
                    processGrass3ColorRule(-1, rdr.readLine());
                    /* Now read the rest of the lines */
                    while( (line = rdr.readLine()) != null ) {
                        processGrass3ColorRule(catNumber++, line.trim());
                    }
                } else {
                    int catNumber = 0;
                    /* Now read the rest of the lines */
                    while( (line = rdr.readLine()) != null ) {
                        processGrass3ColorRule(catNumber++, line.trim());
                    }
                }
            } finally {
                rdr.close();
            }
            colorTableEmpty = false;
            // System.out.println("================================COLORTABLE================================");
            // for (int i=0; i<rules.size(); i++)
            // System.out.println("RULE="+rules.elementAt(i));
            // System.out.println("================================");
        } else {
            colorTableEmpty = true;
        }
    }

    /**
     *
     */
    @SuppressWarnings("nls")
    private void processGrass3ColorRule( int lineNumber, String line ) {
        String r, g, b;

        if (line == null)
            return;
        try {
            JlsTokenizer tk = new JlsTokenizer(line, " ");
            if (lineNumber < 0) {
                if (tk.hasMoreTokens()) {
                    r = g = b = tk.nextToken();
                    if (tk.hasMoreTokens())
                        g = tk.nextToken();
                    if (tk.hasMoreTokens())
                        b = tk.nextToken();
                    if (r.indexOf('.') == -1)
                        setBackgroundColor(new Color(Integer.parseInt(r), Integer.parseInt(g), Integer.parseInt(b)));
                    else
                        setBackgroundColor(new Color(Float.parseFloat(r), Float.parseFloat(g), Float.parseFloat(b)));
                }
            } else {
                r = g = b = tk.nextToken();
                if (tk.hasMoreTokens())
                    g = tk.nextToken();
                if (tk.hasMoreTokens())
                    b = tk.nextToken();
                if (r.indexOf('.') == -1)
                    addColorRule(lineNumber, Integer.parseInt(r), Integer.parseInt(g), Integer.parseInt(b));
                else
                    addColorRule(lineNumber, (int) (Float.parseFloat(r) * 255f), (int) (Float.parseFloat(g) * 255f),
                            (int) (Float.parseFloat(b) * 255));
            }
        } catch (NumberFormatException ex) {
            ex.printStackTrace();
        }
    }

    /**
     *
     */
    @SuppressWarnings("nls")
    private void processGrass4ColorRule( String line ) {
        int r0 = -1, g0 = -1, b0 = -1;
        int r1 = -1, g1 = -1, b1 = -1;
        float cat0 = 0, cat1 = 0;

        if (line == null)
            return;
        // System.out.println(">>"+line);

        try {
            JlsTokenizer tk = new JlsTokenizer(line, " ");
            if (tk.hasMoreTokens()) {
                /* Some lines may have two colors seperated by a space. */
                JlsTokenizer tk1 = new JlsTokenizer(tk.nextToken(), ":");
                cat0 = Float.parseFloat(tk1.nextToken());
                /* The next value(s) describe the color as R:G:B */
                r0 = g0 = b0 = Integer.parseInt(tk1.nextToken());
                if (tk1.hasMoreTokens())
                    g0 = b0 = Integer.parseInt(tk1.nextToken());
                if (tk1.hasMoreTokens())
                    b0 = Integer.parseInt(tk1.nextToken());
                if (tk.hasMoreTokens()) {
                    /* Some lines may have two colors seperated by a space. */
                    tk1 = new JlsTokenizer(tk.nextToken(), ":");
                    cat1 = Float.parseFloat(tk1.nextToken());
                    /* The next value(s) describe the color as R:G:B */
                    r1 = g1 = b1 = Integer.parseInt(tk1.nextToken());
                    if (tk1.hasMoreTokens())
                        g1 = b1 = Integer.parseInt(tk1.nextToken());
                    if (tk1.hasMoreTokens())
                        b1 = Integer.parseInt(tk1.nextToken());
                }
                /* Add colour rule if specified for a range */
                if (r1 == -1) {
                    addColorRule((int) cat0, r0, g0, b0);
                } else {
                    addColorRule(cat0, r0, g0, b0, cat1, r1, g1, b1);
                }
            }
        } catch (NumberFormatException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * create the default color table for a given dataRange for the case in which no hardcoded color
     * table is found
     *
     * @param dataRange the datarange for which the colortable is created
     * @throws IOException
     */
    @SuppressWarnings("nls")
    public void createDefaultColorTable( double[] dataRange ) throws IOException {
        String[][] rainbow = PredefinedColorRules.rainbow;
        ArrayList<String> rules = new ArrayList<String>();

        // calculate the color increment
        float rinc = (float) (dataRange[1] - dataRange[0]) / 5;
        for( int i = 0; i < 4; i++ ) {
            addColorRule((float) (dataRange[0] + (i * rinc)), parseInt(rainbow[i][0]), parseInt(rainbow[i][1]),
                    parseInt(rainbow[i][2]), (float) (dataRange[0] + ((i + 1) * rinc)), parseInt(rainbow[i + 1][0]),
                    parseInt(rainbow[i + 1][1]), parseInt(rainbow[i + 1][2]));

            StringBuffer rule = new StringBuffer();
            rule.append((dataRange[0] + (i * rinc)) + ":");
            rule.append(rainbow[i][0] + ":" + rainbow[i][1] + ":" + rainbow[i][2] + " ");
            rule.append((dataRange[0] + ((i + 1) * rinc)) + ":");
            rule.append(rainbow[i + 1][0] + ":" + rainbow[i + 1][1] + ":" + rainbow[i + 1][2] + " ");
            rules.add(rule.toString());
        }

        addColorRule((float) (dataRange[1] - rinc), parseInt(rainbow[4][0]), parseInt(rainbow[4][1]), parseInt(rainbow[4][2]),
                (float) (dataRange[1]), parseInt(rainbow[5][0]), parseInt(rainbow[5][1]), parseInt(rainbow[5][2]));
        StringBuffer rule = new StringBuffer();
        rule.append((dataRange[1] - rinc) + ":");
        rule.append(rainbow[4][0] + ":" + rainbow[4][1] + ":" + rainbow[4][2] + " ");
        rule.append((dataRange[1]) + ":");
        rule.append(rainbow[5][0] + ":" + rainbow[5][1] + ":" + rainbow[5][2] + " ");
        rules.add(rule.toString());

        if (!colrFile.exists()) {
            BufferedWriter bw = null;
            // check also existence of colr folder, it could be missing
            File colFolder = colrFile.getParentFile();
            if (!colFolder.exists()) {
                if (!colFolder.mkdirs()) {
                    throw new IOException("Could nto create folder: " + colFolder.getAbsolutePath());
                }
            }
            bw = new BufferedWriter(new FileWriter(colrFile));

            String header = "% " + dataRange[0] + "   " + dataRange[1] + "   255";
            bw.write(header + "\n");

            for( String string : rules ) {
                bw.write(string + "\n");
            }

            bw.close();

        }

    }

    /**
     * Sets the colortable from a predefined set of rules as defined in {@link PredefinedColorRules}.
     *
     * @param colrFile the color file to persist to.
     * @param dataRange the datarange or null.
     * @param colorRules the colorrules to apply.
     * @return the string representation of the color table file in GRASS.
     * @throws IOException
     */
    @SuppressWarnings("nls")
    public static String setColorTableFromRules( File colrFile, double[] dataRange, String[][] colorRules ) throws IOException {
        String name = colrFile.getName();
        File mapsetFile = colrFile.getParentFile().getParentFile();
        JGrassMapEnvironment jGrassMapEnvironment = new JGrassMapEnvironment(mapsetFile, name);

        if (colorRules[0].length == 3) {
            /*
             * the colorrules are without values, so we ramp through them
             * over the range.
             */
            if (dataRange == null) {
                // first try to read the range file
                dataRange = jGrassMapEnvironment.getRangeFromRangeFile();

                if (dataRange == null) {
                    // try to guess it from the color file
                    dataRange = jGrassMapEnvironment.getRangeFromColorTable();
                }

                if (dataRange == null) {
                    // something went wrong. read the map and get the range
                    dataRange = jGrassMapEnvironment.getRangeFromMapScan();
                }
            }

            // calculate the color increment
            float rinc = (float) (dataRange[1] - dataRange[0]) / (float) (colorRules.length - 1);

            StringBuffer rule = new StringBuffer();
            rule.append("% " + dataRange[0] + "   " + dataRange[1] + "   255\n");

            for( int i = 0; i < colorRules.length - 2; i++ ) {
                rule.append((dataRange[0] + (i * rinc)) + ":");
                rule.append(colorRules[i][0] + ":" + colorRules[i][1] + ":" + colorRules[i][2] + " ");
                rule.append((dataRange[0] + ((i + 1) * rinc)) + ":");
                rule.append(colorRules[i + 1][0] + ":" + colorRules[i + 1][1] + ":" + colorRules[i + 1][2] + "\n");
            }

            rule.append((dataRange[1] - rinc) + ":");
            rule.append(colorRules[colorRules.length - 2][0] + ":" + colorRules[colorRules.length - 2][1] + ":"
                    + colorRules[colorRules.length - 2][2] + " ");
            rule.append((dataRange[1]) + ":");
            rule.append(colorRules[colorRules.length - 1][0] + ":" + colorRules[colorRules.length - 1][1] + ":"
                    + colorRules[colorRules.length - 1][2] + "\n");

            BufferedWriter bw = new BufferedWriter(new FileWriter(colrFile));
            bw.write(rule.toString());
            bw.close();

            return rule.toString();
        } else {
            /*
             * in this case we have also the values for the range defined
             * and the color rule has to be "v1 r1 g1 b1 v2 r2 g2 b2".
             */
            if (colorRules[0].length != 8) {
                throw new IOException("The colortable can have records of 3 or 8 columns. Check your colortables.");
            }

            StringBuffer rule = new StringBuffer();
            rule.append("% " + colorRules[0][0] + "   " + colorRules[colorRules.length - 1][0] + "   255\n");

            for( int i = 0; i < colorRules.length; i++ ) {
                System.out.println(i);
                rule.append(colorRules[i][0] + ":");
                rule.append(colorRules[i][1] + ":" + colorRules[i][2] + ":" + colorRules[i][3] + " ");
                rule.append(colorRules[i][4] + ":");
                rule.append(colorRules[i][5] + ":" + colorRules[i][6] + ":" + colorRules[i][7] + "\n");
            }

            BufferedWriter bw = new BufferedWriter(new FileWriter(colrFile));
            bw.write(rule.toString());
            bw.close();

            return rule.toString();
        }
    }

    /**
     * Create a default colorrules of the string format of the colorfile of the map.
     *
     * @param dataRange can be null
     * @return the string format of the colorfile of the map
     * @throws Exception
     */
    @SuppressWarnings("nls")
    public String createDefaultColorRulesString( double[] dataRange, boolean writeToDisk ) throws IOException {
        String[][] rainbow = PredefinedColorRules.rainbow;
        if (dataRange == null) {
            dataRange = new double[2];
            // need to read the datarange

            String name = colrFile.getName();
            File mapsetFile = colrFile.getParentFile().getParentFile();
            JGrassMapEnvironment jGrassMapEnvironment = new JGrassMapEnvironment(mapsetFile, name);

            // first try to read the range file
            File rangeFile = jGrassMapEnvironment.getCELLMISC_RANGE();
            boolean fileok = true;
            int testread = 0;
            if (rangeFile.exists()) {
                // the range file exists
                InputStream is = new FileInputStream(rangeFile);
                byte[] numbers = new byte[16];

                testread = is.read(numbers);
                is.close();

                if (testread == 16) {
                    // the range was read right (is this check enough? dont' know...)
                    ByteBuffer rangeBuffer = ByteBuffer.wrap(numbers);

                    dataRange[0] = rangeBuffer.getDouble();
                    dataRange[1] = rangeBuffer.getDouble();
                } else {
                    // something went wrong while reading the range
                    fileok = false;
                }
            } else {
                // range file does not exist
                fileok = false;
            }

            if (!fileok) {
                // something went wrong. set some default value. The user will be able to reset it

                double min = JGrassMapEnvironment.defaultMapMin;
                double max = JGrassMapEnvironment.defaultMapMax;
                dataRange[0] = min;
                dataRange[1] = max;
            }
        }

        // calculate the color increment
        float rinc = (float) (dataRange[1] - dataRange[0]) / 5;

        StringBuffer rule = new StringBuffer();
        rule.append("% " + dataRange[0] + "   " + dataRange[1] + "   255\n");

        for( int i = 0; i < 4; i++ ) {
            rule.append((dataRange[0] + (i * rinc)) + ":");
            rule.append(rainbow[i][0] + ":" + rainbow[i][1] + ":" + rainbow[i][2] + " ");
            rule.append((dataRange[0] + ((i + 1) * rinc)) + ":");
            rule.append(rainbow[i + 1][0] + ":" + rainbow[i + 1][1] + ":" + rainbow[i + 1][2] + "\n");
        }

        rule.append((dataRange[1] - rinc) + ":");
        rule.append(rainbow[4][0] + ":" + rainbow[4][1] + ":" + rainbow[4][2] + " ");
        rule.append((dataRange[1]) + ":");
        rule.append(rainbow[5][0] + ":" + rainbow[5][1] + ":" + rainbow[5][2] + "\n");

        if (writeToDisk) {
            BufferedWriter bw = new BufferedWriter(new FileWriter(colrFile));
            bw.write(rule.toString());
            bw.close();
        }

        return rule.toString();

    }

    public File getColrFile() {
        return colrFile;
    }

    public int getAlpha() {
        return alpha;
    }
}
TOP

Related Classes of org.locationtech.udig.style.jgrass.core.GrassColorTable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.