1 /********************************************************************** 2 * 3 * GEOS - Geometry Engine Open Source 4 * http://geos.osgeo.org 5 * 6 * Copyright (C) 2009 Sandro Santilli <strk@kbt.io> 7 * 8 * This is free software; you can redistribute and/or modify it under 9 * the terms of the GNU Lesser General Public Licence as published 10 * by the Free Software Foundation. 11 * See the COPYING file for more information. 12 * 13 ********************************************************************** 14 * 15 * Last port: algorithm/BoundaryNodeRule.java rev 1.4 (JTS-1.10) 16 * 17 **********************************************************************/ 18 19 #include <geos/algorithm/BoundaryNodeRule.h> 20 21 namespace geos { 22 namespace algorithm { // geos.algorithm 23 24 // These classes are public in JTS, and under the BoundaryNodeRule 25 // namespace. In GEOS they are hidden and only accessible as singleton 26 // from BoundaryNodeRule static const references 27 // 28 namespace { 29 30 /** 31 * A {@link BoundaryNodeRule} specifies that points are in the 32 * boundary of a lineal geometry iff 33 * the point lies on the boundary of an odd number 34 * of components. 35 * Under this rule {@link LinearRing}s and closed 36 * {@link LineString}s have an empty boundary. 37 * <p> 38 * This is the rule specified by the <i>OGC SFS</i>, 39 * and is the default rule used in JTS. 40 * 41 * @author Martin Davis 42 * @version 1.7 43 */ 44 class Mod2BoundaryNodeRule : public BoundaryNodeRule { 45 public: 46 bool isInBoundary(int boundaryCount) const47 isInBoundary(int boundaryCount) const override 48 { 49 // the "Mod-2 Rule" 50 return boundaryCount % 2 == 1; 51 } 52 }; 53 54 55 /** 56 * A {@link BoundaryNodeRule} which specifies that any points 57 * which are endpoints 58 * of lineal components are in the boundary of the 59 * parent geometry. 60 * This corresponds to the "intuitive" topological definition 61 * of boundary. 62 * Under this rule {@link LinearRing}s have a non-empty boundary 63 * (the common endpoint of the underlying LineString). 64 * <p> 65 * This rule is useful when dealing with linear networks. 66 * For example, it can be used to check 67 * whether linear networks are correctly noded. 68 * The usual network topology constraint is that linear segments may 69 * touch only at endpoints. 70 * In the case of a segment touching a closed segment (ring) at one 71 * point, 72 * the Mod2 rule cannot distinguish between the permitted case of 73 * touching at the 74 * node point and the invalid case of touching at some other interior 75 * (non-node) point. 76 * The EndPoint rule does distinguish between these cases, 77 * so is more appropriate for use. 78 * 79 * @author Martin Davis 80 * @version 1.7 81 */ 82 class EndPointBoundaryNodeRule : public BoundaryNodeRule { 83 bool isInBoundary(int boundaryCount) const84 isInBoundary(int boundaryCount) const override 85 { 86 return boundaryCount > 0; 87 } 88 }; 89 90 /** 91 * A {@link BoundaryNodeRule} which determines that only 92 * endpoints with valency greater than 1 are on the boundary. 93 * This corresponds to the boundary of a {@link MultiLineString} 94 * being all the "attached" endpoints, but not 95 * the "unattached" ones. 96 * 97 * @author Martin Davis 98 * @version 1.7 99 */ 100 class MultiValentEndPointBoundaryNodeRule : public BoundaryNodeRule { 101 bool isInBoundary(int boundaryCount) const102 isInBoundary(int boundaryCount) const override 103 { 104 return boundaryCount > 1; 105 } 106 }; 107 108 /** 109 * A {@link BoundaryNodeRule} which determines that only 110 * endpoints with valency of exactly 1 are on the boundary. 111 * This corresponds to the boundary of a {@link MultiLineString} 112 * being all the "unattached" endpoints. 113 * 114 * @author Martin Davis 115 * @version 1.7 116 */ 117 class MonoValentEndPointBoundaryNodeRule : public BoundaryNodeRule { 118 bool isInBoundary(int boundaryCount) const119 isInBoundary(int boundaryCount) const override 120 { 121 return boundaryCount == 1; 122 } 123 }; 124 125 Mod2BoundaryNodeRule mod2Rule; 126 EndPointBoundaryNodeRule endPointRule; 127 MultiValentEndPointBoundaryNodeRule multiValentRule; 128 MonoValentEndPointBoundaryNodeRule monoValentRule; 129 130 } // anonymous namespace 131 132 //const BoundaryNodeRule& BoundaryNodeRule::MOD2_BOUNDARY_RULE = mod2Rule; 133 const BoundaryNodeRule& getBoundaryRuleMod2()134BoundaryNodeRule::getBoundaryRuleMod2() 135 { 136 return mod2Rule; 137 } 138 139 //const BoundaryNodeRule& BoundaryNodeRule::ENDPOINT_BOUNDARY_RULE = endPointRule; 140 const BoundaryNodeRule& getBoundaryEndPoint()141BoundaryNodeRule::getBoundaryEndPoint() 142 { 143 return endPointRule; 144 } 145 146 //const BoundaryNodeRule& BoundaryNodeRule::MULTIVALENT_ENDPOINT_BOUNDARY_RULE = multiValentRule; 147 const BoundaryNodeRule& getBoundaryMultivalentEndPoint()148BoundaryNodeRule::getBoundaryMultivalentEndPoint() 149 { 150 return multiValentRule; 151 } 152 153 //const BoundaryNodeRule& BoundaryNodeRule::MONOVALENT_ENDPOINT_BOUNDARY_RULE = monoValentRule; 154 const BoundaryNodeRule& getBoundaryMonovalentEndPoint()155BoundaryNodeRule::getBoundaryMonovalentEndPoint() 156 { 157 return monoValentRule; 158 } 159 160 //const BoundaryNodeRule& BoundaryNodeRule::OGC_SFS_BOUNDARY_RULE = BoundaryNodeRule::MOD2_BOUNDARY_RULE; 161 const BoundaryNodeRule& getBoundaryOGCSFS()162BoundaryNodeRule::getBoundaryOGCSFS() 163 { 164 return getBoundaryRuleMod2(); 165 } 166 167 } // namespace geos.algorithm 168 } // namespace geos 169 170