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

org.tinfour.svm.properties.SvmFileSpecification Maven / Gradle / Ivy

Go to download

The Simple Volumetric Model (SVM) uses bathymetry to estimate the capacity of lakes and reservoirs

There is a newer version: 2.1.7
Show newest version
/* --------------------------------------------------------------------
 * Copyright (C) 2019  Gary W. Lucas.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ---------------------------------------------------------------------
 */

 /*
 * -----------------------------------------------------------------------
 *
 * Revision History:
 * Date     Name         Description
 * ------   ---------    -------------------------------------------------
 * 04/2019  G. Lucas     Created  
 *
 * Notes:
 *
 * -----------------------------------------------------------------------
 */
package org.tinfour.svm.properties;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.tinfour.gis.utils.IVerticalCoordinateTransform;

/**
 *
 */
public class SvmFileSpecification {

  private static class FixedValueTransform implements IVerticalCoordinateTransform {

    final double value;

    FixedValueTransform(double value) {
      this.value = value;
    }

    @Override
    public String toString() {
      return "Fixed value transform z'=" + value;
    }

    @Override
    public double transform(int recordIndex, double z) {
      return value;
    }
  }

  private static class LinearValueTransform implements IVerticalCoordinateTransform {

    final double scale;
    final double offset;

    LinearValueTransform(double scale, double offset) {
      this.scale = scale;
      this.offset = offset;
    }

    @Override
    public double transform(int recordIndex, double z) {
      return scale * z + offset;
    }

    @Override
    public String toString() {
      return "Linear value transform z'=" + scale + "*z+" + offset;
    }
  }

  final String key;
  final File file;
  final String field;
  final IVerticalCoordinateTransform verticalTransform;

  /**
   * A package-scope constructor used to create specifications by the
   * SvmProperties class. The file may be remapped based on the folder
   * specification. However, if the file specification gives an absolute path,
   * the folder argument will be ignored.
   *
   * @param key the properties key that provided the file specification
   * @param list a list of arguments including the file and any auxiliary
   * fields.
   * @param folder a file reference to a folder containing the file; or a null
   * if no folder reference is to be applied.
   *
   */
  SvmFileSpecification(String key, List list, File folder) {
    if (key == null || key.isEmpty()) {
      throw new IllegalArgumentException("Invalid key");
    }
    if (list.isEmpty()) {
      throw new IllegalArgumentException("Empty specification for " + key);
    }
    this.key = key;
    String path = list.get(0);
    File test = new File(path);
    if (test.isAbsolute() || folder == null) {
      file = test;
    } else {
      file = new File(folder, path);
    }

    // see if the specification supplies a fixed value for the
    // vertical coordinate.  In such a case,  the fixedValue variable
    // will be set to a valid floating point value.  Otherwise,
    // it will remain as NaN indicating that standard processing is required.
    double fixedValue = Double.NaN;
    String s = list.get(1).trim();
    if (s.length() > 0 && !Character.isAlphabetic(s.charAt(0))) {
      // see if it's a numeric giving a fixed value specification
      try {
        fixedValue = Double.parseDouble(s);
      } catch (NumberFormatException dontCare) {
        // it's not a fixed value
        fixedValue = Double.NaN;
      }
    }

    if (Double.isNaN(fixedValue)) {
      // standard processing
      if (list.size() > 1) {
        field = list.get(1);
      } else {
        field = null;
      }
      if (list.size() > 2) {
        verticalTransform = interpretVtrans(list.get(2));
      } else {
        verticalTransform = null;
      }
    } else {
      field = null;
      verticalTransform = new FixedValueTransform(fixedValue);
    }
  }

  private List split(String s) {
    StringBuilder sb = new StringBuilder(128);
    List sList = new ArrayList();
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (Character.isWhitespace(c)) {
        if (sb.length() > 0) {
          sList.add(sb.toString());
          sb.setLength(0);
        }
      } else {
        sb.append(c);
      }
    }
    if (sb.length() > 0) {
      sList.add(sb.toString());
    }
    return sList;
  }

  private IVerticalCoordinateTransform interpretVtrans(String string) {

    List sList = split(string);
    int n = 0;
    double[] d = new double[sList.size()];
    for (String s : sList) {
      try {
        d[n++] = Double.parseDouble(s);
      } catch (NumberFormatException nex) {
        throw new IllegalArgumentException(
                "Invalid entry where numeric expected for "
                + string.trim());
      }
    }
    if (n == 0) {
      return null;
    } else if (n == 1) {
      return new FixedValueTransform(d[0]);
    } else if (n == 2) {
      return new LinearValueTransform(d[0], d[1]);
    } else {
      throw new IllegalArgumentException("Too many specifications for "
              + string.trim());
    }
  }

  /**
   * Get the file reference from the specification
   *
   * @return a valid instance
   */
  public File getFile() {
    return file;
  }

  /**
   * Get the named data field String from the specification (if supplied)
   *
   * @return if supplied, a valid, non-empty string; otherwise, a null.
   */
  public String getField() {
    return field;
  }

  /**
   * Get the vertical coordinate transform from the specification (if supplied)
   *
   * @return if supplied, a valid instance; otherwise, a null.
   */
  public IVerticalCoordinateTransform getVerticalTransform() {
    return verticalTransform;
  }

  @Override
  public String toString() {
    String path = file.getPath();
    return "SvmInput: " + key + "=" + path;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy