OGRErr OGRPoint::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if ( eWkbVariant == wkbVariantIso ) nGType = getIsoGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if ( IsEmpty() && eWkbVariant == wkbVariantIso ) { double dNan = std::numeric_limits<double>::quiet_NaN(); memcpy( pabyData+5, &dNan, 8 ); memcpy( pabyData+5+8, &dNan, 8 ); if( getCoordinateDimension() == 3 ) memcpy( pabyData+5+16, &dNan, 8 ); } else { memcpy( pabyData+5, &x, 16 ); if( getCoordinateDimension() == 3 ) { memcpy( pabyData + 5 + 16, &z, 8 ); } } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( pabyData + 5 ); CPL_SWAPDOUBLE( pabyData + 5 + 8 ); if( getCoordinateDimension() == 3 ) CPL_SWAPDOUBLE( pabyData + 5 + 16 ); } return OGRERR_NONE; }
OGRErr OGRLineString::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the data count. */ /* -------------------------------------------------------------------- */ memcpy( pabyData+5, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ int i; if( getCoordinateDimension() == 3 ) { for( i = 0; i < nPointCount; i++ ) { memcpy( pabyData + 9 + 24*i, paoPoints+i, 16 ); memcpy( pabyData + 9 + 16 + 24*i, padfZ+i, 8 ); } } else memcpy( pabyData+9, paoPoints, 16 * nPointCount ); /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData+5, &nCount, 4 ); for( i = getCoordinateDimension() * nPointCount - 1; i >= 0; i-- ) { CPL_SWAP64PTR( pabyData + 9 + 8 * i ); } } return OGRERR_NONE; }
OGRErr OGRPoint::exportToWkt( char ** ppszDstText, OGRwkbVariant eWkbVariant ) const { char szTextEquiv[140]; char szCoordinate[80]; if ( IsEmpty() ) { if( getCoordinateDimension() == 3 && eWkbVariant == wkbVariantIso ) *ppszDstText = CPLStrdup("POINT Z EMPTY"); else *ppszDstText = CPLStrdup("POINT EMPTY"); } else { OGRMakeWktCoordinate(szCoordinate, x, y, z, getCoordinateDimension() ); if( getCoordinateDimension() == 3 && eWkbVariant == wkbVariantIso ) sprintf( szTextEquiv, "POINT Z (%s)", szCoordinate ); else sprintf( szTextEquiv, "POINT (%s)", szCoordinate ); *ppszDstText = CPLStrdup( szTextEquiv ); } return OGRERR_NONE; }
OGRwkbGeometryType OGRMultiCurve::getGeometryType() const { if( getCoordinateDimension() == 3 ) return wkbMultiCurveZ; else return wkbMultiCurve; }
int OGRPoint::WkbSize() const { if( getCoordinateDimension() != 3 ) return 21; else return 29; }
OGRwkbGeometryType OGRGeometryCollection::getGeometryType() const { if( getCoordinateDimension() == 3 ) return wkbGeometryCollection25D; else return wkbGeometryCollection; }
OGRwkbGeometryType OGRLineString::getGeometryType() { if( getCoordinateDimension() == 3 ) return wkbLineString25D; else return wkbLineString; }
OGRwkbGeometryType OGRMultiLineString::getGeometryType() const { if( getCoordinateDimension() == 3 ) return wkbMultiLineString25D; else return wkbMultiLineString; }
OGRwkbGeometryType OGRMultiPoint::getGeometryType() const { if( getCoordinateDimension() == 3 ) return wkbMultiPoint25D; else return wkbMultiPoint; }
OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { int nOffset; int b3D = getCoordinateDimension() == 3; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nRingCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nRingCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the rings. */ /* ==================================================================== */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { papoRings[iRing]->_exportToWkb( eByteOrder, b3D, pabyData + nOffset ); nOffset += papoRings[iRing]->_WkbSize(b3D); } return OGRERR_NONE; }
void OGRLineString::getPoint( int i, OGRPoint * poPoint ) { assert( i >= 0 ); assert( i < nPointCount ); assert( poPoint != NULL ); poPoint->setX( paoPoints[i].x ); poPoint->setY( paoPoints[i].y ); if( getCoordinateDimension() == 3 ) poPoint->setZ( padfZ[i] ); }
int OGRPolygon::WkbSize() const { int nSize = 9; int b3D = getCoordinateDimension() == 3; for( int i = 0; i < nRingCount; i++ ) { nSize += papoRings[i]->_WkbSize( b3D ); } return nSize; }
void OGRLineString::Value( double dfDistance, OGRPoint * poPoint ) const { double dfLength = 0; int i; if( dfDistance < 0 ) { StartPoint( poPoint ); return; } for( i = 0; i < nPointCount-1; i++ ) { double dfDeltaX, dfDeltaY, dfSegLength; dfDeltaX = paoPoints[i+1].x - paoPoints[i].x; dfDeltaY = paoPoints[i+1].y - paoPoints[i].y; dfSegLength = sqrt(dfDeltaX*dfDeltaX + dfDeltaY*dfDeltaY); if (dfSegLength > 0) { if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >= dfDistance) ) { double dfRatio; dfRatio = (dfDistance - dfLength) / dfSegLength; poPoint->setX( paoPoints[i].x * (1 - dfRatio) + paoPoints[i+1].x * dfRatio ); poPoint->setY( paoPoints[i].y * (1 - dfRatio) + paoPoints[i+1].y * dfRatio ); if( getCoordinateDimension() == 3 ) poPoint->setZ( padfZ[i] * (1 - dfRatio) + padfZ[i] * dfRatio ); return; } dfLength += dfSegLength; } } EndPoint( poPoint ); }
void OGRLineString::setPoint( int iPoint, double xIn, double yIn, double zIn ) { if( iPoint >= nPointCount ) setNumPoints( iPoint+1 ); paoPoints[iPoint].x = xIn; paoPoints[iPoint].y = yIn; if( zIn != 0.0 ) { Make3D(); padfZ[iPoint] = zIn; } else if( getCoordinateDimension() == 3 ) { padfZ[iPoint] = 0.0; } }
void OGRLinearRing::closeRings() { if( nPointCount < 2 ) return; if( getX(0) != getX(nPointCount-1) || getY(0) != getY(nPointCount-1) || getZ(0) != getZ(nPointCount-1) ) { /* Avoid implicit change of coordinate dimensionality * if z=0.0 and dim=2 */ if( getCoordinateDimension() == 2 ) addPoint( getX(0), getY(0) ); else addPoint( getX(0), getY(0), getZ(0) ); } }
OGRLineString* OGRCircularString::CurveToLine( double dfMaxAngleStepSizeDegrees, const char* const* papszOptions ) const { OGRLineString* poLine = new OGRLineString(); poLine->assignSpatialReference(getSpatialReference()); const bool bHasZ = getCoordinateDimension() == 3; for( int i = 0; i < nPointCount - 2; i += 2 ) { OGRLineString* poArc = OGRGeometryFactory::curveToLineString( paoPoints[i].x, paoPoints[i].y, padfZ ? padfZ[i] : 0.0, paoPoints[i+1].x, paoPoints[i+1].y, padfZ ? padfZ[i+1] : 0.0, paoPoints[i+2].x, paoPoints[i+2].y, padfZ ? padfZ[i+2] : 0.0, bHasZ, dfMaxAngleStepSizeDegrees, papszOptions); poLine->addSubLineString(poArc, (i == 0) ? 0 : 1); delete poArc; } return poLine; }
void OGRLinearRing::reverseWindingOrder() { int pos = 0; OGRPoint tempPoint; for( int i = 0; i < nPointCount / 2; i++ ) { getPoint( i, &tempPoint ); pos = nPointCount - i - 1; if( getCoordinateDimension() == 2 ) { setPoint( i, getX(pos), getY(pos) ); setPoint( pos, tempPoint.getX(), tempPoint.getY() ); } else { setPoint( i, getX(pos), getY(pos), getZ(pos) ); setPoint( pos, tempPoint.getX(), tempPoint.getY(), tempPoint.getZ() ); } } }
OGRErr OGRLineString::exportToWkt( char ** ppszReturn ) { int nMaxString = nPointCount * 16 * 2 + 20; int nRetLen = 0; *ppszReturn = (char *) VSIMalloc( nMaxString ); if( *ppszReturn == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; sprintf( *ppszReturn, "%s (", getGeometryName() ); for( int i = 0; i < nPointCount; i++ ) { assert( nMaxString > (int) strlen(*ppszReturn+nRetLen) + 32 + nRetLen); if( i > 0 ) strcat( *ppszReturn + nRetLen, "," ); if( getCoordinateDimension() == 3 ) strcat( *ppszReturn + nRetLen, OGRMakeWktCoordinate( paoPoints[i].x, paoPoints[i].y, padfZ[i] ) ); else strcat( *ppszReturn + nRetLen, OGRMakeWktCoordinate( paoPoints[i].x, paoPoints[i].y, 0.0 ) ); nRetLen += strlen(*ppszReturn + nRetLen); } strcat( *ppszReturn+nRetLen, ")" ); return OGRERR_NONE; }
void OGRLineString::setNumPoints( int nNewPointCount ) { if( nNewPointCount == 0 ) { OGRFree( paoPoints ); paoPoints = NULL; OGRFree( padfZ ); padfZ = NULL; nPointCount = 0; return; } if( nNewPointCount > nPointCount ) { paoPoints = (OGRRawPoint *) OGRRealloc(paoPoints, sizeof(OGRRawPoint) * nNewPointCount); assert( paoPoints != NULL ); memset( paoPoints + nPointCount, 0, sizeof(OGRRawPoint) * (nNewPointCount - nPointCount) ); if( getCoordinateDimension() == 3 ) { padfZ = (double *) OGRRealloc( padfZ, sizeof(double)*nNewPointCount ); memset( padfZ + nPointCount, 0, sizeof(double) * (nNewPointCount - nPointCount) ); } } nPointCount = nNewPointCount; }
OGRErr OGRLineString::exportToWkt( char ** ppszDstText ) const { int nMaxString = nPointCount * 20 * 3 + 20; int nRetLen = 0; /* -------------------------------------------------------------------- */ /* Handle special empty case. */ /* -------------------------------------------------------------------- */ if( nPointCount == 0 ) { *ppszDstText = CPLStrdup("LINESTRING(EMPTY)"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* General case. */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc( nMaxString ); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; sprintf( *ppszDstText, "%s (", getGeometryName() ); for( int i = 0; i < nPointCount; i++ ) { if( nMaxString <= (int) strlen(*ppszDstText+nRetLen) + 32 + nRetLen ) { CPLDebug( "OGR", "OGRLineString::exportToWkt() ... buffer overflow.\n" "nMaxString=%d, strlen(*ppszDstText) = %d, i=%d\n" "*ppszDstText = %s", nMaxString, strlen(*ppszDstText), i, *ppszDstText ); VSIFree( *ppszDstText ); *ppszDstText = NULL; return OGRERR_NOT_ENOUGH_MEMORY; } if( i > 0 ) strcat( *ppszDstText + nRetLen, "," ); nRetLen += strlen(*ppszDstText + nRetLen); if( getCoordinateDimension() == 3 ) OGRMakeWktCoordinate( *ppszDstText + nRetLen, paoPoints[i].x, paoPoints[i].y, padfZ[i] ); else OGRMakeWktCoordinate( *ppszDstText + nRetLen, paoPoints[i].x, paoPoints[i].y, 0.0 ); nRetLen += strlen(*ppszDstText + nRetLen); } strcat( *ppszDstText+nRetLen, ")" ); return OGRERR_NONE; }
int OGRLineString::WkbSize() { return 5 + 4 + 8 * nPointCount * getCoordinateDimension(); }
OGRErr OGRLineString::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = (unsigned char) eByteOrder; /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ if( eByteOrder == wkbNDR ) { pabyData[1] = wkbLineString; if( getCoordinateDimension() == 3 ) pabyData[2] = 0x80; else pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = 0; } else { pabyData[1] = 0; pabyData[2] = 0; if( getCoordinateDimension() == 3 ) pabyData[3] = 0x80; else pabyData[3] = 0; pabyData[4] = wkbLineString; } /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ memcpy( pabyData+5, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ int i; if( getCoordinateDimension() == 3 ) { for( i = 0; i < nPointCount; i++ ) { memcpy( pabyData + 9 + 24*i, paoPoints+i, 16 ); memcpy( pabyData + 9 + 16 + 24*i, padfZ+i, 8 ); } } else memcpy( pabyData+9, paoPoints, 16 * nPointCount ); /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData+5, &nCount, 4 ); for( i = getCoordinateDimension() * 3 - 1; i >= 0; i-- ) { CPL_SWAPDOUBLE( pabyData + 9 + 8 * i ); } } return OGRERR_NONE; }
void OGRCircularString::Value( double dfDistance, OGRPoint * poPoint ) const { if( dfDistance < 0 ) { StartPoint( poPoint ); return; } double dfLength = 0; for( int i = 0; i < nPointCount - 2; i += 2 ) { const double x0 = paoPoints[i].x; const double y0 = paoPoints[i].y; const double x1 = paoPoints[i+1].x; const double y1 = paoPoints[i+1].y; const double x2 = paoPoints[i+2].x; const double y2 = paoPoints[i+2].y; double R = 0.0; double cx = 0.0; double cy = 0.0; double alpha0 = 0.0; double alpha1 = 0.0; double alpha2 = 0.0; // We have strong constraints on the number of intermediate points // we can add. if( OGRGeometryFactory::GetCurveParmeters(x0, y0, x1, y1, x2, y2, R, cx, cy, alpha0, alpha1, alpha2) ) { // It is an arc circle. const double dfSegLength = fabs(alpha2 - alpha0) * R; if( dfSegLength > 0 ) { if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >= dfDistance) ) { const double dfRatio = (dfDistance - dfLength) / dfSegLength; const double alpha = alpha0 * (1 - dfRatio) + alpha2 * dfRatio; const double x = cx + R * cos(alpha); const double y = cy + R * sin(alpha); poPoint->setX( x ); poPoint->setY( y ); if( getCoordinateDimension() == 3 ) poPoint->setZ( padfZ[i] * (1 - dfRatio) + padfZ[i+2] * dfRatio ); return; } dfLength += dfSegLength; } } else { // It is a straight line. const double dfSegLength = dist(x0, y0, x2, y2); if( dfSegLength > 0 ) { if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >= dfDistance) ) { const double dfRatio = (dfDistance - dfLength) / dfSegLength; poPoint->setX( paoPoints[i].x * (1 - dfRatio) + paoPoints[i+2].x * dfRatio ); poPoint->setY( paoPoints[i].y * (1 - dfRatio) + paoPoints[i+2].y * dfRatio ); if( getCoordinateDimension() == 3 ) poPoint->setZ( padfZ[i] * (1 - dfRatio) + padfZ[i+2] * dfRatio ); return; } dfLength += dfSegLength; } } } EndPoint( poPoint ); }
OGRErr OGRMultiPoint::exportToWkt( char ** ppszDstText, OGRwkbVariant eWkbVariant ) const { int nMaxString = getNumGeometries() * 22 + 128; int nRetLen = 0; /* -------------------------------------------------------------------- */ /* Return MULTIPOINT EMPTY if we get no valid points. */ /* -------------------------------------------------------------------- */ if( IsEmpty() ) { if( getCoordinateDimension() == 3 && eWkbVariant == wkbVariantIso ) *ppszDstText = CPLStrdup("MULTIPOINT Z EMPTY"); else *ppszDstText = CPLStrdup("MULTIPOINT EMPTY"); return OGRERR_NONE; } *ppszDstText = (char *) VSIMalloc( nMaxString ); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; if( getCoordinateDimension() == 3 && eWkbVariant == wkbVariantIso ) sprintf( *ppszDstText, "%s Z (", getGeometryName() ); else sprintf( *ppszDstText, "%s (", getGeometryName() ); int bMustWriteComma = FALSE; for( int i = 0; i < getNumGeometries(); i++ ) { OGRPoint *poPoint = (OGRPoint *) getGeometryRef( i ); if (poPoint->IsEmpty()) { CPLDebug( "OGR", "OGRMultiPoint::exportToWkt() - skipping POINT EMPTY."); continue; } if( bMustWriteComma ) strcat( *ppszDstText + nRetLen, "," ); bMustWriteComma = TRUE; nRetLen += strlen(*ppszDstText + nRetLen); if( nMaxString < nRetLen + 100 ) { nMaxString = nMaxString * 2; *ppszDstText = (char *) CPLRealloc(*ppszDstText,nMaxString); } if( eWkbVariant == wkbVariantIso ) { strcat( *ppszDstText + nRetLen, "(" ); nRetLen ++; } OGRMakeWktCoordinate( *ppszDstText + nRetLen, poPoint->getX(), poPoint->getY(), poPoint->getZ(), poPoint->getCoordinateDimension() ); if( eWkbVariant == wkbVariantIso ) { strcat( *ppszDstText + nRetLen, ")" ); nRetLen ++; } } strcat( *ppszDstText+nRetLen, ")" ); return OGRERR_NONE; }
OGRErr OGRGeometryCollection::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { if( eWkbVariant == wkbVariantOldOgc && (wkbFlatten(getGeometryType()) == wkbMultiCurve || wkbFlatten(getGeometryType()) == wkbMultiSurface) ) { // Does not make sense for new geometries, so patch it. eWkbVariant = wkbVariantIso; } /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(static_cast<unsigned char>(eByteOrder)); /* -------------------------------------------------------------------- */ /* Set the geometry feature type, ensuring that 3D flag is */ /* preserved. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eWkbVariant == wkbVariantIso ) nGType = getIsoGeometryType(); else if( eWkbVariant == wkbVariantPostGIS1 ) { const bool bIs3D = wkbHasZ(static_cast<OGRwkbGeometryType>(nGType)); nGType = wkbFlatten(nGType); if( nGType == wkbMultiCurve ) nGType = POSTGIS15_MULTICURVE; else if( nGType == wkbMultiSurface ) nGType = POSTGIS15_MULTISURFACE; if( bIs3D ) // Yes, explicitly set wkb25DBit. nGType = static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse); } if( OGR_SWAP( eByteOrder ) ) { nGType = CPL_SWAP32(nGType); } memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount = CPL_SWAP32( nGeomCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nGeomCount, 4 ); } int nOffset = 9; /* ==================================================================== */ /* Serialize each of the Geoms. */ /* ==================================================================== */ int iGeom = 0; for( auto&& poSubGeom: *this ) { poSubGeom->exportToWkb( eByteOrder, pabyData + nOffset, eWkbVariant ); // Should normally not happen if everyone else does its job, // but has happened sometimes. (#6332) if( poSubGeom->getCoordinateDimension() != getCoordinateDimension() ) { CPLError(CE_Warning, CPLE_AppDefined, "Sub-geometry %d has coordinate dimension %d, " "but container has %d", iGeom, poSubGeom->getCoordinateDimension(), getCoordinateDimension() ); } nOffset += poSubGeom->WkbSize(); iGeom ++; } return OGRERR_NONE; }
OGRErr OGRPolygon::exportToWkt( char ** ppszDstText ) const { char **papszRings; int iRing, nCumulativeLength = 0, nNonEmptyRings = 0; OGRErr eErr; int bMustWriteComma = FALSE; /* -------------------------------------------------------------------- */ /* If we have no valid exterior ring, return POLYGON EMPTY. */ /* -------------------------------------------------------------------- */ if (getExteriorRing() == NULL || getExteriorRing()->IsEmpty()) { *ppszDstText = CPLStrdup("POLYGON EMPTY"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each ring. */ /* -------------------------------------------------------------------- */ papszRings = (char **) CPLCalloc(sizeof(char *),nRingCount); for( iRing = 0; iRing < nRingCount; iRing++ ) { papoRings[iRing]->setCoordinateDimension( getCoordinateDimension() ); if( papoRings[iRing]->getNumPoints() == 0 ) { papszRings[iRing] = NULL; continue; } eErr = papoRings[iRing]->exportToWkt( &(papszRings[iRing]) ); if( eErr != OGRERR_NONE ) goto error; CPLAssert( EQUALN(papszRings[iRing],"LINEARRING (", 12) ); nCumulativeLength += strlen(papszRings[iRing] + 11); nNonEmptyRings++; } /* -------------------------------------------------------------------- */ /* Allocate exactly the right amount of space for the */ /* aggregated string. */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nNonEmptyRings + 11); if( *ppszDstText == NULL ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ strcpy( *ppszDstText, "POLYGON (" ); nCumulativeLength = strlen(*ppszDstText); for( iRing = 0; iRing < nRingCount; iRing++ ) { if( papszRings[iRing] == NULL ) { CPLDebug( "OGR", "OGRPolygon::exportToWkt() - skipping empty ring."); continue; } if( bMustWriteComma ) (*ppszDstText)[nCumulativeLength++] = ','; bMustWriteComma = TRUE; int nRingLen = strlen(papszRings[iRing] + 11); memcpy( *ppszDstText + nCumulativeLength, papszRings[iRing] + 11, nRingLen ); nCumulativeLength += nRingLen; VSIFree( papszRings[iRing] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszRings ); return OGRERR_NONE; error: for( iRing = 0; iRing < nRingCount; iRing++ ) CPLFree(papszRings[iRing]); CPLFree(papszRings); return eErr; }