Class Label

  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 org.locationtech.jts.geom.Location;
 18  
 19  /**
 20  * A <code>Label</code> indicates the topological relationship of a component
 21  * of a topology graph to a given <code>Geometry</code>.
 22  * This class supports labels for relationships to two <code>Geometry</code>s,
 23  * which is sufficient for algorithms for binary operations.
 24  * <P>
 25  * Topology graphs support the concept of labeling nodes and edges in the graph.
 26  * The label of a node or edge specifies its topological relationship to one or
 27  * more geometries.  (In fact, since JTS operations have only two arguments labels
 28  * are required for only two geometries).  A label for a node or edge has one or
 29  * two elements, depending on whether the node or edge occurs in one or both of the
 30  * input <code>Geometry</code>s.  Elements contain attributes which categorize the
 31  * topological location of the node or edge relative to the parent
 32  * <code>Geometry</code>; that is, whether the node or edge is in the interior,
 33  * boundary or exterior of the <code>Geometry</code>.  Attributes have a value
 34  * from the set <code>{Interior, Boundary, Exterior}</code>.  In a node each
 35  * element has  a single attribute <code><On></code>.  For an edge each element has a
 36  * triplet of attributes <code><Left, On, Right></code>.
 37  * <P>
 38  * It is up to the client code to associate the 0 and 1 <code>TopologyLocation</code>s
 39  * with specific geometries.
 40  * @version 1.7
 41  *
 42  */
 43 public class Label {
 44  
 45   // converts a Label to a Line label (that is, one with no side Locations)
 46   public static Label toLineLabel(Label label)
 47   {
 48     Label lineLabel = new Label(Location.NONE);
 49     for (int i = 0; i < 2; i++) {
 50       lineLabel.setLocation(i, label.getLocation(i));
 51     }
 52     return lineLabel;
 53   }
 54  
 55   TopologyLocation elt[] = new TopologyLocation[2];
 56  
 57   /**
 58    * Construct a Label with a single location for both Geometries.
 59    * Initialize the locations to Null
 60    */
 61   public Label(int onLoc)
 62   {
 63     elt[0] = new TopologyLocation(onLoc);
 64     elt[1] = new TopologyLocation(onLoc);
 65   }
 66   /**
 67    * Construct a Label with a single location for both Geometries.
 68    * Initialize the location for the Geometry index.
 69    */
 70   public Label(int geomIndex, int onLoc)
 71   {
 72     elt[0] = new TopologyLocation(Location.NONE);
 73     elt[1] = new TopologyLocation(Location.NONE);
 74     elt[geomIndex].setLocation(onLoc);
 75   }
 76   /**
 77    * Construct a Label with On, Left and Right locations for both Geometries.
 78    * Initialize the locations for both Geometries to the given values.
 79    */
 80   public Label(int onLoc, int leftLoc, int rightLoc)
 81   {
 82     elt[0] = new TopologyLocation(onLoc, leftLoc, rightLoc);
 83     elt[1] = new TopologyLocation(onLoc, leftLoc, rightLoc);
 84   }
 85   /**
 86    * Construct a Label with On, Left and Right locations for both Geometries.
 87    * Initialize the locations for the given Geometry index.
 88    */
 89   public Label(int geomIndex, int onLoc, int leftLoc, int rightLoc)
 90   {
 91     elt[0] = new TopologyLocation(Location.NONE, Location.NONE, Location.NONE);
 92     elt[1] = new TopologyLocation(Location.NONE, Location.NONE, Location.NONE);
 93     elt[geomIndex].setLocations(onLoc, leftLoc, rightLoc);
 94   }
 95   /**
 96    * Construct a Label with the same values as the argument Label.
 97    */
 98   public Label(Label lbl)
 99   {
100     elt[0] = new TopologyLocation(lbl.elt[0]);
101     elt[1] = new TopologyLocation(lbl.elt[1]);
102   }
103  
104   public void flip()
105   {
106     elt[0].flip();
107     elt[1].flip();
108   }
109  
110   public int getLocation(int geomIndex, int posIndex) { return elt[geomIndex].get(posIndex); }
111   public int getLocation(int geomIndex) { return elt[geomIndex].get(Position.ON); }
112   public void setLocation(int geomIndex, int posIndex, int location)
113   {
114     elt[geomIndex].setLocation(posIndex, location);
115   }
116   public void setLocation(int geomIndex, int location)
117   {
118     elt[geomIndex].setLocation(Position.ON, location);
119   }
120   public void setAllLocations(int geomIndex, int location)
121   {
122     elt[geomIndex].setAllLocations(location);
123   }
124   public void setAllLocationsIfNull(int geomIndex, int location)
125   {
126     elt[geomIndex].setAllLocationsIfNull(location);
127   }
128   public void setAllLocationsIfNull(int location)
129   {
130     setAllLocationsIfNull(0, location);
131     setAllLocationsIfNull(1, location);
132   }
133   /**
134    * Merge this label with another one.
135    * Merging updates any null attributes of this label with the attributes from lbl
136    */
137   public void merge(Label lbl)
138   {
139     for (int i = 0; i < 2; i++) {
140       if (elt[i] == null && lbl.elt[i] != null) {
141         elt[i] = new TopologyLocation(lbl.elt[i]);
142       }
143       else {
144         elt[i].merge(lbl.elt[i]);
145       }
146     }
147   }
148   public int getGeometryCount()
149   {
150     int count = 0;
151     if (! elt[0].isNull()) count++;
152     if (! elt[1].isNull()) count++;
153     return count;
154   }
155   public boolean isNull(int geomIndex) { return elt[geomIndex].isNull(); }
156   public boolean isAnyNull(int geomIndex) { return elt[geomIndex].isAnyNull(); }
157  
158   public boolean isArea()               { return elt[0].isArea() || elt[1].isArea();   }
159   public boolean isArea(int geomIndex)  
160   {
161       /*  Testing
162       if (elt[0].getLocations().length != elt[1].getLocations().length) {
163           System.out.println(this);
164       }
165           */
166       return elt[geomIndex].isArea();   
167   }
168   public boolean isLine(int geomIndex)  { return elt[geomIndex].isLine();   }
169  
170   public boolean isEqualOnSide(Label lbl, int side)
171   {
172     return
173           this.elt[0].isEqualOnSide(lbl.elt[0], side)
174       &&  this.elt[1].isEqualOnSide(lbl.elt[1], side);
175   }
176   public boolean allPositionsEqual(int geomIndex, int loc)
177   {
178     return elt[geomIndex].allPositionsEqual(loc);
179   }
180   /**
181    * Converts one GeometryLocation to a Line location
182    */
183   public void toLine(int geomIndex)
184   {
185     if (elt[geomIndex].isArea())
186       elt[geomIndex] = new TopologyLocation(elt[geomIndex].location[0]);
187   }
188   public String toString()
189   {
190     StringBuffer buf = new StringBuffer();
191     if (elt[0] != null) {
192       buf.append("A:");
193       buf.append(elt[0].toString());
194     }
195     if (elt[1] != null) {
196       buf.append(" B:");
197       buf.append(elt[1].toString());
198     }
199     return buf.toString();
200   }
201 }
202