예제 #1
0
int kml2tessellate_rec (
    GeometryPtr poKmlGeometry,
    int *pnTessellate )
{

    LineStringPtr poKmlLineString;
    PolygonPtr poKmlPolygon;
    MultiGeometryPtr poKmlMultiGeometry;

    size_t nGeom;
    size_t i;

    switch ( poKmlGeometry->Type (  ) ) {

    case kmldom::Type_Point:
        break;

    case kmldom::Type_LineString:
        poKmlLineString = AsLineString ( poKmlGeometry );

        if ( poKmlLineString->has_tessellate (  ) ) {
            *pnTessellate = poKmlLineString->get_tessellate (  );
            return TRUE;
        }

        break;

    case kmldom::Type_LinearRing:
        break;

    case kmldom::Type_Polygon:
        poKmlPolygon = AsPolygon ( poKmlGeometry );

        if ( poKmlPolygon->has_tessellate (  ) ) {
            *pnTessellate = poKmlPolygon->get_tessellate (  );
            return TRUE;
        }

        break;

    case kmldom::Type_MultiGeometry:
        poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );

        nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
        for ( i = 0; i < nGeom; i++ ) {
            if ( kml2tessellate_rec ( poKmlMultiGeometry->
                                      get_geometry_array_at ( i ),
                                      pnTessellate ) )
                return TRUE;
        }

        break;

    default:
        break;

    }

    return FALSE;
}
예제 #2
0
	void object::test<16>()
	{
		const std::size_t size = 5;
		CoordArrayPtr coords = new geos::geom::CoordinateArraySequence(size);
		ensure( coords != 0 );
		ensure_equals( coords->getSize(), size );

		LineStringPtr line = factory_.createLineString(coords);
		ensure( "createLineString() returned null pointer.", line != 0 );
		ensure( "createLineString() returned empty point.", !line->isEmpty() );
		ensure( line->isSimple() );
		ensure( line->getCoordinate() != 0 );

		// TODO - mloskot - is this correct?
		//ensure( line->isValid() );

		ensure_equals( line->getGeometryTypeId(), geos::geom::GEOS_LINESTRING );
		ensure_equals( line->getDimension(), geos::geom::Dimension::L );
		ensure_equals( line->getBoundaryDimension(), geos::geom::Dimension::False );
		ensure_equals( line->getNumPoints(), size );
		ensure_equals( line->getLength(), 0.0 );
		ensure_equals( line->getArea(), 0.0 );

		// FREE MEMORY
		factory_.destroyGeometry(line);	
	}
    void object::test<15>()
	{
		GeometryPtr geo = reader_.read("LINESTRING (0 0, 5 5, 10 5, 10 10)");
		ensure( geo != 0 );

		LineStringPtr line = dynamic_cast<LineStringPtr>(geo);
		ensure(line != 0);

		ensure( !line->isEmpty() );
		ensure( !line->isClosed() );
		ensure( !line->isRing() );
		
		// FREE TESTED LINESTRING
		factory_.destroyGeometry(line);
	}
예제 #4
0
void ogr2tessellate_rec (
    int nTessellate,
    GeometryPtr poKmlGeometry )
{

    LineStringPtr poKmlLineString;
    PolygonPtr poKmlPolygon;
    MultiGeometryPtr poKmlMultiGeometry;

    size_t nGeom;
    size_t i;

    switch ( poKmlGeometry->Type (  ) ) {

    case kmldom::Type_Point:
        break;

    case kmldom::Type_LineString:
        poKmlLineString = AsLineString ( poKmlGeometry );
        poKmlLineString->set_tessellate ( nTessellate );
        break;

    case kmldom::Type_LinearRing:
        break;

    case kmldom::Type_Polygon:
        poKmlPolygon = AsPolygon ( poKmlGeometry );

        poKmlPolygon->set_tessellate ( nTessellate );
        break;

    case kmldom::Type_MultiGeometry:
        poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );

        nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
        for ( i = 0; i < nGeom; i++ ) {
            ogr2tessellate_rec ( nTessellate,
                                 poKmlMultiGeometry->
                                 get_geometry_array_at ( i ) );
        }

        break;

    default:
        break;

    }
}
예제 #5
0
    void object::test<15>()
	{
		GeometryPtr geo = reader_.read("LINESTRING (0 0, 5 5, 10 5, 10 10)");
		ensure( geo != nullptr );

		LineStringPtr line = dynamic_cast<LineStringPtr>(geo);
		ensure(line != nullptr);

		ensure( !line->isEmpty() );
		ensure( !line->isClosed() );
		ensure( !line->isRing() );
        ensure( line->getCoordinateDimension() == 2 );

		// FREE TESTED LINESTRING
		factory_->destroyGeometry(line);
	}
예제 #6
0
    void object::test<16>()
	{
		GeometryPtr geo = reader_.read("LINESTRING (0 0, 5 5, 10 5, 10 10)");
		ensure( geo != 0 );

		LineStringPtr line = dynamic_cast<LineStringPtr>(geo);
		ensure(line != 0);
		
		GeometryPtr envelope = line->getEnvelope();	
		ensure( envelope != 0 );
		ensure( !envelope->isEmpty() );
		ensure_equals( envelope->getDimension(), geos::geom::Dimension::A );

		factory_.destroyGeometry(envelope);

		// FREE TESTED LINESTRING
		factory_.destroyGeometry(line);
	}
예제 #7
0
    void object::test<18>()
	{
		GeometryPtr geo = reader_.read("LINESTRING (0 0, 5 5, 10 5, 10 10)");
		ensure( geo != 0 );

		LineStringPtr line = dynamic_cast<LineStringPtr>(geo);
		ensure(line != 0);
		
		GeometryPtr hull = line->convexHull();	
		ensure( hull != 0 );
		ensure( !hull->isEmpty() );
		ensure_equals( hull->getGeometryTypeId(), geos::geom::GEOS_POLYGON );
		ensure_equals( hull->getDimension(), geos::geom::Dimension::A );
		factory_.destroyGeometry(hull);

		// FREE TESTED LINESTRING
		factory_.destroyGeometry(line);
	}
예제 #8
0
    void object::test<17>()
	{
		GeometryPtr geo = reader_.read("LINESTRING (0 0, 5 5, 10 5, 10 10)");
		ensure( geo != 0 );

		LineStringPtr line = dynamic_cast<LineStringPtr>(geo);
		ensure(line != 0);
		
		GeometryPtr boundary = line->getBoundary();	
		ensure( boundary != 0 );
		ensure( !boundary->isEmpty() );
		ensure_equals( boundary->getGeometryTypeId(), geos::geom::GEOS_MULTIPOINT );
		ensure_equals( boundary->getDimension(), geos::geom::Dimension::P );
		factory_.destroyGeometry(boundary);

		// FREE TESTED LINESTRING
		factory_.destroyGeometry(line);
	}
예제 #9
0
	void object::test<30>()
	{
		using geos::geom::Coordinate;
		
		const std::size_t size = 5;
		const std::size_t lineSize = 2;

		std::vector<GeometryPtr> lines;

		for (std::size_t i = 0; i < size; ++i)
		{
			const std::size_t factor = i * i;
			CoordArrayPtr coords = new geos::geom::CoordinateArraySequence(lineSize);
			ensure( coords != 0 );
			coords->setAt(Coordinate(0 + factor, 0 + factor), 0);
			coords->setAt(Coordinate(5 + factor, 5 + factor), 1);
			ensure_equals( coords->getSize(), lineSize );

			LineStringPtr line = factory_.createLineString(coords);
			ensure( "createLineString() returned empty point.", !line->isEmpty() );
			ensure_equals( line->getNumPoints(), lineSize );
			ensure( line->isSimple() );
			ensure( line->getCoordinate() != 0 );
			ensure_equals( line->getGeometryTypeId(), geos::geom::GEOS_LINESTRING );

			lines.push_back(line);
		}

		MultiLineStringPtr mls = factory_.createMultiLineString(lines);
		ensure( mls != 0 );
		// TODO - mloskot - why isValid() returns false?
		//ensure( mls->isValid() );
		ensure_equals( mls->getNumGeometries(), size );
		ensure_equals( mls->getGeometryTypeId(), geos::geom::GEOS_MULTILINESTRING );

		// FREE MEMORY
		factory_.destroyGeometry(mls);
		std::vector<GeometryPtr>::const_iterator it;
		for (it = lines.begin(); it != lines.end(); ++it)
		{
			delete (*it);
		}
	}
예제 #10
0
	void object::test<17>()
	{
		const std::size_t size = 5;
		geos::geom::CoordinateArraySequence coords(size);
		ensure_equals( coords.getSize(), size );

		LineStringPtr line = factory_.createLineString(coords);
		ensure( "createLineString() returned empty point.", !line->isEmpty() );
		ensure_equals( line->getNumPoints(), size );
		ensure( line->isSimple() );
		ensure( line->getCoordinate() != 0 );
		
		ensure_equals( line->getGeometryTypeId(), geos::geom::GEOS_LINESTRING );
		ensure_equals( line->getDimension(), geos::geom::Dimension::L );
		ensure_equals( line->getBoundaryDimension(), geos::geom::Dimension::False );
		ensure_equals( line->getNumPoints(), size );
		ensure_equals( line->getLength(), 0.0 );
		ensure_equals( line->getArea(), 0.0 );

		// FREE MEMORY
		factory_.destroyGeometry(line);
	}
예제 #11
0
void ogr2altitudemode_rec (
    GeometryPtr poKmlGeometry,
    int iAltitudeMode,
    int isGX )
{

    PointPtr poKmlPoint;
    LineStringPtr poKmlLineString;
    PolygonPtr poKmlPolygon;
    MultiGeometryPtr poKmlMultiGeometry;

    size_t nGeom;
    size_t i;

    switch ( poKmlGeometry->Type (  ) ) {

    case kmldom::Type_Point:
        poKmlPoint = AsPoint ( poKmlGeometry );

        if ( !isGX )
            poKmlPoint->set_altitudemode ( iAltitudeMode );
        else
            poKmlPoint->set_gx_altitudemode ( iAltitudeMode );

        break;

    case kmldom::Type_LineString:
        poKmlLineString = AsLineString ( poKmlGeometry );

        if ( !isGX )
            poKmlLineString->set_altitudemode ( iAltitudeMode );
        else
            poKmlLineString->set_gx_altitudemode ( iAltitudeMode );

        break;

    case kmldom::Type_LinearRing:
        break;

    case kmldom::Type_Polygon:
        poKmlPolygon = AsPolygon ( poKmlGeometry );

        if ( !isGX )
            poKmlPolygon->set_altitudemode ( iAltitudeMode );
        else
            poKmlPolygon->set_gx_altitudemode ( iAltitudeMode );

        break;

    case kmldom::Type_MultiGeometry:
        poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );

        nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
        for ( i = 0; i < nGeom; i++ ) {
            ogr2altitudemode_rec ( poKmlMultiGeometry->
                                   get_geometry_array_at ( i ), iAltitudeMode,
                                   isGX );
        }

        break;

    default:
        break;

    }

}
예제 #12
0
	void object::test<15>()
	{
		LineStringPtr line = factory_.createLineString();
		
		ensure( "createLineString() returned null pointer.", line != 0 );
		ensure( "createLineString() returned non-empty point.", line->isEmpty() );
		ensure( line->isSimple() );
		ensure( line->isValid() );
		ensure( line->getCentroid() == 0 );
		
		// TODO - mloskot - waiting for some decision
		// http://geos.refractions.net/pipermail/geos-devel/2006-March/002006.html
		//ensure( line->getCoordinate() == 0 );

		GeometryPtr geo = 0;
		geo = line->getEnvelope();
		ensure( geo != 0 );
		ensure( geo->isEmpty() );
		factory_.destroyGeometry(geo);

		geo = line->getBoundary();
		ensure( geo != 0 );
		ensure( geo->isEmpty() );
		factory_.destroyGeometry(geo);

		geo = line->convexHull();
		ensure( geo != 0 );
		ensure( geo->isEmpty() );
		factory_.destroyGeometry(geo);

		ensure_equals( line->getGeometryTypeId(), geos::geom::GEOS_LINESTRING );
		ensure_equals( line->getDimension(), geos::geom::Dimension::L );
		ensure_equals( line->getBoundaryDimension(), geos::geom::Dimension::P ); // empty linestring
		ensure_equals( line->getNumPoints(), 0u );
		ensure_equals( line->getLength(), 0.0 );
		ensure_equals( line->getArea(), 0.0 );

		// FREE MEMORY
		factory_.destroyGeometry(line);
	}
예제 #13
0
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;
}
예제 #14
0
static OGRGeometry *kml2geom_rec (
    GeometryPtr poKmlGeometry,
    OGRSpatialReference *poOgrSRS)

{

    /***** ogr geom vars *****/

    OGRPoint *poOgrPoint;
    OGRLineString *poOgrLineString;
    OGRLinearRing *poOgrLinearRing;
    OGRPolygon *poOgrPolygon;
    OGRGeometryCollection *poOgrMultiGeometry;
    OGRGeometry *poOgrGeometry = NULL;
    OGRGeometry *poOgrTmpGeometry = NULL;


    /***** libkml geom vars *****/

    CoordinatesPtr poKmlCoordinates;
    PointPtr poKmlPoint;
    LineStringPtr poKmlLineString;
    LinearRingPtr poKmlLinearRing;
    OuterBoundaryIsPtr poKmlOuterRing;
    InnerBoundaryIsPtr poKmlInnerRing;
    PolygonPtr poKmlPolygon;
    MultiGeometryPtr poKmlMultiGeometry;
    GxTrackPtr poKmlGxTrack;
    GxMultiTrackPtr poKmlGxMultiTrack;
    GeometryPtr poKmlTmpGeometry;

    Vec3 oKmlVec;

    size_t nRings,
        nCoords,
        nGeom,
        i;

    switch ( poKmlGeometry->Type (  ) ) {
    case kmldom::Type_Point:
        poKmlPoint = AsPoint ( poKmlGeometry );
        if ( poKmlPoint->has_coordinates (  ) ) {
            poKmlCoordinates = poKmlPoint->get_coordinates (  );
            nCoords = poKmlCoordinates->get_coordinates_array_size (  );
            if (nCoords > 0)
            {
                oKmlVec = poKmlCoordinates->get_coordinates_array_at ( 0 );

                if ( oKmlVec.has_altitude (  ) )
                    poOgrPoint = new OGRPoint ( oKmlVec.get_longitude (  ),
                                                oKmlVec.get_latitude (  ),
                                                oKmlVec.get_altitude (  ) );
                else
                    poOgrPoint = new OGRPoint ( oKmlVec.get_longitude (  ),
                                                oKmlVec.get_latitude (  ) );

                poOgrGeometry = poOgrPoint;
            }
            else
            {
                poOgrGeometry = new OGRPoint();
            }
        }
        else
        {
            poOgrGeometry = new OGRPoint();
        }

        break;

    case kmldom::Type_LineString:
        poKmlLineString = AsLineString ( poKmlGeometry );
        poOgrLineString = new OGRLineString (  );
        if ( poKmlLineString->has_coordinates (  ) ) {
            poKmlCoordinates = poKmlLineString->get_coordinates (  );

            nCoords = poKmlCoordinates->get_coordinates_array_size (  );
            for ( i = 0; i < nCoords; i++ ) {
                oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
                if ( oKmlVec.has_altitude (  ) )
                    poOgrLineString->
                        addPoint ( oKmlVec.get_longitude (  ),
                                   oKmlVec.get_latitude (  ),
                                   oKmlVec.get_altitude (  ) );
                else
                    poOgrLineString->
                        addPoint ( oKmlVec.get_longitude (  ),
                                   oKmlVec.get_latitude (  ) );
            }
        }
        poOgrGeometry = poOgrLineString;

        break;
    case kmldom::Type_LinearRing:
        poKmlLinearRing = AsLinearRing ( poKmlGeometry );
        poOgrLinearRing = new OGRLinearRing (  );
        if ( poKmlLinearRing->has_coordinates (  ) ) {
            poKmlCoordinates = poKmlLinearRing->get_coordinates (  );

            nCoords = poKmlCoordinates->get_coordinates_array_size (  );
            for ( i = 0; i < nCoords; i++ ) {
                oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
                if ( oKmlVec.has_altitude (  ) )
                    poOgrLinearRing->
                        addPoint ( oKmlVec.get_longitude (  ),
                                   oKmlVec.get_latitude (  ),
                                   oKmlVec.get_altitude (  ) );
                else
                    poOgrLinearRing->
                        addPoint ( oKmlVec.get_longitude (  ),
                                   oKmlVec.get_latitude (  ) );
            }
        }
        poOgrGeometry = poOgrLinearRing;

        break;
    case kmldom::Type_Polygon:
        poKmlPolygon = AsPolygon ( poKmlGeometry );

        poOgrPolygon = new OGRPolygon (  );
        if ( poKmlPolygon->has_outerboundaryis (  ) ) {

            poKmlOuterRing = poKmlPolygon->get_outerboundaryis (  );
            poKmlLinearRing = poKmlOuterRing->get_linearring (  );
            if (poKmlLinearRing)
            {
                poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS );

                poOgrPolygon->
                    addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry );
            }

        }
        nRings = poKmlPolygon->get_innerboundaryis_array_size (  );
        for ( i = 0; i < nRings; i++ ) {
            poKmlInnerRing = poKmlPolygon->get_innerboundaryis_array_at ( i );
            poKmlLinearRing = poKmlInnerRing->get_linearring (  );
            if (poKmlLinearRing)
            {
                poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS );

                poOgrPolygon->
                    addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry );
            }
        }
        poOgrGeometry = poOgrPolygon;

        break;
    case kmldom::Type_MultiGeometry:
    {
        poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
        nGeom = poKmlMultiGeometry->get_geometry_array_size (  );

        // Detect subgeometry type to instantiate appropriate
        // multi geometry type.
        kmldom::KmlDomType type = kmldom::Type_Unknown;
        for ( i = 0; i < nGeom; i++ ) {
            poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i );
            if (type == kmldom::Type_Unknown)
                type = poKmlTmpGeometry->Type();
            else if (type != poKmlTmpGeometry->Type())
            {
                type = kmldom::Type_Unknown;
                break;
            }
        }

        if (type == kmldom::Type_Point)
            poOgrMultiGeometry = new OGRMultiPoint();
        else if (type == kmldom::Type_LineString)
            poOgrMultiGeometry = new OGRMultiLineString();
        else if (type == kmldom::Type_Polygon)
            poOgrMultiGeometry = new OGRMultiPolygon();
        else
            poOgrMultiGeometry = new OGRGeometryCollection ();

        for ( i = 0; i < nGeom; i++ ) {
            poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i );
            poOgrTmpGeometry = kml2geom_rec ( poKmlTmpGeometry, poOgrSRS );

            poOgrMultiGeometry->addGeometryDirectly ( poOgrTmpGeometry );
        }
        poOgrGeometry = poOgrMultiGeometry;
        break;
    }

    case kmldom::Type_GxTrack:
        poKmlGxTrack = AsGxTrack ( poKmlGeometry );
        nCoords = poKmlGxTrack->get_gx_coord_array_size();
        poOgrLineString = new OGRLineString (  );
        for ( i = 0; i < nCoords; i++ ) {
            oKmlVec = poKmlGxTrack->get_gx_coord_array_at ( i );
            if ( oKmlVec.has_altitude (  ) )
                poOgrLineString->
                    addPoint ( oKmlVec.get_longitude (  ),
                                oKmlVec.get_latitude (  ),
                                oKmlVec.get_altitude (  ) );
            else
                poOgrLineString->
                    addPoint ( oKmlVec.get_longitude (  ),
                                oKmlVec.get_latitude (  ) );
        }
        poOgrGeometry = poOgrLineString;
        break;

    case kmldom::Type_GxMultiTrack:
    {
        poKmlGxMultiTrack = AsGxMultiTrack ( poKmlGeometry );
        nGeom = poKmlGxMultiTrack->get_gx_track_array_size (  );
        poOgrMultiGeometry = new OGRMultiLineString();
        for( size_t j = 0; j < nGeom; j++ )
        {
            poKmlGxTrack = poKmlGxMultiTrack->get_gx_track_array_at ( j );
            nCoords = poKmlGxTrack->get_gx_coord_array_size();
            poOgrLineString = new OGRLineString (  );
            for ( i = 0; i < nCoords; i++ ) {
                oKmlVec = poKmlGxTrack->get_gx_coord_array_at ( i );
                if ( oKmlVec.has_altitude (  ) )
                    poOgrLineString->
                        addPoint ( oKmlVec.get_longitude (  ),
                                    oKmlVec.get_latitude (  ),
                                    oKmlVec.get_altitude (  ) );
                else
                    poOgrLineString->
                        addPoint ( oKmlVec.get_longitude (  ),
                                    oKmlVec.get_latitude (  ) );
            }
            poOgrMultiGeometry->addGeometryDirectly(poOgrLineString);
        }
        poOgrGeometry = poOgrMultiGeometry;
        break;
    }

    default:
        break;
    }

    if (poOgrGeometry)
        poOgrGeometry->assignSpatialReference(poOgrSRS);

    return poOgrGeometry;
}
예제 #15
0
int kml2altitudemode_rec (
    GeometryPtr poKmlGeometry,
    int *pnAltitudeMode,
    int *pbIsGX )
{

    PointPtr poKmlPoint;
    LineStringPtr poKmlLineString;
    PolygonPtr poKmlPolygon;
    MultiGeometryPtr poKmlMultiGeometry;

    size_t nGeom;
    size_t i;

    switch ( poKmlGeometry->Type (  ) ) {

    case kmldom::Type_Point:
        poKmlPoint = AsPoint ( poKmlGeometry );

        if ( poKmlPoint->has_altitudemode (  ) ) {
            *pnAltitudeMode = poKmlPoint->get_altitudemode (  );
            return TRUE;
        }
        else if ( poKmlPoint->has_gx_altitudemode (  ) ) {
            *pnAltitudeMode = poKmlPoint->get_gx_altitudemode (  );
            *pbIsGX = TRUE;
            return TRUE;
        }

        break;

    case kmldom::Type_LineString:
        poKmlLineString = AsLineString ( poKmlGeometry );

        if ( poKmlLineString->has_altitudemode (  ) ) {
            *pnAltitudeMode = poKmlLineString->get_altitudemode (  );
            return TRUE;
        }
        else if ( poKmlLineString->has_gx_altitudemode (  ) ) {
            *pnAltitudeMode = poKmlLineString->get_gx_altitudemode (  );
            *pbIsGX = TRUE;
            return TRUE;
        }
        break;

    case kmldom::Type_LinearRing:
        break;

    case kmldom::Type_Polygon:
        poKmlPolygon = AsPolygon ( poKmlGeometry );

        if ( poKmlPolygon->has_altitudemode (  ) ) {
            *pnAltitudeMode = poKmlPolygon->get_altitudemode (  );
            return TRUE;
        }
        else if ( poKmlPolygon->has_gx_altitudemode (  ) ) {
            *pnAltitudeMode = poKmlPolygon->get_gx_altitudemode (  );
            *pbIsGX = TRUE;
            return TRUE;
        }

        break;

    case kmldom::Type_MultiGeometry:
        poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );

        nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
        for ( i = 0; i < nGeom; i++ ) {
            if ( kml2altitudemode_rec ( poKmlMultiGeometry->
                                        get_geometry_array_at ( i ),
                                        pnAltitudeMode, pbIsGX ) )
                return TRUE;
        }

        break;

    default:
        break;

    }

    return FALSE;
}
예제 #16
0
/**
 * @brief KmlExport::exportToKML Triggers logfile export to KML.
 */
