1 /******************************************************************************
2  * $Id: ogrmulticurve.cpp 27960 2014-11-14 18:31:32Z rouault $
3  *
4  * Project:  OpenGIS Simple Features Reference Implementation
5  * Purpose:  The OGRMultiCurve class.
6  * Author:   Even Rouault <even dot rouault at spatialys dot com>
7  *
8  ******************************************************************************
9  * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys dot com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #include "ogr_geometry.h"
31 #include "ogr_p.h"
32 #include "ogr_api.h"
33 
34 CPL_CVSID("$Id: ogrmulticurve.cpp 27960 2014-11-14 18:31:32Z rouault $");
35 
36 /************************************************************************/
37 /*                            OGRMultiCurve()                           */
38 /************************************************************************/
39 
40 /**
41  * \brief Create an empty multi curve collection.
42  */
43 
OGRMultiCurve()44 OGRMultiCurve::OGRMultiCurve()
45 {
46 }
47 
48 /************************************************************************/
49 /*                           ~OGRMultiCurve()                           */
50 /************************************************************************/
51 
~OGRMultiCurve()52 OGRMultiCurve::~OGRMultiCurve()
53 {
54 }
55 
56 /************************************************************************/
57 /*                          getGeometryType()                           */
58 /************************************************************************/
59 
getGeometryType() const60 OGRwkbGeometryType OGRMultiCurve::getGeometryType() const
61 
62 {
63     if( getCoordinateDimension() == 3 )
64         return wkbMultiCurveZ;
65     else
66         return wkbMultiCurve;
67 }
68 
69 /************************************************************************/
70 /*                            getDimension()                            */
71 /************************************************************************/
72 
getDimension() const73 int OGRMultiCurve::getDimension() const
74 
75 {
76     return 1;
77 }
78 
79 /************************************************************************/
80 /*                          getGeometryName()                           */
81 /************************************************************************/
82 
getGeometryName() const83 const char * OGRMultiCurve::getGeometryName() const
84 
85 {
86     return "MULTICURVE";
87 }
88 
89 /************************************************************************/
90 /*                          isCompatibleSubType()                       */
91 /************************************************************************/
92 
isCompatibleSubType(OGRwkbGeometryType eGeomType) const93 OGRBoolean OGRMultiCurve::isCompatibleSubType( OGRwkbGeometryType eGeomType ) const
94 {
95     return OGR_GT_IsCurve(eGeomType);
96 }
97 
98 /************************************************************************/
99 /*                       addCurveDirectlyFromWkt()                      */
100 /************************************************************************/
101 
addCurveDirectlyFromWkt(OGRGeometry * poSelf,OGRCurve * poCurve)102 OGRErr OGRMultiCurve::addCurveDirectlyFromWkt( OGRGeometry* poSelf, OGRCurve* poCurve )
103 {
104     return ((OGRMultiCurve*)poSelf)->addGeometryDirectly(poCurve);
105 }
106 
107 /************************************************************************/
108 /*                           importFromWkt()                            */
109 /*                                                                      */
110 /*      Instantiate from well known text format.                        */
111 /************************************************************************/
112 
importFromWkt(char ** ppszInput)113 OGRErr OGRMultiCurve::importFromWkt( char ** ppszInput )
114 
115 {
116     int bIsMultiCurve = (wkbFlatten(getGeometryType()) == wkbMultiCurve);
117     return importCurveCollectionFromWkt( ppszInput,
118                                          TRUE, /* bAllowEmptyComponent */
119                                          bIsMultiCurve, /* bAllowLineString */
120                                          bIsMultiCurve, /* bAllowCurve */
121                                          bIsMultiCurve, /* bAllowCompoundCurve */
122                                          addCurveDirectlyFromWkt );
123 }
124 
125 /************************************************************************/
126 /*                            exportToWkt()                             */
127 /************************************************************************/
128 
exportToWkt(char ** ppszDstText,CPL_UNUSED OGRwkbVariant eWkbVariant) const129 OGRErr OGRMultiCurve::exportToWkt( char ** ppszDstText,
130                                    CPL_UNUSED OGRwkbVariant eWkbVariant ) const
131 
132 {
133     return exportToWktInternal( ppszDstText, wkbVariantIso, "LINESTRING" );
134 }
135 
136 /************************************************************************/
137 /*                         hasCurveGeometry()                           */
138 /************************************************************************/
139 
hasCurveGeometry(int bLookForNonLinear) const140 OGRBoolean OGRMultiCurve::hasCurveGeometry(int bLookForNonLinear) const
141 {
142     if( bLookForNonLinear )
143         return OGRGeometryCollection::hasCurveGeometry(TRUE);
144     return TRUE;
145 }
146 
147 /************************************************************************/
148 /*                          CastToMultiLineString()                     */
149 /************************************************************************/
150 
151 /**
152  * \brief Cast to multi line string.
153  *
154  * This method should only be called if the multicurve actually only contains
155  * instances of OGRLineString. This can be verified if hasCurveGeometry(TRUE)
156  * returns FALSE. It is not intended to approximate circular curves. For that
157  * use getLinearGeometry().
158  *
159  * The passed in geometry is consumed and a new one returned (or NULL in case
160  * of failure).
161  *
162  * @param poMS the input geometry - ownership is passed to the method.
163  * @return new geometry.
164  */
165 
CastToMultiLineString(OGRMultiCurve * poMC)166 OGRMultiLineString* OGRMultiCurve::CastToMultiLineString(OGRMultiCurve* poMC)
167 {
168     for(int i=0;i<poMC->nGeomCount;i++)
169     {
170         poMC->papoGeoms[i] = OGRCurve::CastToLineString( (OGRCurve*)poMC->papoGeoms[i] );
171         if( poMC->papoGeoms[i] == NULL )
172         {
173             delete poMC;
174             return NULL;
175         }
176     }
177     return (OGRMultiLineString*) TransferMembersAndDestroy(poMC, new OGRMultiLineString());
178 }
179