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; }
static bool OGR2KMLGeometryAppend( OGRGeometry *poGeometry, char **ppszText, size_t *pnLength, size_t *pnMaxLength, char *szAltitudeMode ) { /* -------------------------------------------------------------------- */ /* 2D Point */ /* -------------------------------------------------------------------- */ if( poGeometry->getGeometryType() == wkbPoint ) { OGRPoint* poPoint = static_cast<OGRPoint*>(poGeometry); if (poPoint->getCoordinateDimension() == 0) { _GrowBuffer( *pnLength + 10, ppszText, pnMaxLength ); strcat( *ppszText + *pnLength, "<Point/>"); *pnLength += strlen( *ppszText + *pnLength ); } else { char szCoordinate[256] = { 0 }; MakeKMLCoordinate( szCoordinate, sizeof(szCoordinate), poPoint->getX(), poPoint->getY(), 0.0, FALSE ); _GrowBuffer( *pnLength + strlen(szCoordinate) + 60, ppszText, pnMaxLength ); snprintf( *ppszText + *pnLength, *pnMaxLength - *pnLength, "<Point><coordinates>%s</coordinates></Point>", szCoordinate ); *pnLength += strlen( *ppszText + *pnLength ); } } /* -------------------------------------------------------------------- */ /* 3D Point */ /* -------------------------------------------------------------------- */ else if( poGeometry->getGeometryType() == wkbPoint25D ) { char szCoordinate[256] = { 0 }; OGRPoint *poPoint = static_cast<OGRPoint*>(poGeometry); MakeKMLCoordinate( szCoordinate, sizeof(szCoordinate), poPoint->getX(), poPoint->getY(), poPoint->getZ(), true ); if (NULL == szAltitudeMode) { _GrowBuffer( *pnLength + strlen(szCoordinate) + 70, ppszText, pnMaxLength ); snprintf( *ppszText + *pnLength, *pnMaxLength - *pnLength, "<Point><coordinates>%s</coordinates></Point>", szCoordinate ); } else { _GrowBuffer( *pnLength + strlen(szCoordinate) + strlen(szAltitudeMode) + 70, ppszText, pnMaxLength ); snprintf( *ppszText + *pnLength, *pnMaxLength - *pnLength, "<Point>%s<coordinates>%s</coordinates></Point>", szAltitudeMode, szCoordinate ); } *pnLength += strlen( *ppszText + *pnLength ); } /* -------------------------------------------------------------------- */ /* LineString and LinearRing */ /* -------------------------------------------------------------------- */ else if( poGeometry->getGeometryType() == wkbLineString || poGeometry->getGeometryType() == wkbLineString25D ) { const bool bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING"); if( bRing ) AppendString( ppszText, pnLength, pnMaxLength, "<LinearRing>" ); else AppendString( ppszText, pnLength, pnMaxLength, "<LineString>" ); if (NULL != szAltitudeMode) { AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode); } AppendCoordinateList( reinterpret_cast<OGRLineString *>(poGeometry), ppszText, pnLength, pnMaxLength ); if( bRing ) AppendString( ppszText, pnLength, pnMaxLength, "</LinearRing>" ); else AppendString( ppszText, pnLength, pnMaxLength, "</LineString>" ); } /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ else if( poGeometry->getGeometryType() == wkbPolygon || poGeometry->getGeometryType() == wkbPolygon25D ) { OGRPolygon* poPolygon = static_cast<OGRPolygon*>(poGeometry); AppendString( ppszText, pnLength, pnMaxLength, "<Polygon>" ); if (NULL != szAltitudeMode) { AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode); } if( poPolygon->getExteriorRing() != NULL ) { AppendString( ppszText, pnLength, pnMaxLength, "<outerBoundaryIs>" ); if( !OGR2KMLGeometryAppend( poPolygon->getExteriorRing(), ppszText, pnLength, pnMaxLength, szAltitudeMode ) ) { return false; } AppendString( ppszText, pnLength, pnMaxLength, "</outerBoundaryIs>" ); } for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ ) { OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing); AppendString( ppszText, pnLength, pnMaxLength, "<innerBoundaryIs>" ); if( !OGR2KMLGeometryAppend( poRing, ppszText, pnLength, pnMaxLength, szAltitudeMode ) ) { return false; } AppendString( ppszText, pnLength, pnMaxLength, "</innerBoundaryIs>" ); } AppendString( ppszText, pnLength, pnMaxLength, "</Polygon>" ); } /* -------------------------------------------------------------------- */ /* MultiPolygon */ /* -------------------------------------------------------------------- */ else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection ) { OGRGeometryCollection* poGC = NULL; poGC = static_cast<OGRGeometryCollection*>(poGeometry); AppendString( ppszText, pnLength, pnMaxLength, "<MultiGeometry>" ); // XXX - mloskot //if (NULL != szAltitudeMode) //{ // AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode); //} for( int iMember = 0; iMember < poGC->getNumGeometries(); iMember++) { OGRGeometry *poMember = poGC->getGeometryRef( iMember ); if( !OGR2KMLGeometryAppend( poMember, ppszText, pnLength, pnMaxLength, szAltitudeMode ) ) { return false; } } AppendString( ppszText, pnLength, pnMaxLength, "</MultiGeometry>" ); } else { return false; } return true; }
ElementPtr geom2kml ( OGRGeometry * poOgrGeom, int extra, KmlFactory * poKmlFactory ) { int i; if ( !poOgrGeom ) { return NULL; } /***** ogr geom vars *****/ OGRPoint *poOgrPoint = NULL; OGRLineString *poOgrLineString; OGRPolygon *poOgrPolygon; OGRGeometryCollection *poOgrMultiGeom; /***** libkml geom vars *****/ CoordinatesPtr coordinates; PointPtr poKmlPoint; LineStringPtr poKmlLineString; LinearRingPtr poKmlLinearRing; OuterBoundaryIsPtr poKmlOuterRing; InnerBoundaryIsPtr poKmlInnerRing; PolygonPtr poKmlPolygon; MultiGeometryPtr poKmlMultiGeometry; ElementPtr poKmlGeometry; ElementPtr poKmlTmpGeometry; /***** other vars *****/ double x, y, z; int numpoints = 0; int nGeom; OGRwkbGeometryType type = poOgrGeom->getGeometryType ( ); switch ( type ) { case wkbPoint: poOgrPoint = ( OGRPoint * ) poOgrGeom; if (poOgrPoint->getCoordinateDimension() == 0) { poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint ( ); } else { x = poOgrPoint->getX ( ); y = poOgrPoint->getY ( ); if ( x > 180 ) x -= 360; coordinates = poKmlFactory->CreateCoordinates ( ); coordinates->add_latlng ( y, x ); poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint ( ); poKmlPoint->set_coordinates ( coordinates ); } break; case wkbPoint25D: poOgrPoint = ( OGRPoint * ) poOgrGeom; x = poOgrPoint->getX ( ); y = poOgrPoint->getY ( ); z = poOgrPoint->getZ ( ); if ( x > 180 ) x -= 360; coordinates = poKmlFactory->CreateCoordinates ( ); coordinates->add_latlngalt ( y, x, z ); poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint ( ); poKmlPoint->set_coordinates ( coordinates ); break; case wkbLineString: poOgrLineString = ( OGRLineString * ) poOgrGeom; if( extra >= 0 ) { ((OGRLinearRing*)poOgrGeom)->closeRings(); } numpoints = poOgrLineString->getNumPoints ( ); if( extra >= 0 ) { if( numpoints < 4 && CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) ) { CPLError(CE_Failure, CPLE_NotSupported, "A linearring should have at least 4 points"); return NULL; } } else { if( numpoints < 2 && CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) ) { CPLError(CE_Failure, CPLE_NotSupported, "A linestring should have at least 2 points"); return NULL; } } coordinates = poKmlFactory->CreateCoordinates ( ); poOgrPoint = new OGRPoint ( ); for ( i = 0; i < numpoints; i++ ) { poOgrLineString->getPoint ( i, poOgrPoint ); x = poOgrPoint->getX ( ); y = poOgrPoint->getY ( ); if ( x > 180 ) x -= 360; coordinates->add_latlng ( y, x ); } delete poOgrPoint; /***** check if its a wkbLinearRing *****/ if ( extra < 0 ) { poKmlGeometry = poKmlLineString = poKmlFactory->CreateLineString ( ); poKmlLineString->set_coordinates ( coordinates ); break; } /***** fallthrough *****/ case wkbLinearRing: //this case is for readability only poKmlLinearRing = poKmlFactory->CreateLinearRing ( ); poKmlLinearRing->set_coordinates ( coordinates ); if ( !extra ) { poKmlOuterRing = poKmlFactory->CreateOuterBoundaryIs ( ); poKmlOuterRing->set_linearring ( poKmlLinearRing ); poKmlGeometry = poKmlOuterRing; } else { poKmlGeometry = poKmlInnerRing = poKmlFactory->CreateInnerBoundaryIs ( ); poKmlInnerRing->set_linearring ( poKmlLinearRing ); } break; case wkbLineString25D: poOgrLineString = ( OGRLineString * ) poOgrGeom; if( extra >= 0 ) { ((OGRLinearRing*)poOgrGeom)->closeRings(); } numpoints = poOgrLineString->getNumPoints ( ); if( extra >= 0 ) { if( numpoints < 4 && CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) ) { CPLError(CE_Failure, CPLE_NotSupported, "A linearring should have at least 4 points"); return NULL; } } else { if( numpoints < 2 && CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) ) { CPLError(CE_Failure, CPLE_NotSupported, "A linestring should have at least 2 points"); return NULL; } } coordinates = poKmlFactory->CreateCoordinates ( ); poOgrPoint = new OGRPoint ( ); for ( i = 0; i < numpoints; i++ ) { poOgrLineString->getPoint ( i, poOgrPoint ); x = poOgrPoint->getX ( ); y = poOgrPoint->getY ( ); z = poOgrPoint->getZ ( ); if ( x > 180 ) x -= 360; coordinates->add_latlngalt ( y, x, z ); } delete poOgrPoint; /***** check if its a wkbLinearRing *****/ if ( extra < 0 ) { poKmlGeometry = poKmlLineString = poKmlFactory->CreateLineString ( ); poKmlLineString->set_coordinates ( coordinates ); break; } /***** fallthrough *****/ //case wkbLinearRing25D: // this case is for readability only poKmlLinearRing = poKmlFactory->CreateLinearRing ( ); poKmlLinearRing->set_coordinates ( coordinates ); if ( !extra ) { poKmlGeometry = poKmlOuterRing = poKmlFactory->CreateOuterBoundaryIs ( ); poKmlOuterRing->set_linearring ( poKmlLinearRing ); } else { poKmlGeometry = poKmlInnerRing = poKmlFactory->CreateInnerBoundaryIs ( ); poKmlInnerRing->set_linearring ( poKmlLinearRing ); } break; case wkbPolygon: CPLErrorReset(); if( CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) && OGRGeometryFactory::haveGEOS() && (!poOgrGeom->IsValid() || CPLGetLastErrorType() != CE_None) ) { CPLError(CE_Failure, CPLE_NotSupported, "Invalid polygon"); return NULL; } poOgrPolygon = ( OGRPolygon * ) poOgrGeom; poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon ( ); poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing ( ), 0, poKmlFactory ); poKmlPolygon-> set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) ); nGeom = poOgrPolygon->getNumInteriorRings ( ); for ( i = 0; i < nGeom; i++ ) { poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ), i + 1, poKmlFactory ); poKmlPolygon-> add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) ); } break; case wkbPolygon25D: CPLErrorReset(); if( CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) && OGRGeometryFactory::haveGEOS() && (!poOgrGeom->IsValid() || CPLGetLastErrorType() != CE_None) ) { CPLError(CE_Failure, CPLE_NotSupported, "Invalid polygon"); return NULL; } poOgrPolygon = ( OGRPolygon * ) poOgrGeom; poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon ( ); poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing ( ), 0, poKmlFactory ); poKmlPolygon-> set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) ); nGeom = poOgrPolygon->getNumInteriorRings ( ); for ( i = 0; i < nGeom; i++ ) { poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ), i + 1, poKmlFactory ); poKmlPolygon-> add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) ); } break; case wkbMultiPoint: case wkbMultiLineString: case wkbMultiPolygon: case wkbGeometryCollection: case wkbMultiPoint25D: case wkbMultiLineString25D: case wkbMultiPolygon25D: case wkbGeometryCollection25D: poOgrMultiGeom = ( OGRGeometryCollection * ) poOgrGeom; nGeom = poOgrMultiGeom->getNumGeometries ( ); if( nGeom == 1 && CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) ) { CPLDebug("LIBKML", "Turning multiple geometry into single geometry"); poKmlGeometry = geom2kml( poOgrMultiGeom->getGeometryRef ( 0 ), -1, poKmlFactory ); } else { if( nGeom == 0 && CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) ) { CPLError(CE_Warning, CPLE_AppDefined, "Empty multi geometry are not recommended"); } poKmlGeometry = poKmlMultiGeometry = poKmlFactory->CreateMultiGeometry ( ); for ( i = 0; i < nGeom; i++ ) { poKmlTmpGeometry = geom2kml ( poOgrMultiGeom->getGeometryRef ( i ), -1, poKmlFactory ); poKmlMultiGeometry-> add_geometry ( AsGeometry ( poKmlTmpGeometry ) ); } } break; case wkbUnknown: case wkbNone: default: break; } return poKmlGeometry; }
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; }