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

org.tinfour.common.VertexMergerGroup Maven / Gradle / Ivy

/*
 * Copyright 2014 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
 * ------   ---------    -------------------------------------------------
 * 03/2014  G. Lucas     Created
 *
 * Notes:
 *
 * -----------------------------------------------------------------------
 */
package org.tinfour.common;

import java.util.ArrayList;
import java.util.List;

/**
 * A synthetic vertex used to handle cases when multiple vertices
 * occupy coincident locations.
 */
public class VertexMergerGroup extends Vertex {

  /**
   * Specifies a rule for determining a z value based on the collection
   * of coincident vertices. The selection of rules may be made to
   * reflect lidar return type (i.e. MaxValue for first-return processing),
   * or classification (min or average value used for ground-classified
   * vertices).
   */
  public enum ResolutionRule {
    /**
     * use the minimum z value
     */
    MinValue,
    /**
     * use the mean z value
     */
    MeanValue,
    /**
     * use the maximum z value
     */
    MaxValue
  };

  List list = new ArrayList<>();

  ResolutionRule rule = ResolutionRule.MeanValue;

  double zRule;

  /**
   * Constructs a coincident vertex using the specified vertex
   * for initialization.
   *
   * @param firstVertex a valid instance
   */
  public VertexMergerGroup(Vertex firstVertex) {
    super(
      firstVertex.x,
      firstVertex.y,
      firstVertex.z,
      firstVertex.getIndex());
    zRule = z;
    status = firstVertex.status;
    list.add(firstVertex);
  }

  /**
   * Add a new vertex to the coincident collection. Recompute z value using
   * current rule.
   *
   * @param v a valid, unique instance
   * @return true if added to collection; otherwise false
   */
  public boolean addVertex(Vertex v) {
    if (v.isConstraintMember()) {
      setConstraintMember(true);
    }
    if(!v.isSynthetic()){
       setSynthetic(false);
    }
    if (v instanceof VertexMergerGroup) {
      // put the content of the added group into
      // the existing group.  it's the only way to
      // ensure that the resolution rules behave properly.
      // note that logic assumes that in general the size
      // of the groups is rather small and so performs the
      // linear search for the contains() method.
      VertexMergerGroup g = (VertexMergerGroup) v;
      boolean added = false;
      for (Vertex a : g.list) {
        if (!list.contains(a)) {
          list.add(a);
          added = true;
        }
      }
      applyRule();
      return added;
    }
    if (list.contains(v)) {
      return false;
    }
    boolean added = list.add(v);
    applyRule();
    return added;
  }

  /**
   * Removes the specified vertex from the group. If the vertex is
   * not currently a member of the group, this operation will be ignored.
   *
   * @param v the vertex to be removed.
   * @return true if the vertex was a member of the group and was removed;
   * otherwise, false.
   */
  public boolean removeVertex(Vertex v) {
    boolean removed = list.remove(v);
    if(removed){
       applyRule();
    }
    return removed;
  }

  private void applyRule() {
    switch (rule) {
      case MeanValue:
        double zSum = 0;
        for (Vertex m : list) {
          zSum += m.z;
        }
        zRule = zSum / list.size();
        break;
      case MinValue:
        double zMin = Double.POSITIVE_INFINITY;
        for (Vertex m : list) {
          if (Double.isNaN(m.z)) {
            zMin = Double.NaN;
            break;
          }
          if (m.z < zMin) {
            zMin = m.z;
          }
        }
        zRule = zMin;
        break;
      case MaxValue:
        double zMax = Double.NEGATIVE_INFINITY;
        for (Vertex m : list) {
          if (Double.isNaN(m.z)) {
            zMax = Double.NaN;
            break;
          }
          if (m.z > zMax) {
            zMax = m.z;
          }
        }
        zRule = zMax;
        break;
      default:

    }
  }

  /**
   * Sets the rule for resolving coincident vertices; recalculates
   * value for vertex if necessary
   *
   * @param rule a valid member of the enumeration
   */
  public void setResolutionRule(ResolutionRule rule) {
    if (rule == null || rule == this.rule) {
      return;
    }
    this.rule = rule;
    applyRule();
  }

  /**
   * Get the z value associated with the vertex and the merging rules.
   * If the vertex is null, the return value for this method is
   * Double.NaN ("not a number").
   *
   * @return a floating point value or Double.NaN if z value is null.
   */
  @Override
  public double getZ() {
    return zRule;
  }

  /**
   * Gets an array of the coincident vertices. Each invocation of this method
   * results in a new instance of the array.
   *
   * @return a valid array of size 1 or greater.
   */
  public Vertex[] getVertices() {
    return list.toArray(new Vertex[list.size()]);
  }

  /**
   * Gets the number of vertices grouped together in the collection
   *
   * @return normally, a value of 1 or greater; but if the last vertex
   * in the group has been removed, a value of zero.
   */
  public int getSize() {
    return list.size();
  }

  /**
   * Indicates whether the group contains the specified vertex
   *
   * @param v a valid vertex
   * @return true if the vertex is a member of the group; otherwise, false.
   */
  public boolean contains(Vertex v) {
    return list.contains(v);
  }

  /**
   * Sets the color index for the vertex. The color index field is provided in
   * support of graph-coloring algorithms. Values in the range 0 to 255 are
   * supported.
   * 

* This method will set the color index for all vertices contain within the * merger group. * * @param colorIndex a value in the range 0 to 255 */ @Override public void setColorIndex(int colorIndex) { super.setColorIndex(colorIndex); for (Vertex v : list) { v.setColorIndex(colorIndex); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy