Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: The OGRMultiCurve class. 5 : * Author: Even Rouault <even dot rouault at spatialys dot com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys dot com> 9 : * 10 : * Permission is hereby granted, free of charge, to any person obtaining a 11 : * copy of this software and associated documentation files (the "Software"), 12 : * to deal in the Software without restriction, including without limitation 13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 : * and/or sell copies of the Software, and to permit persons to whom the 15 : * Software is furnished to do so, subject to the following conditions: 16 : * 17 : * The above copyright notice and this permission notice shall be included 18 : * in all copies or substantial portions of the Software. 19 : * 20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 : * DEALINGS IN THE SOFTWARE. 27 : ****************************************************************************/ 28 : 29 : #include "cpl_port.h" 30 : #include "ogr_geometry.h" 31 : 32 : #include <cstddef> 33 : 34 : #include "cpl_error.h" 35 : #include "ogr_api.h" 36 : #include "ogr_core.h" 37 : #include "ogr_p.h" 38 : 39 : /************************************************************************/ 40 : /* OGRMultiCurve() */ 41 : /************************************************************************/ 42 : 43 : /** 44 : * \brief Create an empty multi curve collection. 45 : */ 46 : 47 : OGRMultiCurve::OGRMultiCurve() = default; 48 : 49 : /************************************************************************/ 50 : /* OGRMultiCurve( const OGRMultiCurve& ) */ 51 : /************************************************************************/ 52 : 53 : /** 54 : * \brief Copy constructor. 55 : * 56 : * Note: before GDAL 2.1, only the default implementation of the constructor 57 : * existed, which could be unsafe to use. 58 : * 59 : * @since GDAL 2.1 60 : */ 61 : 62 : OGRMultiCurve::OGRMultiCurve(const OGRMultiCurve &) = default; 63 : 64 : /************************************************************************/ 65 : /* ~OGRMultiCurve() */ 66 : /************************************************************************/ 67 : 68 : OGRMultiCurve::~OGRMultiCurve() = default; 69 : 70 : /************************************************************************/ 71 : /* operator=( const OGRMultiCurve&) */ 72 : /************************************************************************/ 73 : 74 : /** 75 : * \brief Assignment operator. 76 : * 77 : * Note: before GDAL 2.1, only the default implementation of the operator 78 : * existed, which could be unsafe to use. 79 : * 80 : * @since GDAL 2.1 81 : */ 82 : 83 9 : OGRMultiCurve &OGRMultiCurve::operator=(const OGRMultiCurve &other) 84 : { 85 9 : if (this != &other) 86 : { 87 8 : OGRGeometryCollection::operator=(other); 88 : } 89 9 : return *this; 90 : } 91 : 92 : /************************************************************************/ 93 : /* clone() */ 94 : /************************************************************************/ 95 : 96 152 : OGRMultiCurve *OGRMultiCurve::clone() const 97 : 98 : { 99 152 : return new (std::nothrow) OGRMultiCurve(*this); 100 : } 101 : 102 : /************************************************************************/ 103 : /* getGeometryType() */ 104 : /************************************************************************/ 105 : 106 3765 : OGRwkbGeometryType OGRMultiCurve::getGeometryType() const 107 : 108 : { 109 3765 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) 110 2839 : return wkbMultiCurveZM; 111 926 : else if (flags & OGR_G_MEASURED) 112 13 : return wkbMultiCurveM; 113 913 : else if (flags & OGR_G_3D) 114 30 : return wkbMultiCurveZ; 115 : else 116 883 : return wkbMultiCurve; 117 : } 118 : 119 : /************************************************************************/ 120 : /* getDimension() */ 121 : /************************************************************************/ 122 : 123 3 : int OGRMultiCurve::getDimension() const 124 : 125 : { 126 3 : return 1; 127 : } 128 : 129 : /************************************************************************/ 130 : /* getGeometryName() */ 131 : /************************************************************************/ 132 : 133 369 : const char *OGRMultiCurve::getGeometryName() const 134 : 135 : { 136 369 : return "MULTICURVE"; 137 : } 138 : 139 : /************************************************************************/ 140 : /* isCompatibleSubType() */ 141 : /************************************************************************/ 142 : 143 : OGRBoolean 144 1461 : OGRMultiCurve::isCompatibleSubType(OGRwkbGeometryType eGeomType) const 145 : { 146 1461 : return OGR_GT_IsCurve(eGeomType); 147 : } 148 : 149 : /*! @cond Doxygen_Suppress */ 150 : /************************************************************************/ 151 : /* addCurveDirectlyFromWkt() */ 152 : /************************************************************************/ 153 : 154 1034 : OGRErr OGRMultiCurve::addCurveDirectlyFromWkt(OGRGeometry *poSelf, 155 : OGRCurve *poCurve) 156 : { 157 1034 : return poSelf->toMultiCurve()->addGeometryDirectly(poCurve); 158 : } 159 : 160 : /*! @endcond */ 161 : 162 : /************************************************************************/ 163 : /* importFromWkt() */ 164 : /* */ 165 : /* Instantiate from well known text format. */ 166 : /************************************************************************/ 167 : 168 774 : OGRErr OGRMultiCurve::importFromWkt(const char **ppszInput) 169 : 170 : { 171 774 : const bool bIsMultiCurve = wkbFlatten(getGeometryType()) == wkbMultiCurve; 172 774 : return importCurveCollectionFromWkt(ppszInput, 173 : TRUE, // bAllowEmptyComponent. 174 : bIsMultiCurve, // bAllowLineString. 175 : bIsMultiCurve, // bAllowCurve. 176 : bIsMultiCurve, // bAllowCompoundCurve. 177 774 : addCurveDirectlyFromWkt); 178 : } 179 : 180 : /************************************************************************/ 181 : /* exportToWkt() */ 182 : /************************************************************************/ 183 : 184 69 : std::string OGRMultiCurve::exportToWkt(const OGRWktOptions &opts, 185 : OGRErr *err) const 186 : { 187 69 : OGRWktOptions optsModified(opts); 188 69 : optsModified.variant = wkbVariantIso; 189 69 : return exportToWktInternal(optsModified, err, "LINESTRING"); 190 : } 191 : 192 : /************************************************************************/ 193 : /* hasCurveGeometry() */ 194 : /************************************************************************/ 195 : 196 1158 : OGRBoolean OGRMultiCurve::hasCurveGeometry(int bLookForNonLinear) const 197 : { 198 1158 : if (bLookForNonLinear) 199 11 : return OGRGeometryCollection::hasCurveGeometry(TRUE); 200 1147 : return true; 201 : } 202 : 203 : /************************************************************************/ 204 : /* CastToMultiLineString() */ 205 : /************************************************************************/ 206 : 207 : /** 208 : * \brief Cast to multi line string. 209 : * 210 : * This method should only be called if the multicurve actually only contains 211 : * instances of OGRLineString. This can be verified if hasCurveGeometry(TRUE) 212 : * returns FALSE. It is not intended to approximate circular curves. For that 213 : * use getLinearGeometry(). 214 : * 215 : * The passed in geometry is consumed and a new one returned (or NULL in case 216 : * of failure). 217 : * 218 : * @param poMC the input geometry - ownership is passed to the method. 219 : * @return new geometry. 220 : */ 221 : 222 42 : OGRMultiLineString *OGRMultiCurve::CastToMultiLineString(OGRMultiCurve *poMC) 223 : { 224 82 : for (auto &&poSubGeom : *poMC) 225 : { 226 40 : poSubGeom = OGRCurve::CastToLineString(poSubGeom); 227 40 : if (poSubGeom == nullptr) 228 : { 229 0 : delete poMC; 230 0 : return nullptr; 231 : } 232 : } 233 42 : OGRMultiLineString *poMLS = new OGRMultiLineString(); 234 42 : TransferMembersAndDestroy(poMC, poMLS); 235 42 : return poMLS; 236 : }