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

com.hazelcast.shaded.org.locationtech.jts.geomgraph.DirectedEdge Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * Copyright (c) 2016 Vivid Solutions.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 * and the Eclipse Distribution License is available at
 *
 * http://www.eclipse.org/org/documents/edl-v10.php.
 */
package com.hazelcast.shaded.org.locationtech.jts.geomgraph;

import java.io.PrintStream;

import com.hazelcast.shaded.org.locationtech.jts.geom.Location;
import com.hazelcast.shaded.org.locationtech.jts.geom.Position;
import com.hazelcast.shaded.org.locationtech.jts.geom.TopologyException;


/**
 * @version 1.7
 */
public class DirectedEdge
  extends EdgeEnd
{

  /**
   * Computes the factor for the change in depth when moving from one location to another.
   * E.g. if crossing from the {@link Location#INTERIOR} to the{@link Location#EXTERIOR}
   * the depth decreases, so the factor is -1.
   *
   * @param currLocation Current location
   * @param nextLocation Next location
   * @return change of depth moving from currLocation to nextLocation
   */
  public static int depthFactor(int currLocation, int nextLocation)
  {
    if (currLocation == Location.EXTERIOR && nextLocation == Location.INTERIOR)
       return 1;
    else if (currLocation == Location.INTERIOR && nextLocation == Location.EXTERIOR)
       return -1;
    return 0;
  }

  protected boolean isForward;
  private boolean isInResult = false;
  private boolean isVisited = false;

  private DirectedEdge sym; // the symmetric edge
  private DirectedEdge next;  // the next edge in the edge ring for the polygon containing this edge
  private DirectedEdge nextMin;  // the next edge in the MinimalEdgeRing that contains this edge
  private EdgeRing edgeRing;  // the EdgeRing that this edge is part of
  private EdgeRing minEdgeRing;  // the MinimalEdgeRing that this edge is part of
  /**
   * The depth of each side (position) of this edge.
   * The 0 element of the array is never used.
   */
  private int[] depth = { 0, -999, -999 };

  public DirectedEdge(Edge edge, boolean isForward)
  {
    super(edge);
    this.isForward = isForward;
    if (isForward) {
      init(edge.getCoordinate(0), edge.getCoordinate(1));
    }
    else {
      int n = edge.getNumPoints() - 1;
      init(edge.getCoordinate(n), edge.getCoordinate(n-1));
    }
    computeDirectedLabel();
  }
  public Edge getEdge() { return edge; }
  public void setInResult(boolean isInResult) { this.isInResult = isInResult; }
  public boolean isInResult() { return isInResult; }
  public boolean isVisited() { return isVisited; }
  public void setVisited(boolean isVisited) { this.isVisited = isVisited; }
  public void setEdgeRing(EdgeRing edgeRing) { this.edgeRing = edgeRing; }
  public EdgeRing getEdgeRing() { return edgeRing; }
  public void setMinEdgeRing(EdgeRing minEdgeRing) { this.minEdgeRing = minEdgeRing; }
  public EdgeRing getMinEdgeRing() { return minEdgeRing; }
  public int getDepth(int position) { return depth[position]; }

  /**
   * Set depth for a position.
   *
   * You may also use {@link #setEdgeDepths(int, int)} to
   * update depth and opposite depth together.
   *
   * @param position Position to update
   * @param depthVal Depth at the provided position
   */
  public void setDepth(int position, int depthVal)
  {
    if (depth[position] != -999) {
//      if (depth[position] != depthVal) {
//        Debug.print(this);
//      }
      if (depth[position] != depthVal)
        throw new TopologyException("assigned depths do not match", getCoordinate());
      //Assert.isTrue(depth[position] == depthVal, "assigned depths do not match at " + getCoordinate());
    }
    depth[position] = depthVal;
  }

  public int getDepthDelta()
  {
    int depthDelta = edge.getDepthDelta();
    if (! isForward) depthDelta = -depthDelta;
    return depthDelta;
  }

  /**
   * Marks both DirectedEdges attached to a given Edge.
   *
   * This is used for edges corresponding to lines, which will only
   * appear oriented in a single direction in the result.
   *
   * @param isVisited True to mark edge as visited
   */
  public void setVisitedEdge(boolean isVisited)
  {
    setVisited(isVisited);
    sym.setVisited(isVisited);
  }
  /**
   * Each Edge gives rise to a pair of symmetric DirectedEdges, in opposite
   * directions.
   * @return the DirectedEdge for the same Edge but in the opposite direction
   */
  public DirectedEdge getSym() { return sym; }
  public boolean isForward() { return isForward; }
  public void setSym(DirectedEdge de)
  {
    sym = de;
  }
  public DirectedEdge getNext() { return next; }
  public void setNext(DirectedEdge next) { this.next = next; }
  public DirectedEdge getNextMin() { return nextMin; }
  public void setNextMin(DirectedEdge nextMin) { this.nextMin = nextMin; }

  /**
   * This edge is a line edge if
   * 
    *
  • at least one of the labels is a line label *
  • any labels which are not line labels have all Locations = EXTERIOR *
* * @return If edge is a line edge */ public boolean isLineEdge() { boolean isLine = label.isLine(0) || label.isLine(1); boolean isExteriorIfArea0 = ! label.isArea(0) || label.allPositionsEqual(0, Location.EXTERIOR); boolean isExteriorIfArea1 = ! label.isArea(1) || label.allPositionsEqual(1, Location.EXTERIOR); return isLine && isExteriorIfArea0 && isExteriorIfArea1; } /** * This is an interior Area edge if *
    *
  • its label is an Area label for both Geometries *
  • and for each Geometry both sides are in the interior. *
* * @return true if this is an interior Area edge */ public boolean isInteriorAreaEdge() { boolean isInteriorAreaEdge = true; for (int i = 0; i < 2; i++) { if (! ( label.isArea(i) && label.getLocation(i, Position.LEFT ) == Location.INTERIOR && label.getLocation(i, Position.RIGHT) == Location.INTERIOR) ) { isInteriorAreaEdge = false; } } return isInteriorAreaEdge; } /** * Compute the label in the appropriate orientation for this DirEdge */ private void computeDirectedLabel() { label = new Label(edge.getLabel()); if (! isForward) label.flip(); } /** * Set both edge depths. One depth for a given side is provided. The other is * computed depending on the Location transition and the depthDelta of the edge. * * @param position Position to update * @param depth Depth at the provided position */ public void setEdgeDepths(int position, int depth) { // get the depth transition delta from R to L for this directed Edge int depthDelta = getEdge().getDepthDelta(); if (! isForward) depthDelta = -depthDelta; // if moving from L to R instead of R to L must change sign of delta int directionFactor = 1; if (position == Position.LEFT) directionFactor = -1; int oppositePos = Position.opposite(position); int delta = depthDelta * directionFactor; //TESTINGint delta = depthDelta * DirectedEdge.depthFactor(loc, oppositeLoc); int oppositeDepth = depth + delta; setDepth(position, depth); setDepth(oppositePos, oppositeDepth); } public void print(PrintStream out) { super.print(out); out.print(" " + depth[Position.LEFT] + "/" + depth[Position.RIGHT]); out.print(" (" + getDepthDelta() + ")"); //out.print(" " + this.hashCode()); //if (next != null) out.print(" next:" + next.hashCode()); if (isInResult) out.print(" inResult"); } public void printEdge(PrintStream out) { print(out); out.print(" "); if (isForward) edge.print(out); else edge.printReverse(out); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy