OGRErr OGRGeometryCollection::exportToWkt( char ** ppszDstText ) const { char **papszGeoms; int iGeom, nCumulativeLength = 0; OGRErr eErr; if( getNumGeometries() == 0 ) { *ppszDstText = CPLStrdup("GEOMETRYCOLLECTION(EMPTY)"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each Geom. */ /* -------------------------------------------------------------------- */ papszGeoms = (char **) CPLCalloc(sizeof(char *),nGeomCount); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { eErr = papoGeoms[iGeom]->exportToWkt( &(papszGeoms[iGeom]) ); if( eErr != OGRERR_NONE ) return eErr; nCumulativeLength += strlen(papszGeoms[iGeom]); } /* -------------------------------------------------------------------- */ /* Allocate the right amount of space for the aggregated string */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nGeomCount + 23); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ strcpy( *ppszDstText, getGeometryName() ); strcat( *ppszDstText, " (" ); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( iGeom > 0 ) strcat( *ppszDstText, "," ); strcat( *ppszDstText, papszGeoms[iGeom] ); VSIFree( papszGeoms[iGeom] ); } strcat( *ppszDstText, ")" ); CPLFree( papszGeoms ); return OGRERR_NONE; }
OGRErr OGRMultiPoint::exportToWkt( char ** ppszDstText ) const { int nMaxString = getNumGeometries() * 20 + 128; int nRetLen = 0; if( getNumGeometries() == 0 ) { *ppszDstText = CPLStrdup("MULTIPOINT(EMPTY)"); return OGRERR_NONE; } *ppszDstText = (char *) VSIMalloc( nMaxString ); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; sprintf( *ppszDstText, "%s (", getGeometryName() ); for( int i = 0; i < getNumGeometries(); i++ ) { OGRPoint *poPoint = (OGRPoint *) getGeometryRef( i ); if( i > 0 ) strcat( *ppszDstText + nRetLen, "," ); nRetLen += strlen(*ppszDstText + nRetLen); if( nMaxString < nRetLen + 100 ) { nMaxString = nMaxString * 2; *ppszDstText = (char *) CPLRealloc(*ppszDstText,nMaxString); } if( poPoint->getCoordinateDimension() == 3 ) OGRMakeWktCoordinate( *ppszDstText + nRetLen, poPoint->getX(), poPoint->getY(), poPoint->getZ() ); else OGRMakeWktCoordinate( *ppszDstText + nRetLen, poPoint->getX(), poPoint->getY(), 0.0 ); } strcat( *ppszDstText+nRetLen, ")" ); return OGRERR_NONE; }
OGRErr OGRLineString::importFromWkt( char ** ppszInput ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; if( paoPoints != NULL ) { nPointCount = 0; CPLFree( paoPoints ); paoPoints = NULL; CPLFree( padfZ ); padfZ = NULL; } /* -------------------------------------------------------------------- */ /* Read and verify the ``LINESTRING'' keyword token. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Read the point list which should consist of exactly one point. */ /* -------------------------------------------------------------------- */ int nMaxPoint = 0; nPointCount = 0; pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoint, &nPointCount ); if( pszInput == NULL ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
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; }
OGRErr OGRMultiPoint::importFromWkt( char ** ppszInput ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; int iGeom; OGRErr eErr = OGRERR_NONE; /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Read and verify the type keyword, and ensure it matches the */ /* actual type of this container. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Skip past first bracket for checking purposes, but don't */ /* alter pszInput. */ /* -------------------------------------------------------------------- */ const char *pszPreScan = pszInput; // skip white space. while( *pszPreScan == ' ' || *pszPreScan == '\t' ) pszPreScan++; // Skip outer bracket. if( *pszPreScan != '(' ) return OGRERR_CORRUPT_DATA; pszPreScan++; /* -------------------------------------------------------------------- */ /* If the next token is EMPTY, then verify that we have proper */ /* EMPTY format will a trailing closing bracket. */ /* -------------------------------------------------------------------- */ OGRWktReadToken( pszPreScan, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszPreScan, szToken ); pszInput = OGRWktReadToken( pszInput, szToken ); *ppszInput = (char *) pszInput; if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Check for inner bracket indicating the improper bracketed */ /* format which we still want to support. */ /* -------------------------------------------------------------------- */ // skip white space. while( *pszPreScan == ' ' || *pszPreScan == '\t' ) pszPreScan++; // Do we have an inner bracket? if( *pszPreScan == '(' ) return importFromWkt_Bracketed( ppszInput ); /* -------------------------------------------------------------------- */ /* Read the point list which should consist of exactly one point. */ /* -------------------------------------------------------------------- */ int nMaxPoint = 0; int nPointCount = 0; OGRRawPoint *paoPoints = NULL; double *padfZ = NULL; pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoint, &nPointCount ); if( pszInput == NULL ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Transform raw points into point objects. */ /* -------------------------------------------------------------------- */ for( iGeom = 0; iGeom < nPointCount && eErr == OGRERR_NONE; iGeom++ ) { OGRGeometry *poGeom; if( padfZ ) poGeom = new OGRPoint( paoPoints[iGeom].x, paoPoints[iGeom].y, padfZ[iGeom] ); else poGeom = new OGRPoint( paoPoints[iGeom].x, paoPoints[iGeom].y ); eErr = addGeometryDirectly( poGeom ); } OGRFree( paoPoints ); if( padfZ ) OGRFree( padfZ ); if( eErr != OGRERR_NONE ) return eErr; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
OGRErr OGRPolygon::exportToWkt( char ** ppszDstText, OGRwkbVariant eWkbVariant ) const { bool bMustWriteComma = false; /* -------------------------------------------------------------------- */ /* If we have no valid exterior ring, return POLYGON EMPTY. */ /* -------------------------------------------------------------------- */ if( getExteriorRing() == NULL || getExteriorRing()->IsEmpty() ) { if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " ZM EMPTY").c_str()); else if( flags & OGR_G_MEASURED ) *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " M EMPTY").c_str()); else if( flags & OGR_G_3D ) *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " Z EMPTY").c_str()); else *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " EMPTY").c_str()); } else *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " EMPTY").c_str()); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each ring. */ /* -------------------------------------------------------------------- */ char **papszRings = static_cast<char **>(CPLCalloc(sizeof(char *), oCC.nCurveCount)); size_t nCumulativeLength = 0; size_t nNonEmptyRings = 0; size_t *pnRingBeginning = static_cast<size_t *>(CPLCalloc(sizeof(size_t), oCC.nCurveCount)); OGRErr eErr; for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { OGRLinearRing* poLR = (OGRLinearRing*) oCC.papoCurves[iRing]; //poLR->setFlags( getFlags() ); poLR->set3D(Is3D()); poLR->setMeasured(IsMeasured()); if( poLR->getNumPoints() == 0 ) { papszRings[iRing] = NULL; continue; } eErr = poLR->exportToWkt( &(papszRings[iRing]), eWkbVariant ); if( eErr != OGRERR_NONE ) goto error; if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING ZM (") ) pnRingBeginning[iRing] = 14; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING M (") ) pnRingBeginning[iRing] = 13; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING Z (") ) pnRingBeginning[iRing] = 13; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING (") ) pnRingBeginning[iRing] = 11; else { CPLAssert(false); } nCumulativeLength += strlen(papszRings[iRing] + pnRingBeginning[iRing]); nNonEmptyRings++; } /* -------------------------------------------------------------------- */ /* Allocate exactly the right amount of space for the */ /* aggregated string. */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSI_MALLOC_VERBOSE( nCumulativeLength + nNonEmptyRings + strlen(getGeometryName()) + strlen(" ZM ()") + 1); if( *ppszDstText == NULL ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) strcpy( *ppszDstText, (CPLString(getGeometryName()) + " ZM (").c_str() ); else if( flags & OGR_G_MEASURED ) strcpy( *ppszDstText, (CPLString(getGeometryName()) + " M (").c_str() ); else if( flags & OGR_G_3D ) strcpy( *ppszDstText, (CPLString(getGeometryName()) + " Z (").c_str() ); else strcpy( *ppszDstText, (CPLString(getGeometryName()) + " (").c_str() ); } else strcpy( *ppszDstText, (CPLString(getGeometryName()) + " (").c_str() ); nCumulativeLength = strlen(*ppszDstText); for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { if( papszRings[iRing] == NULL ) { CPLDebug( "OGR", "OGRPolygon::exportToWkt() - skipping empty ring."); continue; } if( bMustWriteComma ) (*ppszDstText)[nCumulativeLength++] = ','; bMustWriteComma = true; size_t nRingLen = strlen(papszRings[iRing] + pnRingBeginning[iRing]); memcpy( *ppszDstText + nCumulativeLength, papszRings[iRing] + pnRingBeginning[iRing], nRingLen ); nCumulativeLength += nRingLen; VSIFree( papszRings[iRing] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszRings ); CPLFree( pnRingBeginning ); return OGRERR_NONE; error: for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) CPLFree(papszRings[iRing]); CPLFree(papszRings); return eErr; }
OGRErr OGRGeometryCollection::importFromWkt( char ** ppszInput ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; int iGeom; /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ if( nGeomCount > 0 ) { for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) delete papoGeoms[iGeom]; nGeomCount = 0; CPLFree( papoGeoms ); } /* -------------------------------------------------------------------- */ /* Read and verify the type keyword, and ensure it matches the */ /* actual type of this container. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* The next character should be a ( indicating the start of the */ /* list of objects. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( szToken[0] != '(' ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* If the next token is EMPTY, then verify that we have proper */ /* EMPTY format will a trailing closing bracket. */ /* -------------------------------------------------------------------- */ OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszInput, szToken ); pszInput = OGRWktReadToken( pszInput, szToken ); *ppszInput = (char *) pszInput; if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else return OGRERR_NONE; } /* ==================================================================== */ /* Read each subgeometry in turn. */ /* ==================================================================== */ do { OGRGeometry *poGeom = NULL; OGRErr eErr; eErr = OGRGeometryFactory::createFromWkt( (char **) &pszInput, NULL, &poGeom ); if( eErr != OGRERR_NONE ) return eErr; addGeometryDirectly( poGeom ); /* -------------------------------------------------------------------- */ /* Read the delimeter following the ring. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); } while( szToken[0] == ',' ); /* -------------------------------------------------------------------- */ /* freak if we don't get a closing bracket. */ /* -------------------------------------------------------------------- */ if( szToken[0] != ')' ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
OGRErr OGRMultiLineString::importFromWkt( char ** ppszInput ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; OGRErr eErr; /* -------------------------------------------------------------------- */ /* Clear existing rings. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Read and verify the ``MULTILINESTRING'' keyword token. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* The next character should be a ( indicating the start of the */ /* list of linestrings. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszInput; return OGRERR_NONE; } if( szToken[0] != '(' ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* If the next token is EMPTY, then verify that we have proper */ /* EMPTY format will a trailing closing bracket. */ /* -------------------------------------------------------------------- */ OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszInput, szToken ); pszInput = OGRWktReadToken( pszInput, szToken ); *ppszInput = (char *) pszInput; if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else return OGRERR_NONE; } /* ==================================================================== */ /* Read each line in turn. Note that we try to reuse the same */ /* point list buffer from ring to ring to cut down on */ /* allocate/deallocate overhead. */ /* ==================================================================== */ OGRRawPoint *paoPoints = NULL; int nMaxPoints = 0; double *padfZ = NULL; do { int nPoints = 0; /* -------------------------------------------------------------------- */ /* Read points for one line from input. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoints, &nPoints ); if( pszInput == NULL ) { eErr = OGRERR_CORRUPT_DATA; break; } /* -------------------------------------------------------------------- */ /* Create the new line, and add to collection. */ /* -------------------------------------------------------------------- */ OGRLineString *poLine; poLine = new OGRLineString(); poLine->setPoints( nPoints, paoPoints, padfZ ); eErr = addGeometryDirectly( poLine ); /* -------------------------------------------------------------------- */ /* Read the delimeter following the ring. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); } while( szToken[0] == ',' && eErr == OGRERR_NONE ); /* -------------------------------------------------------------------- */ /* freak if we don't get a closing bracket. */ /* -------------------------------------------------------------------- */ CPLFree( paoPoints ); CPLFree( padfZ ); if( eErr != OGRERR_NONE ) return eErr; if( szToken[0] != ')' ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
OGRErr OGRGeometryCollection::importFromWkt( char ** ppszInput ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Read and verify the type keyword, and ensure it matches the */ /* actual type of this container. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Check for EMPTY ... */ /* -------------------------------------------------------------------- */ const char *pszPreScan; int bHasZ = FALSE, bHasM = FALSE; pszPreScan = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszPreScan; empty(); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Check for Z, M or ZM. Will ignore the Measure */ /* -------------------------------------------------------------------- */ else if( EQUAL(szToken,"Z") ) { bHasZ = TRUE; } else if( EQUAL(szToken,"M") ) { bHasM = TRUE; } else if( EQUAL(szToken,"ZM") ) { bHasZ = TRUE; bHasM = TRUE; } if (bHasZ || bHasM) { pszInput = pszPreScan; pszPreScan = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszPreScan; empty(); /* FIXME?: In theory we should store the dimension and M presence */ /* if we want to allow round-trip with ExportToWKT v1.2 */ return OGRERR_NONE; } } if( !EQUAL(szToken,"(") ) return OGRERR_CORRUPT_DATA; if ( !bHasZ && !bHasM ) { /* Test for old-style GEOMETRYCOLLECTION(EMPTY) */ pszPreScan = OGRWktReadToken( pszPreScan, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszPreScan, szToken ); if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else { *ppszInput = (char *) pszInput; empty(); return OGRERR_NONE; } } } /* Skip first '(' */ pszInput = OGRWktReadToken( pszInput, szToken ); /* ==================================================================== */ /* Read each subgeometry in turn. */ /* ==================================================================== */ do { OGRGeometry *poGeom = NULL; OGRErr eErr; eErr = OGRGeometryFactory::createFromWkt( (char **) &pszInput, NULL, &poGeom ); if( eErr != OGRERR_NONE ) return eErr; addGeometryDirectly( poGeom ); /* -------------------------------------------------------------------- */ /* Read the delimeter following the ring. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); } while( szToken[0] == ',' ); /* -------------------------------------------------------------------- */ /* freak if we don't get a closing bracket. */ /* -------------------------------------------------------------------- */ if( szToken[0] != ')' ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
//! @cond Doxygen_Suppress OGRErr OGRGeometryCollection::exportToWktInternal( char ** ppszDstText, OGRwkbVariant eWkbVariant, const char* pszSkipPrefix ) const { size_t nCumulativeLength = 0; OGRErr eErr = OGRERR_NONE; bool bMustWriteComma = false; /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each Geom. */ /* -------------------------------------------------------------------- */ char **papszGeoms = nGeomCount ? static_cast<char **>(CPLCalloc(sizeof(char *), nGeomCount)) : nullptr; for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { eErr = papoGeoms[iGeom]->exportToWkt(&(papszGeoms[iGeom]), eWkbVariant); if( eErr != OGRERR_NONE ) goto error; size_t nSkip = 0; if( pszSkipPrefix != nullptr && EQUALN(papszGeoms[iGeom], pszSkipPrefix, strlen(pszSkipPrefix)) && papszGeoms[iGeom][strlen(pszSkipPrefix)] == ' ' ) { nSkip = strlen(pszSkipPrefix) + 1; if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "ZM ") ) nSkip += 3; else if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "M ") ) nSkip += 2; if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "Z ") ) nSkip += 2; // Skip empty subgeoms. if( papszGeoms[iGeom][nSkip] != '(' ) { CPLDebug( "OGR", "OGRGeometryCollection::exportToWkt() - skipping %s.", papszGeoms[iGeom] ); CPLFree( papszGeoms[iGeom] ); papszGeoms[iGeom] = nullptr; continue; } } else if( eWkbVariant != wkbVariantIso ) { char *substr = nullptr; // TODO(schwehr): Looks dangerous. Cleanup. if( (substr = strstr(papszGeoms[iGeom], " Z")) != nullptr ) memmove(substr, substr + strlen(" Z"), 1 + strlen(substr + strlen(" Z"))); } nCumulativeLength += strlen(papszGeoms[iGeom] + nSkip); } /* -------------------------------------------------------------------- */ /* Return XXXXXXXXXXXXXXX EMPTY if we get no valid line string. */ /* -------------------------------------------------------------------- */ if( nCumulativeLength == 0 ) { CPLFree( papszGeoms ); CPLString osEmpty; if( eWkbVariant == wkbVariantIso ) { if( Is3D() && IsMeasured() ) osEmpty.Printf("%s ZM EMPTY", getGeometryName()); else if( IsMeasured() ) osEmpty.Printf("%s M EMPTY", getGeometryName()); else if( Is3D() ) osEmpty.Printf("%s Z EMPTY", getGeometryName()); else osEmpty.Printf("%s EMPTY", getGeometryName()); } else { osEmpty.Printf("%s EMPTY", getGeometryName()); } *ppszDstText = CPLStrdup(osEmpty); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Allocate the right amount of space for the aggregated string */ /* -------------------------------------------------------------------- */ *ppszDstText = static_cast<char *>( VSI_MALLOC_VERBOSE(nCumulativeLength + nGeomCount + 26)); if( *ppszDstText == nullptr ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ strcpy( *ppszDstText, getGeometryName() ); if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) strcat( *ppszDstText, " ZM" ); else if( flags & OGR_G_3D ) strcat( *ppszDstText, " Z" ); else if( flags & OGR_G_MEASURED ) strcat( *ppszDstText, " M" ); } strcat( *ppszDstText, " (" ); nCumulativeLength = strlen(*ppszDstText); for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( papszGeoms[iGeom] == nullptr ) continue; if( bMustWriteComma ) (*ppszDstText)[nCumulativeLength++] = ','; bMustWriteComma = true; size_t nSkip = 0; if( pszSkipPrefix != nullptr && EQUALN(papszGeoms[iGeom], pszSkipPrefix, strlen(pszSkipPrefix)) && papszGeoms[iGeom][strlen(pszSkipPrefix)] == ' ' ) { nSkip = strlen(pszSkipPrefix) + 1; if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "ZM ") ) nSkip += 3; else if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "M ") ) nSkip += 2; else if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "Z ") ) nSkip += 2; } const size_t nGeomLength = strlen(papszGeoms[iGeom] + nSkip); memcpy( *ppszDstText + nCumulativeLength, papszGeoms[iGeom] + nSkip, nGeomLength ); nCumulativeLength += nGeomLength; VSIFree( papszGeoms[iGeom] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszGeoms ); return OGRERR_NONE; error: for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) CPLFree( papszGeoms[iGeom] ); CPLFree( papszGeoms ); return eErr; }
OGRErr OGRGeometryCollection::importFromWktInternal( char ** ppszInput, int nRecLevel ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; /* Arbitrary value, but certainly large enough for reasonable usages ! */ if( nRecLevel == 32 ) { CPLError( CE_Failure, CPLE_AppDefined, "Too many recursiong level (%d) while parsing WKT geometry.", nRecLevel ); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Read and verify the type keyword, and ensure it matches the */ /* actual type of this container. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Check for EMPTY ... */ /* -------------------------------------------------------------------- */ const char *pszPreScan; int bHasZ = FALSE, bHasM = FALSE; pszPreScan = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszPreScan; empty(); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Check for Z, M or ZM. Will ignore the Measure */ /* -------------------------------------------------------------------- */ else if( EQUAL(szToken,"Z") ) { bHasZ = TRUE; } else if( EQUAL(szToken,"M") ) { bHasM = TRUE; } else if( EQUAL(szToken,"ZM") ) { bHasZ = TRUE; bHasM = TRUE; } if (bHasZ || bHasM) { pszInput = pszPreScan; pszPreScan = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszPreScan; empty(); /* FIXME?: In theory we should store the dimension and M presence */ /* if we want to allow round-trip with ExportToWKT v1.2 */ return OGRERR_NONE; } } if( !EQUAL(szToken,"(") ) return OGRERR_CORRUPT_DATA; if ( !bHasZ && !bHasM ) { /* Test for old-style GEOMETRYCOLLECTION(EMPTY) */ pszPreScan = OGRWktReadToken( pszPreScan, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszPreScan, szToken ); if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else { *ppszInput = (char *) pszInput; empty(); return OGRERR_NONE; } } } /* Skip first '(' */ pszInput = OGRWktReadToken( pszInput, szToken ); /* ==================================================================== */ /* Read each subgeometry in turn. */ /* ==================================================================== */ do { OGRGeometry *poGeom = NULL; OGRErr eErr; /* -------------------------------------------------------------------- */ /* Get the first token, which should be the geometry type. */ /* -------------------------------------------------------------------- */ if( OGRWktReadToken( pszInput, szToken ) == NULL ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Do the import. */ /* -------------------------------------------------------------------- */ if (EQUAL(szToken,"GEOMETRYCOLLECTION")) { poGeom = new OGRGeometryCollection(); eErr = ((OGRGeometryCollection*)poGeom)-> importFromWktInternal( (char **) &pszInput, nRecLevel + 1 ); } else eErr = OGRGeometryFactory::createFromWkt( (char **) &pszInput, NULL, &poGeom ); if( eErr != OGRERR_NONE ) return eErr; addGeometryDirectly( poGeom ); /* -------------------------------------------------------------------- */ /* Read the delimeter following the ring. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); } while( szToken[0] == ',' ); /* -------------------------------------------------------------------- */ /* freak if we don't get a closing bracket. */ /* -------------------------------------------------------------------- */ if( szToken[0] != ')' ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
OGRErr OGRMultiPoint::exportToWkt( char ** ppszDstText, OGRwkbVariant eWkbVariant ) const { size_t nMaxString = static_cast<size_t>(getNumGeometries()) * 22 + 130; size_t nRetLen = 0; /* -------------------------------------------------------------------- */ /* Return MULTIPOINT EMPTY if we get no valid points. */ /* -------------------------------------------------------------------- */ if( IsEmpty() ) { if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) *ppszDstText = CPLStrdup("MULTIPOINT ZM EMPTY"); else if( flags & OGR_G_MEASURED ) *ppszDstText = CPLStrdup("MULTIPOINT M EMPTY"); else if( flags & OGR_G_3D ) *ppszDstText = CPLStrdup("MULTIPOINT Z EMPTY"); else *ppszDstText = CPLStrdup("MULTIPOINT EMPTY"); } else *ppszDstText = CPLStrdup("MULTIPOINT EMPTY"); return OGRERR_NONE; } *ppszDstText = static_cast<char *>(VSI_MALLOC_VERBOSE( nMaxString )); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) snprintf( *ppszDstText, nMaxString, "%s ZM (", getGeometryName() ); else if( flags & OGR_G_MEASURED ) snprintf( *ppszDstText, nMaxString, "%s M (", getGeometryName() ); else if( flags & OGR_G_3D ) snprintf( *ppszDstText, nMaxString, "%s Z (", getGeometryName() ); else snprintf( *ppszDstText, nMaxString, "%s (", getGeometryName() ); } else snprintf( *ppszDstText, nMaxString, "%s (", getGeometryName() ); bool 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 = static_cast<char *>(CPLRealloc(*ppszDstText, nMaxString)); } if( eWkbVariant == wkbVariantIso ) { strcat( *ppszDstText + nRetLen, "(" ); nRetLen++; } OGRMakeWktCoordinateM( *ppszDstText + nRetLen, poPoint->getX(), poPoint->getY(), poPoint->getZ(), poPoint->getM(), poPoint->Is3D(), poPoint->IsMeasured() && (eWkbVariant == wkbVariantIso)); if( eWkbVariant == wkbVariantIso ) { strcat( *ppszDstText + nRetLen, ")" ); nRetLen++; } } strcat( *ppszDstText+nRetLen, ")" ); return OGRERR_NONE; }
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; }
OGRErr OGRLineString::importFromWkt( char ** ppszInput ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; if( paoPoints != NULL ) { nPointCount = 0; CPLFree( paoPoints ); paoPoints = NULL; CPLFree( padfZ ); padfZ = NULL; } /* -------------------------------------------------------------------- */ /* Read and verify the ``LINESTRING'' keyword token. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Check for EMPTY ... but treat like a point at 0,0. */ /* -------------------------------------------------------------------- */ const char *pszPreScan; pszPreScan = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,"(") ) return OGRERR_CORRUPT_DATA; pszPreScan = OGRWktReadToken( pszPreScan, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszPreScan = OGRWktReadToken( pszPreScan, szToken ); *ppszInput = (char *) pszPreScan; if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Read the point list. */ /* -------------------------------------------------------------------- */ int nMaxPoint = 0; nPointCount = 0; pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoint, &nPointCount ); if( pszInput == NULL ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
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; }