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