Package org.locationtech.udig.style.sld.editor.raster

Source Code of org.locationtech.udig.style.sld.editor.raster.PredefinedColorRules$PredefinedColorRule

/*
* uDig - User Friendly Desktop Internet GIS client
* (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.sld.editor.raster;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.locationtech.udig.style.sld.SLDPlugin;

import org.apache.commons.io.FilenameUtils;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.geotools.filter.expression.ExpressionBuilder;
import org.geotools.styling.ColorMap;
import org.geotools.styling.ColorMapEntryImpl;
import org.geotools.styling.ColorMapImpl;
import org.opengis.coverage.grid.GridCoverageReader;
import org.opengis.filter.expression.Expression;
import org.osgi.framework.Bundle;

/**
* The class reading default colortables from disk.
*
* @author Andrea Antonello (www.hydrologis.com)
*
*/
public class PredefinedColorRules {

  /**
   * The rainbow colormap is the only one that has to exist.
   */
  public final static String[][] rainbow = new String[][] { //
  { "255", "255", "0" }, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      { "0", "255", "0" }, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      { "0", "255", "255" }, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      { "0", "0", "255" }, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      { "255", "0", "255" }, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      { "255", "0", "0" } }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

  /**
   * The {@link HashMap map} holding all predefined color rules.
   */
  private List<PredefinedColorRule> colorRules = new ArrayList<PredefinedColorRule>();

  private Double dataMin = null;
  private Double dataMax = null;
  private GridCoverageReader reader = null;
  private double[] noDataValues = null;

  Job minMaxJob = new Job("ComputeMinMax") { //$NON-NLS-1$
    @Override
    protected IStatus run(IProgressMonitor monitor) {
      try {
        double[] noData = noDataValues;
        if (noData == null) {
          noData = new double[] { -9999.0 };
        }
        double[] minmax = (new ClassificationEngine()).computeMinMax(
            noData, reader, ClassificationEngine.WARN_VALUE / 2);
        if (minmax != null) {
          setDataMinMax(minmax[0], minmax[1]);
        }
      } catch (Exception e) {
        SLDPlugin.log(e.getMessage(), e);
      }

      return Status.OK_STATUS;
    }
  };

  public PredefinedColorRules(GridCoverageReader reader, double[] noData) {
    this.reader = reader;
    this.noDataValues = noData;

  }

  public void dispose(){
    colorRules.clear();
    try {
      reader.dispose();
    } catch (IOException e) {
      SLDPlugin.log(e.getMessage(), e);
    }
  }
  private void setDataMinMax(Double min, Double max) {
    this.dataMax = max;
    this.dataMin = min;
    colorRules.clear();
  }

  public List<PredefinedColorRule> getPredefinedSets() {
    if (colorRules == null || colorRules.size() == 0) {
      readColorRules();
    }
    return colorRules;
  }

  public void clear() {
    colorRules.clear();
  }
 
  public PredefinedColorRule getPredefinedRule(String name){
    for (PredefinedColorRule r: getPredefinedSets()){
      if (r.getName().equals(name)){
        return r;
      }
    }
    return null;
  }

