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 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "cpl_port.h" 14 : #include "ogr_geometry.h" 15 : 16 : #include <cstddef> 17 : 18 : #include "cpl_error.h" 19 : #include "ogr_api.h" 20 : #include "ogr_core.h" 21 : #include "ogr_p.h" 22 : 23 : /************************************************************************/ 24 : /* OGRMultiCurve( const OGRMultiCurve& ) */ 25 : /************************************************************************/ 26 : 27 : /** 28 : * \brief Copy constructor. 29 : * 30 : * Note: before GDAL 2.1, only the default implementation of the constructor 31 : * existed, which could be unsafe to use. 32 : * 33 : * @since GDAL 2.1 34 : */ 35 : 36 : OGRMultiCurve::OGRMultiCurve(const OGRMultiCurve &) = default; 37 : 38 : /************************************************************************/ 39 : /* operator=( const OGRMultiCurve&) */ 40 : /************************************************************************/ 41 : 42 : /** 43 : * \brief Assignment operator. 44 : * 45 : * Note: before GDAL 2.1, only the default implementation of the operator 46 : * existed, which could be unsafe to use. 47 : * 48 : * @since GDAL 2.1 49 : */ 50 : 51 9 : OGRMultiCurve &OGRMultiCurve::operator=(const OGRMultiCurve &other) 52 : { 53 9 : if (this != &other) 54 : { 55 8 : OGRGeometryCollection::operator=(other); 56 : } 57 9 : return *this; 58 : } 59 : 60 : /************************************************************************/ 61 : /* clone() */ 62 : /************************************************************************/ 63 : 64 154 : OGRMultiCurve *OGRMultiCurve::clone() const 65 : 66 : { 67 154 : auto ret = new (std::nothrow) OGRMultiCurve(*this); 68 154 : if (ret) 69 : { 70 154 : if (ret->WkbSize() != WkbSize()) 71 : { 72 0 : delete ret; 73 0 : ret = nullptr; 74 : } 75 : } 76 154 : return ret; 77 : } 78 : 79 : /************************************************************************/ 80 : /* getGeometryType() */ 81 : /************************************************************************/ 82 : 83 3792 : OGRwkbGeometryType OGRMultiCurve::getGeometryType() const 84 : 85 : { 86 3792 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) 87 2839 : return wkbMultiCurveZM; 88 953 : else if (flags & OGR_G_MEASURED) 89 13 : return wkbMultiCurveM; 90 940 : else if (flags & OGR_G_3D) 91 34 : return wkbMultiCurveZ; 92 : else 93 906 : return wkbMultiCurve; 94 : } 95 : 96 : /************************************************************************/ 97 : /* getDimension() */ 98 : /************************************************************************/ 99 : 100 3 : int OGRMultiCurve::getDimension() const 101 : 102 : { 103 3 : return 1; 104 : } 105 : 106 : /************************************************************************/ 107 : /* getGeometryName() */ 108 : /************************************************************************/ 109 : 110 381 : const char *OGRMultiCurve::getGeometryName() const 111 : 112 : { 113 381 : return "MULTICURVE"; 114 : } 115 : 116 : /************************************************************************/ 117 : /* isCompatibleSubType() */ 118 : /************************************************************************/ 119 : 120 : OGRBoolean 121 1467 : OGRMultiCurve::isCompatibleSubType(OGRwkbGeometryType eGeomType) const 122 : { 123 1467 : return OGR_GT_IsCurve(eGeomType); 124 : } 125 : 126 : /*! @cond Doxygen_Suppress */ 127 : /************************************************************************/ 128 : /* addCurveDirectlyFromWkt() */ 129 : /************************************************************************/ 130 : 131 1073 : OGRErr OGRMultiCurve::addCurveDirectlyFromWkt(OGRGeometry *poSelf, 132 : OGRCurve *poCurve) 133 : { 134 1073 : return poSelf->toMultiCurve()->addGeometryDirectly(poCurve); 135 : } 136 : 137 : /*! @endcond */ 138 : 139 : /************************************************************************/ 140 : /* importFromWkt() */ 141 : /* */ 142 : /* Instantiate from well known text format. */ 143 : /************************************************************************/ 144 : 145 810 : OGRErr OGRMultiCurve::importFromWkt(const char **ppszInput) 146 : 147 : { 148 810 : const bool bIsMultiCurve = wkbFlatten(getGeometryType()) == wkbMultiCurve; 149 810 : return importCurveCollectionFromWkt(ppszInput, 150 : TRUE, // bAllowEmptyComponent. 151 : bIsMultiCurve, // bAllowLineString. 152 : bIsMultiCurve, // bAllowCurve. 153 : bIsMultiCurve, // bAllowCompoundCurve. 154 810 : addCurveDirectlyFromWkt); 155 : } 156 : 157 : /************************************************************************/ 158 : /* exportToWkt() */ 159 : /************************************************************************/ 160 : 161 72 : std::string OGRMultiCurve::exportToWkt(const OGRWktOptions &opts, 162 : OGRErr *err) const 163 : { 164 72 : OGRWktOptions optsModified(opts); 165 72 : optsModified.variant = wkbVariantIso; 166 72 : return exportToWktInternal(optsModified, err, "LINESTRING"); 167 : } 168 : 169 : /************************************************************************/ 170 : /* hasCurveGeometry() */ 171 : /************************************************************************/ 172 : 173 1166 : OGRBoolean OGRMultiCurve::hasCurveGeometry(int bLookForNonLinear) const 174 : { 175 1166 : if (bLookForNonLinear) 176 11 : return OGRGeometryCollection::hasCurveGeometry(TRUE); 177 1155 : return true; 178 : } 179 : 180 : /************************************************************************/ 181 : /* CastToMultiLineString() */ 182 : /************************************************************************/ 183 : 184 : /** 185 : * \brief Cast to multi line string. 186 : * 187 : * This method should only be called if the multicurve actually only contains 188 : * instances of OGRLineString. This can be verified if hasCurveGeometry(TRUE) 189 : * returns FALSE. It is not intended to approximate circular curves. For that 190 : * use getLinearGeometry(). 191 : * 192 : * The passed in geometry is consumed and a new one returned (or NULL in case 193 : * of failure). 194 : * 195 : * @param poMC the input geometry - ownership is passed to the method. 196 : * @return new geometry. 197 : */ 198 : 199 43 : OGRMultiLineString *OGRMultiCurve::CastToMultiLineString(OGRMultiCurve *poMC) 200 : { 201 84 : for (auto &&poSubGeom : *poMC) 202 : { 203 41 : poSubGeom = OGRCurve::CastToLineString(poSubGeom); 204 41 : if (poSubGeom == nullptr) 205 : { 206 0 : delete poMC; 207 0 : return nullptr; 208 : } 209 : } 210 43 : OGRMultiLineString *poMLS = new OGRMultiLineString(); 211 43 : TransferMembersAndDestroy(poMC, poMLS); 212 43 : return poMLS; 213 : }