bool KmlExport::exportToKML()
{
    bool ret = open();
    if (!ret) {
        qDebug () << "Logfile failed to open during KML export";
        return false;
    }

    // Parses logfile and generates KML document
    ret = preparseLogFile();
    if (!ret) {
        qDebug () << "Logfile preparsing failed";
        return false;
    }

    // Call parser.
    parseLogFile();

    // Add track to <Document>
    document->add_feature(trackFolder);

    // Add timespans to <Document>
    document->add_feature(timestampFolder);

    // Add ground track to <Document>
    {
        LineStringPtr linestring = factory->CreateLineString();
        linestring->set_extrude(false); // Do not extrude to ground
        linestring->set_altitudemode(kmldom::ALTITUDEMODE_CLAMPTOGROUND);
        linestring->set_coordinates(wallAxes[0]);

        MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry();
        multiGeometry->add_geometry(linestring);

        PlacemarkPtr placemark = factory->CreatePlacemark();
        placemark->set_geometry(multiGeometry);
        placemark->set_styleurl("#ts_2_tb");
        placemark->set_name("Ground track");

        document->add_feature(placemark);
    }

    // Add wall axes to <Document>
    FolderPtr folder = factory->CreateFolder();
    for (int i=0; i<numberOfWallAxes; i++) {
        LineStringPtr linestring = factory->CreateLineString();
        linestring->set_extrude(false); // Do not extrude to ground
        linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE);
        linestring->set_coordinates(wallAxes[i]);

        MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry();
        multiGeometry->add_geometry(linestring);

        PlacemarkPtr placemark = factory->CreatePlacemark();
        placemark->set_geometry(multiGeometry);
        placemark->set_styleurl("#ts_1_tb");

        folder->add_feature(placemark);
        folder->set_name("Wall axes");
    }
    document->add_feature(folder);

    // Create <kml> and give it <Document>.
    KmlPtr kml = factory->CreateKml();
    kml->set_feature(document);  // kml takes ownership.

    // Serialize to XML
    std::string kml_data = kmldom::SerializePretty(kml);

    // Save to file
    if (QFileInfo(outputFileName).suffix().toLower() == "kmz") {
        if (!kmlengine::KmzFile::WriteKmz(outputFileName.toStdString().c_str(), kml_data)) {
            qDebug() << "KMZ write failed: " << outputFileName;
            QMessageBox::critical(new QWidget(),"KMZ write failed", "Failed to write KMZ file.");
            return false;
        }
    } else if (QFileInfo(outputFileName).suffix().toLower() == "kml") {
        if (!kmlbase::File::WriteStringToFile(kml_data, outputFileName.toStdString())) {
            qDebug() << "KML write failed: " << outputFileName;
            QMessageBox::critical(new QWidget(),"KML write failed", "Failed to write KML file.");
            return false;
        }
    } else {
        qDebug() << "Write failed. Invalid file name:" << outputFileName;
        QMessageBox::critical(new QWidget(),"Write failed", "Failed to write file. Invalid filename");
        return false;
    }


    return true;
}
예제 #17
0
/**
 * @brief KmlExport::CreateLineStringPlacemark Adds a line segment which is colored according to the
 * vehicle's speed.
 * @param startPoint Beginning point along line
 * @param endPoint End point point along line
 * @return Returns the placemark containing the line segment
 */
