Class Node

  1  
  2  
  3  
  4 /*
  5  * Copyright (c) 2016 Vivid Solutions.
  6  *
  7  * All rights reserved. This program and the accompanying materials
  8  * are made available under the terms of the Eclipse Public License 2.0
  9  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 10  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 11  * and the Eclipse Distribution License is available at
 12  *
 13  * http://www.eclipse.org/org/documents/edl-v10.php.
 14  */
 15 package org.locationtech.jts.geomgraph;
 16  
 17 import java.io.PrintStream;
 18 import java.util.Iterator;
 19  
 20 import org.locationtech.jts.geom.Coordinate;
 21 import org.locationtech.jts.geom.IntersectionMatrix;
 22 import org.locationtech.jts.geom.Location;
 23  
 24  
 25 /**
 26  * @version 1.7
 27  */
 28 public class Node
 29   extends GraphComponent
 30 {
 31   protected Coordinate coord// only non-null if this node is precise
 32   protected EdgeEndStar edges;
 33  
 34   public Node(Coordinate coord, EdgeEndStar edges)
 35   {
 36     this.coord = coord;
 37     this.edges = edges;
 38     label = new Label(0, Location.NONE);
 39   }
 40  
 41   public Coordinate getCoordinate() { return coord; }
 42   public EdgeEndStar getEdges() { return edges; }
 43  
 44   /**
 45    * Tests whether any incident edge is flagged as
 46    * being in the result.
 47    * This test can be used to determine if the node is in the result,
 48    * since if any incident edge is in the result, the node must be in the result as well.
 49    *
 50    * @return <code>true</code> if any incident edge in the in the result
 51    */
 52   public boolean isIncidentEdgeInResult()
 53   {
 54     for (Iterator it = getEdges().getEdges().iterator(); it.hasNext(); ) {
 55       DirectedEdge de = (DirectedEdge) it.next();
 56       if (de.getEdge().isInResult())
 57         return true;
 58     }
 59     return false;
 60   }
 61  
 62   public boolean isIsolated()
 63   {
 64     return (label.getGeometryCount() == 1);
 65   }
 66   /**
 67    * Basic nodes do not compute IMs
 68    */
 69   protected void computeIM(IntersectionMatrix im) {}
 70   /**
 71    * Add the edge to the list of edges at this node
 72    */
 73   public void add(EdgeEnd e)
 74   {
 75     // Assert: start pt of e is equal to node point
 76     edges.insert(e);
 77     e.setNode(this);
 78   }
 79  
 80   public void mergeLabel(Node n)
 81   {
 82     mergeLabel(n.label);
 83   }
 84  
 85   /**
 86    * To merge labels for two nodes,
 87    * the merged location for each LabelElement is computed.
 88    * The location for the corresponding node LabelElement is set to the result,
 89    * as long as the location is non-null.
 90    */
 91  
 92   public void mergeLabel(Label label2)
 93   {
 94     for (int i = 0; i < 2; i++) {
 95       int loc = computeMergedLocation(label2, i);
 96       int thisLoc = label.getLocation(i);
 97       if (thisLoc == Location.NONE) label.setLocation(i, loc);
 98     }
 99   }
100  
101   public void setLabel(int argIndex, int onLocation)
102   {
103     if (label == null) {
104       label = new Label(argIndex, onLocation);
105     }
106     else
107       label.setLocation(argIndex, onLocation);
108   }
109  
110   /**
111    * Updates the label of a node to BOUNDARY,
112    * obeying the mod-2 boundaryDetermination rule.
113    */
114   public void setLabelBoundary(int argIndex)
115   {
116     if (label == nullreturn;
117  
118     // determine the current location for the point (if any)
119     int loc = Location.NONE;
120     if (label != null)
121       loc = label.getLocation(argIndex);
122     // flip the loc
123     int newLoc;
124     switch (loc) {
125     case Location.BOUNDARY: newLoc = Location.INTERIOR; break;
126     case Location.INTERIOR: newLoc = Location.BOUNDARY; break;
127     default: newLoc = Location.BOUNDARY;  break;
128     }
129     label.setLocation(argIndex, newLoc);
130   }
131  
132   /**
133    * The location for a given eltIndex for a node will be one
134    * of { null, INTERIOR, BOUNDARY }.
135    * A node may be on both the boundary and the interior of a geometry;
136    * in this case, the rule is that the node is considered to be in the boundary.
137    * The merged location is the maximum of the two input values.
138    */
139   int computeMergedLocation(Label label2, int eltIndex)
140   {
141     int loc = Location.NONE;
142     loc = label.getLocation(eltIndex);
143     if (! label2.isNull(eltIndex)) {
144         int nLoc = label2.getLocation(eltIndex);
145         if (loc != Location.BOUNDARY) loc = nLoc;
146     }
147     return loc;
148   }
149  
150   public void print(PrintStream out)
151   {
152     out.println("node " + coord + " lbl: " + label);
153   }
154 }
155