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