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