  /**
   * Reads and returns the {@link HashMap map} holding all predefined color
   * rules.
   *
   * <p>
   * The map has the name of the colortable as key and and array of Strings as
   * value, representing the colors and values of the colortable.<br>
   * The array can be of two types:<br>
   * <ul>
   * <li>
   * 3 values per row (r, g, b): in that case the colortable will be
   * interpolated over a supplied range and be kept continuos between the
   * values. On example is the elevation map.</li>
   * <li>
   * 8 values per row (v1, r1, g1, b1, v2, r2, g2, b2): in that case the
   * values of every step is defined and the color rules are used as they
   * come. One example is the corine landcover map, that has to be consistent
   * with the given values and colors.</li>
   * </ul>
   * </p>
   *
   * @param doReset
   *            if true the folder of colortables is reread.
   * @return the map of colortables.
   */
  private void readColorRules() {
    colorRules.clear();
    /*
     * read the default colortables from the plugin folder
     */
    try {
      // create the rainbow colortable, which has to exist
      colorRules.add(new PredefinedColorRule("rainbow", rainbow)); //$NON-NLS-1$

      File colorTablesFolder = null;
      Bundle bundle = Platform.getBundle("org.locationtech.udig.style.advanced"); //$NON-NLS-1$
      if (bundle != null) {
        URL queriesUrl = bundle.getResource("colortables"); //$NON-NLS-1$
        String colorTablesFolderPath = FileLocator
            .toFileURL(queriesUrl).getPath();
        colorTablesFolder = new File(colorTablesFolderPath);
      } else {
        File baseFolder = new File(".."); //$NON-NLS-1$
        File[] listFiles = baseFolder.listFiles();

        for (File folder : listFiles) {
          String name = folder.getName().toLowerCase();
          if (name.startsWith("eu.hydrologis.jgrass.libs") && !name.contains("external") && !name.contains("scripting")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            colorTablesFolder = new File(folder, "colortables"); //$NON-NLS-1$
          }
        }

      }
      if (colorTablesFolder != null && colorTablesFolder.exists()) {
        File[] files = colorTablesFolder.listFiles();
        for (File file : files) {
          String name = file.getName();
          if (name.toLowerCase().endsWith(".clr")) { //$NON-NLS-1$
            BufferedReader bR = new BufferedReader(new FileReader(
                file));
            List<String[]> lines = new ArrayList<String[]>();
            String line = null;
            int cols = 0;
            while ((line = bR.readLine()) != null) {
              if (line.startsWith("#")) { //$NON-NLS-1$
                continue;
              }
              String[] lineSplit = line.trim().split("\\s+"); //$NON-NLS-1$
              cols = lineSplit.length;
              lines.add(lineSplit);
            }
            bR.close();
            String[][] linesArray = (String[][]) lines
                .toArray(new String[lines.size()][cols]);
            String ruleName = FilenameUtils.getBaseName(file
                .getName());
            ruleName = ruleName.replaceAll("\\_", " "); //$NON-NLS-1$ //$NON-NLS-2$
            colorRules.add(new PredefinedColorRule(ruleName,
                linesArray));
          }
        }

      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private ColorMap parseRulesValuesList(final String[][] colorRules)
      throws IOException {

    ColorMap cm = new ColorMapImpl();
    ExpressionBuilder builder = new ExpressionBuilder();
    if (colorRules[0].length == 3) {
      if (dataMin == null && dataMax == null) {
        minMaxJob.schedule();
        try {
          minMaxJob.join();
        } catch (InterruptedException e) {
          SLDPlugin.log(e.getMessage(), e);
          return null;
        }
      }
      /*
       * the colorrules are without values, so we ramp through them over
       * the range.
       */
      if (dataMin == null) {
        dataMin = -100.0;
      }
      if (dataMax == null) {
        dataMax = 5000.0;
      }

      // calculate the color increment
      float rinc = (float) (dataMax - dataMin)
          / (float) (colorRules.length - 1);

      for (int i = 0; i < colorRules.length - 1; i++) {
        try {
          double to = dataMin + ((i + 1) * rinc);
          Color toColor = new Color(
              Integer.parseInt(colorRules[i + 1][0]),
              Integer.parseInt(colorRules[i + 1][1]),
              Integer.parseInt(colorRules[i + 1][2]));
          if (i == 0) {
            double from = dataMin + (i * rinc);
            Color fromColor = new Color(
                Integer.parseInt(colorRules[i][0]),
                Integer.parseInt(colorRules[i][1]),
                Integer.parseInt(colorRules[i][2]));

            ColorMapEntryImpl cme = new ColorMapEntryImpl();
            cme.setColor((Expression) builder.literal(fromColor)
                .build());
            cme.setQuantity((Expression) builder.literal(from)
                .build());
            cm.addColorMapEntry(cme);
          }
          ColorMapEntryImpl cme = new ColorMapEntryImpl();
          cme.setColor((Expression) builder.literal(toColor).build());
          cme.setQuantity((Expression) builder.literal(to).build());
          cm.addColorMapEntry(cme);

        } catch (NumberFormatException e) {
          SLDPlugin.log(e.getMessage(), e);
          continue;
        }
      }

    } 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."); //$NON-NLS-1$
      }

      for (int i = 0; i < colorRules.length; i++) {
        try {
          double to = Double.parseDouble(colorRules[i][4]);
          Color toColor = new Color(
              Integer.parseInt(colorRules[i][5]),
              Integer.parseInt(colorRules[i][6]),
              Integer.parseInt(colorRules[i][7]));
          if (i == 0) {
            double from = Double.parseDouble(colorRules[i][0]);
            Color fromColor = new Color(
                Integer.parseInt(colorRules[i][1]),
                Integer.parseInt(colorRules[i][2]),
                Integer.parseInt(colorRules[i][3]));

            ColorMapEntryImpl cme = new ColorMapEntryImpl();
            cme.setColor((Expression) builder.literal(fromColor)
                .build());
            cme.setQuantity((Expression) builder.literal(from)
                .build());
            cm.addColorMapEntry(cme);
          }
          ColorMapEntryImpl cme = new ColorMapEntryImpl();
          cme.setColor((Expression) builder.literal(toColor).build());
          cme.setQuantity((Expression) builder.literal(to).build());
          cm.addColorMapEntry(cme);
        } catch (NumberFormatException e) {
          SLDPlugin.log(e.getMessage(), e);
          continue;
        }
      }

    }
    return cm;

  }

  class PredefinedColorRule {
    String name;
    ColorMap colorMap;
    String[][] rules;

    public PredefinedColorRule(String name, String[][] rules) {
      this.name = name;
      this.rules = rules;
    }

    public String getName() {
      return this.name;
    }

    public ColorMap getColorMap() {
      if (colorMap == null) {
        try{
          this.colorMap = PredefinedColorRules.this
              .parseRulesValuesList(rules);
        }catch (Exception ex){
          SLDPlugin.log(ex.getMessage(), ex);
        }
      }
      return this.colorMap;
    }
  }
}
TOP

Related Classes of org.locationtech.udig.style.sld.editor.raster.PredefinedColorRules$PredefinedColorRule

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.