PlacemarkPtr KmlExport::CreateLineStringPlacemark(const LLAVCoordinates &startPoint, const LLAVCoordinates &endPoint, quint32 newPlacemarkTime)
{
    CoordinatesPtr coordinates = factory->CreateCoordinates();
    coordinates->add_latlngalt(startPoint.latitude, startPoint.longitude, startPoint.altitude);
    coordinates->add_latlngalt(endPoint.latitude,   endPoint.longitude,   endPoint.altitude);

    LineStringPtr linestring = factory->CreateLineString();
    linestring->set_extrude(true); // Extrude to ground
    linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE);
    linestring->set_coordinates(coordinates);

    StyleMapPtr styleMap = factory->CreateStyleMap();


    // Add custom balloon style (gets rid of "Directions to here...")
    // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY
    BalloonStylePtr balloonStyle = factory->CreateBalloonStyle();
    balloonStyle->set_text("$[description]");

    {
        double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2;

        // Set the linestyle. The color is a function of speed.
        LineStylePtr lineStyle = factory->CreateLineStyle();
        lineStyle->set_color(mapVelocity2Color(currentVelocity));

        PolyStylePtr polyStyle = factory->CreatePolyStyle();
        polyStyle->set_color(mapVelocity2Color(currentVelocity, 100));

        // Link the style to the icon
        StylePtr style = factory->CreateStyle();
        style->set_balloonstyle(balloonStyle);
        style->set_linestyle(lineStyle);
        style->set_polystyle(polyStyle);

        PairPtr pair = factory->CreatePair();
        pair->set_styleselector(style);
        pair->set_key(kmldom::STYLESTATE_NORMAL);

        styleMap->add_pair(pair);
    }

    {
        double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2;

        // Set the linestyle. The color is a function of speed.
        LineStylePtr lineStyle = factory->CreateLineStyle();
        lineStyle->set_color(mapVelocity2Color(currentVelocity));

        PolyStylePtr polyStyle = factory->CreatePolyStyle();
        polyStyle->set_color(mapVelocity2Color(currentVelocity, 100));
        polyStyle->set_fill(false);

        // Link the style to the icon
        StylePtr style = factory->CreateStyle();
        style->set_balloonstyle(balloonStyle);
        style->set_linestyle(lineStyle);
        style->set_polystyle(polyStyle);

        PairPtr pair = factory->CreatePair();
        pair->set_styleselector(style);
        pair->set_key(kmldom::STYLESTATE_HIGHLIGHT);

        styleMap->add_pair(pair);
    }

    PlacemarkPtr placemark = factory->CreatePlacemark();
    placemark->set_geometry(linestring);
    placemark->set_styleselector(styleMap);
    placemark->set_visibility(true);

    // Create the timespan
    TimeSpanPtr timeSpan = factory->CreateTimeSpan();
    QDateTime startTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make this a function of the true time, preferably gotten from the GPS
    QDateTime endTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime);
    timeSpan->set_begin(startTime.toString(dateTimeFormat).toStdString());
    timeSpan->set_end(endTime.toString(dateTimeFormat).toStdString());

    // Set the name
    QDateTime trackTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make it a function of the realtime preferably gotten from the GPS
    placemark->set_name(trackTime.toString(dateTimeFormat).toStdString());

    // Add a nice description to the track placemark
    placemark->set_description(informationString.toStdString());

    // Set the timespan
    placemark->set_timeprimitive(timeSpan);

    return placemark;
}