1 /********************************************************************** 2 * 3 * GEOS - Geometry Engine Open Source 4 * http://geos.osgeo.org 5 * 6 * Copyright (C) 2011 Sandro Santilli <strk@kbt.io> 7 * Copyright (C) 2005-2006 Refractions Research Inc. 8 * Copyright (C) 2001-2002 Vivid Solutions Inc. 9 * 10 * This is free software; you can redistribute and/or modify it under 11 * the terms of the GNU Lesser General Public Licence as published 12 * by the Free Software Foundation. 13 * See the COPYING file for more information. 14 * 15 ********************************************************************** 16 * 17 * Last port: linearref/LengthIndexedLine.java r463 18 * 19 **********************************************************************/ 20 21 #ifndef GEOS_LINEARREF_LENGTHINDEXEDLINE_H 22 #define GEOS_LINEARREF_LENGTHINDEXEDLINE_H 23 24 #include <geos/export.h> 25 #include <geos/geom/Coordinate.h> 26 #include <geos/geom/Geometry.h> 27 #include <geos/linearref/LinearLocation.h> 28 29 namespace geos { 30 namespace linearref { // geos::linearref 31 32 /** \brief 33 * Supports linear referencing along a linear geom::Geometry 34 * using the length along the line as the index. 35 * 36 * Negative length values are taken as measured in the reverse direction 37 * from the end of the geometry. 38 * Out-of-range index values are handled by clamping 39 * them to the valid range of values. 40 * Non-simple lines (i.e. which loop back to cross or touch 41 * themselves) are supported. 42 */ 43 44 class GEOS_DLL LengthIndexedLine { 45 private: 46 const geom::Geometry* linearGeom; 47 LinearLocation locationOf(double index) const; 48 LinearLocation locationOf(double index, bool resolveLower) const; 49 double positiveIndex(double index) const; 50 51 public: 52 53 /** \brief 54 * Constructs an object which allows a linear [Geometry](@ref geom::Geometry) 55 * to be linearly referenced using length as an index. 56 * 57 * @param linearGeom the linear geometry to reference along 58 */ 59 60 LengthIndexedLine(const geom::Geometry* linearGeom); 61 62 /** \brief 63 * Computes the [Coordinate](@ref geom::Coordinate) for the point 64 * on the line at the given index. 65 * 66 * If the index is out of range the first or last point on the 67 * line will be returned. 68 * The Z-ordinate of the computed point will be interpolated from 69 * the Z-ordinates of the line segment containing it, if they exist. 70 * 71 * @param index the index of the desired point 72 * @return the Coordinate at the given index 73 */ 74 geom::Coordinate extractPoint(double index) const; 75 76 77 /** 78 * \brief 79 * Computes the [Coordinate](@ref geom::Coordinate) for the point 80 * on the line at the given index, offset by the given distance. 81 * 82 * If the index is out of range the first or last point on the 83 * line will be returned. 84 * The computed point is offset to the left of the line if the 85 * offset distance is positive, to the right if negative. 86 * 87 * The Z-ordinate of the computed point will be interpolated from 88 * the Z-ordinates of the line segment containing it, if they exist. 89 * 90 * @param index the index of the desired point 91 * @param offsetDistance the distance the point is offset from the segment 92 * (positive is to the left, negative is to the right) 93 * @return the Coordinate at the given index 94 */ 95 geom::Coordinate extractPoint(double index, double offsetDistance) const; 96 97 /** \brief 98 * Computes the [LineString](@ref geom::LineString) for the interval 99 * on the line between the given indices. 100 * 101 * If the endIndex lies before the startIndex, 102 * the computed geometry is reversed. 103 * 104 * @param startIndex the index of the start of the interval 105 * @param endIndex the index of the end of the interval 106 * @return the linear interval between the indices 107 */ 108 std::unique_ptr<geom::Geometry> extractLine(double startIndex, double endIndex) const; 109 110 111 /** \brief 112 * Computes the minimum index for a point on the line. 113 * 114 * If the line is not simple (i.e. loops back on itself) 115 * a single point may have more than one possible index. 116 * In this case, the smallest index is returned. 117 * 118 * The supplied point does not *necessarily* have to lie precisely 119 * on the line, but if it is far from the line the accuracy and 120 * performance of this function is not guaranteed. 121 * Use {@link #project} to compute a guaranteed result for points 122 * which may be far from the line. 123 * 124 * @param pt a point on the line 125 * @return the minimum index of the point 126 * 127 * @see project 128 */ 129 double indexOf(const geom::Coordinate& pt) const; 130 131 /** \brief 132 * Finds the index for a point on the line which is 133 * greater than the given index. 134 * 135 * If no such index exists, returns `minIndex`. 136 * This method can be used to determine all indexes for 137 * a point which occurs more than once on a non-simple line. 138 * It can also be used to disambiguate cases where the given point lies 139 * slightly off the line and is equidistant from two different 140 * points on the line. 141 * 142 * The supplied point does not `*necessarily* have to lie precisely 143 * on the line, but if it is far from the line the accuracy and 144 * performance of this function is not guaranteed. 145 * Use {@link #project} to compute a guaranteed result for points 146 * which may be far from the line. 147 * 148 * @param pt a point on the line 149 * @param minIndex the value the returned index must be greater than 150 * @return the index of the point greater than the given minimum index 151 * 152 * @see project 153 */ 154 double indexOfAfter(const geom::Coordinate& pt, double minIndex) const; 155 156 /** \brief 157 * Computes the indices for a subline of the line. 158 * 159 * (The subline must **conform** to the line; that is, 160 * all vertices in the subline (except possibly the first and last) 161 * must be vertices of the line and occcur in the same order). 162 * 163 * @param subLine a subLine of the line 164 * @return a pair of indices for the start and end of the subline. 165 */ 166 double* indicesOf(const geom::Geometry* subLine) const; 167 168 169 /** \brief 170 * Computes the index for the closest point on the line to the given point. 171 * 172 * If more than one point has the closest distance the first one along the line 173 * is returned. 174 * (The point does not necessarily have to lie precisely on the line.) 175 * 176 * @param pt a point on the line 177 * @return the index of the point 178 */ 179 double project(const geom::Coordinate& pt) const; 180 181 /** \brief 182 * Returns the index of the start of the line 183 * @return the start index 184 */ 185 double getStartIndex() const; 186 187 /** \brief 188 * Returns the index of the end of the line 189 * @return the end index 190 */ 191 double getEndIndex() const; 192 193 /** \brief 194 * Tests whether an index is in the valid index range for the line. 195 * 196 * @param index the index to test 197 * @return `true` if the index is in the valid range 198 */ 199 bool isValidIndex(double index) const; 200 201 202 /** \brief 203 * Computes a valid index for this line by clamping the given index 204 * to the valid range of index values. 205 * 206 * @return a valid index value 207 */ 208 double clampIndex(double index) const; 209 }; 210 } 211 } 212 #endif 213