diff --git a/src/osgPlugins/ESRIShape/ESRIShape.cpp b/src/osgPlugins/ESRIShape/ESRIShape.cpp new file mode 100644 index 000000000..493c846ea --- /dev/null +++ b/src/osgPlugins/ESRIShape/ESRIShape.cpp @@ -0,0 +1,1212 @@ +#include + +#include "ESRIShape.h" + +using namespace ESRIShape ; + +template +inline void swapBytes( T &s ) +{ + if( sizeof( T ) == 1 ) return; + + T d = s; + BytePtr sptr = (BytePtr)&s; + BytePtr dptr = &(((BytePtr)&d)[sizeof(T)-1]); + + for( unsigned int i = 0; i < sizeof(T); i++ ) + *(sptr++) = *(dptr--); +} + +inline ByteOrder getByteOrder() +{ + int one = 1; + unsigned char *ptr = (unsigned char *)&one; + if( ptr[0] == 1 ) + return LittleEndian; + else + return BigEndian; +} + +template +inline bool readVal( int fd, T &val, ByteOrder bo = LittleEndian ) +{ + int nbytes = 0; + if( (nbytes = ::read( fd, &val, sizeof(T))) <= 0 ) + return false; + + if( getByteOrder() != bo ) + swapBytes(val); + + return true; +} + +inline void printType( ShapeType type ) +{ + printf( "%s", + type == ShapeTypeNullShape ? "NullShape" : + type == ShapeTypePoint ? "Point" : + type == ShapeTypePolyLine ? "PolyLine" : + type == ShapeTypePolygon ? "Polygon" : + type == ShapeTypeMultiPoint ? "MultiPoint" : + type == ShapeTypePointZ ? "PointZ" : + type == ShapeTypePolyLineZ ? "PolyLineZ" : + type == ShapeTypePolygonZ ? "PolygonZ" : + type == ShapeTypeMultiPointZ ? "MultiPointZ" : + type == ShapeTypePointM ? "PointM" : + type == ShapeTypePolyLineM ? "PolyLineM" : + type == ShapeTypePolygonM ? "PolygonM" : + type == ShapeTypeMultiPointM ? "MultiPointM" : + type == ShapeTypeMultiPatch ? "MultiPatch" : "Unknown" ); +} + + +bool BoundingBox::read( int fd ) +{ + if( readVal(fd, Xmin, LittleEndian ) == false ) return false; + if( readVal(fd, Ymin, LittleEndian ) == false ) return false; + if( readVal(fd, Xmax, LittleEndian ) == false ) return false; + if( readVal(fd, Ymax, LittleEndian ) == false ) return false; + if( readVal(fd, Zmin, LittleEndian ) == false ) return false; + if( readVal(fd, Zmax, LittleEndian ) == false ) return false; + if( readVal(fd, Mmin, LittleEndian ) == false ) return false; + if( readVal(fd, Mmax, LittleEndian ) == false ) return false; + + return true; +} + +void BoundingBox::print() +{ + printf( " Xmin: %G\n", Xmin ); + printf( " Ymin: %G\n", Ymin ); + printf( " Xmax: %G\n", Xmax ); + printf( " Ymax: %G\n", Ymax ); + printf( " Zmin: %G\n", Zmin ); + printf( " Zmax: %G\n", Zmax ); + printf( " Mmin: %G\n", Mmin ); + printf( " Mmax: %G\n", Mmax ); +} + + +bool ShapeHeader::read(int fd) +{ + if( readVal( fd, fileCode, BigEndian ) == false ) return false; + if( ::read( fd, _unused_0, sizeof(_unused_0)) <= 0 ) return false; + if( readVal( fd, fileLength, BigEndian ) == false ) return false; + if( readVal( fd, version, LittleEndian ) == false ) return false; + if( readVal( fd, shapeType, LittleEndian ) == false ) return false; + bbox.read(fd); + return true; +} + +void ShapeHeader::print() +{ + printf( "File Code: %d\n", fileCode ); + printf( "File Length: %d\n", fileLength ); + printf( "Version: %d\n", version ); + printf( "Shape Type: "); printType( ShapeType(shapeType) ); printf( "\n" ); + printf( "Bounding Box:\n" ); + bbox.print(); +} + +RecordHeader::RecordHeader(): + recordNumber(-1), + contentLength(0) +{ +} + +bool RecordHeader::read( int fd ) +{ + if( readVal( fd, recordNumber, BigEndian ) == false ) return false; + if( readVal( fd, contentLength, BigEndian ) == false ) return false; + return true; +} + +void RecordHeader::print() +{ + printf( " Record Number: %d\n", recordNumber ); + printf( "Content Length: %d\n", contentLength ); +} + + + +NullRecord::NullRecord(): + shapeType(ShapeTypeNullShape) +{} + +bool NullRecord::read( int fd ) +{ + if( readVal( fd, shapeType, LittleEndian ) == false ) return false; + return true; +} + + +Box::Box() {} +Box::Box(const Box &b ): + Xmin(b.Xmin), + Ymin(b.Ymin), + Xmax(b.Xmax), + Ymax(b.Ymax) + {} + +bool Box::read( int fd ) +{ + if( readVal(fd, Xmin, LittleEndian) == false ) return false; + if( readVal(fd, Ymin, LittleEndian) == false ) return false; + if( readVal(fd, Xmax, LittleEndian) == false ) return false; + if( readVal(fd, Ymax, LittleEndian) == false ) return false; + return true; +} + +Range::Range() {} +Range::Range( const Range &r ): min(r.min), max(r.max) {} + +bool Range::read( int fd ) +{ + if( readVal(fd, min, LittleEndian ) == false ) return false; + if( readVal(fd, max, LittleEndian ) == false ) return false; + return true; +} + +ShapeObject::ShapeObject(ShapeType s): + shapeType(s) +{} + +ShapeObject::~ShapeObject() +{ } + + + +Point::Point(): + ShapeObject(ShapeTypePoint), + x(0.0), + y(0.0) +{} + +Point::Point(const Point &p): + ShapeObject(ShapeTypePoint), + x(p.x), + y(p.y) +{} + +Point::~Point() {} + +bool Point::read( int fd ) +{ + + if( readVal( fd, x, LittleEndian ) == false ) return false; + if( readVal( fd, y, LittleEndian ) == false ) return false; + + return true; +} + +bool PointRecord::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePoint ) + return false; + + return point.read(fd); +} + +void Point::print() +{ + printf( " %G %G\n", x, y ); +} + +MultiPoint::MultiPoint(): + ShapeObject(ShapeTypeMultiPoint), + numPoints(0), + points(0L) +{} + +MultiPoint::MultiPoint( const struct MultiPoint &mpoint ): ShapeObject(ShapeTypeMultiPoint), + bbox(mpoint.bbox), + numPoints(mpoint.numPoints) +{ + points = new Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + points[i] = mpoint.points[i]; +} + +MultiPoint::~MultiPoint() +{ + delete [] points; +} + +bool MultiPoint::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypeMultiPoint ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + points = new struct Point[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd) == false ) + return false; + } + return true; +} + +void MultiPoint::print() +{ + printf( "Point - numPoints: %d\n", numPoints ); + for( int i= 0; i < numPoints; i++ ) + points[i].print(); +} + + + +PolyLine::PolyLine(): + ShapeObject(ShapeTypePolyLine), + numParts(0), + numPoints(0), + parts(0L), + points(0L) {} + +PolyLine::PolyLine( const PolyLine &p ): + ShapeObject(ShapeTypePolyLine), + numParts(p.numParts), + numPoints(p.numPoints) +{ + parts = new Integer[numParts]; + for( Integer i = 0; i < numParts; i++ ) + parts[i] = p.parts[i]; + + points = new Point[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + points[i] = p.points[i]; +} + +PolyLine::~PolyLine() +{ + delete [] parts; + delete [] points; +} + +bool PolyLine::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePolyLine ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numParts, LittleEndian ) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + parts = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, parts[i], LittleEndian ) == false ) + return false; + + } + points = new struct Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd ) == false ) + return false; + } + return true; +} + + +Polygon::Polygon(): + ShapeObject(ShapeTypePolygon), + numParts(0), + numPoints(0), + parts(0L), + points(0L) {} + + Polygon::Polygon( const Polygon &p ): + ShapeObject(ShapeTypePolygon), + numParts(p.numParts), + numPoints(p.numPoints) +{ + parts = new Integer[numParts]; + for( Integer i = 0; i < numParts; i++ ) + parts[i] = p.parts[i]; + + points = new Point[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + points[i] = p.points[i]; +} + +Polygon::~Polygon() +{ + delete [] parts; + delete [] points; +} + + +bool Polygon::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePolygon ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numParts, LittleEndian ) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + parts = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, parts[i], LittleEndian ) == false ) + return false; + } + points = new struct Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd ) == false ) + return false; + } + return true; +} + +////////////////////////////////////////////////////////////////////// + +PointM::PointM(): + ShapeObject(ShapeTypePointM), + x(0.0), + y(0.0), + m(0.0) +{} + +PointM::PointM(const PointM &p): + ShapeObject(ShapeTypePointM), + x(p.x), + y(p.y), + m(p.m) +{} + +PointM::~PointM() {} + +bool PointM::read( int fd ) +{ + if( readVal( fd, x, LittleEndian ) == false ) return false; + if( readVal( fd, y, LittleEndian ) == false ) return false; + if( readVal( fd, m, LittleEndian ) == false ) return false; + + return true; +} + +void PointM::print() +{ + printf( " %G %G (%G)\n", x, y, m ); +} + +bool PointMRecord::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePointM ) + return false; + + return pointM.read(fd); +} + + +MultiPointM::MultiPointM(): + ShapeObject(ShapeTypeMultiPointM), + numPoints(0), + points(0L), + mArray(0L) +{} + + MultiPointM::MultiPointM( const struct MultiPointM &mpointm ): + ShapeObject(ShapeTypeMultiPointM), + bbox(mpointm.bbox), + numPoints(mpointm.numPoints), + mRange(mpointm.mRange) +{ + points = new Point[numPoints]; + mArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + points[i] = mpointm.points[i]; + mArray[i] = mpointm.mArray[i]; + } +} + +MultiPointM::~MultiPointM() +{ + delete [] points; + delete [] mArray; +} + +bool MultiPointM::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypeMultiPointM ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + points = new struct Point[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd) == false ) + return false; + } + + int X = 40 + (16 * numPoints); + if( rh.contentLength > X ) + { + if( mRange.read(fd) == false ) + return false; + + mArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + if( readVal(fd, mArray[i], LittleEndian ) == false ) + return false; + } + } + + return true; +} + +void MultiPointM::print() +{ + printf( "Point - numPoints: %d\n", numPoints ); + for( int i= 0; i < numPoints; i++ ) + points[i].print(); +} + +PolyLineM::PolyLineM(): + ShapeObject(ShapeTypePolyLineM), + numParts(0), + numPoints(0), + parts(0L), + points(0L), + mArray(0L) +{} + +PolyLineM::PolyLineM(const PolyLineM &p): + ShapeObject(ShapeTypePolyLineM), + numParts(p.numParts), + numPoints(p.numPoints), + parts(0L), + points(0L), + mArray(0L) +{ + parts = new Integer[numParts]; + for( Integer i = 0; i < numParts; i++ ) + parts[i] = p.parts[i]; + + points = new Point[numPoints]; + mArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + points[i] = p.points[i]; + mArray[i] = p.mArray[i]; + } +} + +PolyLineM::~PolyLineM() +{ + delete [] parts; + delete [] points; + delete [] mArray; +} + +bool PolyLineM::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePolyLineM ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numParts, LittleEndian ) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + parts = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, parts[i], LittleEndian ) == false ) + return false; + + } + points = new struct Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd ) == false ) + return false; + } + + int X = 44 + (4 * numParts); + int Y = X + (16 * numPoints); + + if( rh.contentLength > Y ) + { + mRange.read(fd); + mArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, mArray[i], LittleEndian ) == false ) + return false; + } + } + + return true; +} + + +PolygonM::PolygonM(): + ShapeObject(ShapeTypePolygonM), + numParts(0), + numPoints(0), + parts(0L), + points(0L) , + mArray(0L) +{} + +PolygonM::PolygonM(const PolygonM &p): + ShapeObject(ShapeTypePolygonM), + numParts(p.numParts), + numPoints(p.numPoints), + parts(0L), + points(0L) , + mArray(0L) +{ + parts = new Integer[numParts]; + for( Integer i = 0; i < numParts; i++ ) + parts[i] = p.parts[i]; + + points = new Point[numPoints]; + mArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + points[i] = p.points[i]; + mArray[i] = p.mArray[i]; + } +} + +bool PolygonM::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePolygonM ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numParts, LittleEndian ) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + parts = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, parts[i], LittleEndian ) == false ) + return false; + } + points = new struct Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd ) == false ) + return false; + } + + int X = 44 + (4 * numParts); + int Y = X + (16 * numPoints); + + if( rh.contentLength > Y ) + { + if( mRange.read(fd) == false ) + return false; + + mArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, mArray[i], LittleEndian ) == false ) + return false; + } + } + + return true; +} + + +////////////////////////////////////////////////////////////////////// + +PointZ::PointZ(): + ShapeObject(ShapeTypePointZ), + x(0.0), + y(0.0), + z(0.0), + m(0.0) +{} + +PointZ::PointZ(const PointZ &p): + ShapeObject(ShapeTypePointZ), + x(p.x), + y(p.y), + z(p.z), + m(p.m) +{} + +PointZ::~PointZ() {} + +bool PointZ::read( int fd ) +{ + if( readVal( fd, x, LittleEndian ) == false ) return false; + if( readVal( fd, y, LittleEndian ) == false ) return false; + if( readVal( fd, z, LittleEndian ) == false ) return false; + if( readVal( fd, m, LittleEndian ) == false ) return false; + + return true; +} + +void PointZ::print() +{ + printf( " %G %G %G (%G)\n", x, y, z, m ); +} + +bool PointZRecord::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePointZ ) + return false; + + return pointZ.read(fd); +} + + +MultiPointZ::MultiPointZ(): + ShapeObject(ShapeTypeMultiPointZ), + numPoints(0), + points(0L), + zArray(0L), + mArray(0L) + {} + +MultiPointZ::MultiPointZ( const struct MultiPointZ &mpointm ): + ShapeObject(ShapeTypeMultiPointZ), + bbox(mpointm.bbox), + numPoints(mpointm.numPoints), + zRange(mpointm.zRange), + mRange(mpointm.mRange) +{ + points = new Point[numPoints]; + zArray = new Double[numPoints]; + mArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + points[i] = mpointm.points[i]; + zArray[i] = mpointm.zArray[i]; + mArray[i] = mpointm.mArray[i]; + } +} + +MultiPointZ::~MultiPointZ() +{ + delete [] points; + delete [] zArray; + delete [] mArray; +} + +bool MultiPointZ::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypeMultiPointZ ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + points = new struct Point[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd) == false ) + return false; + } + + if( zRange.read(fd) == false ) + return false; + + zArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + if( readVal(fd, zArray[i], LittleEndian) == false ) + return false; + } + + int X = 40 + (16*numPoints); + int Y = X + 16 + (8*numPoints); + if( rh.contentLength > Y ) + { + if( mRange.read(fd) == false ) + return false; + + mArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + if( readVal(fd, mArray[i], LittleEndian ) == false ) + return false; + } + } + + return true; +} + +void MultiPointZ::print() +{ + printf( "Point - numPoints: %d\n", numPoints ); + for( int i= 0; i < numPoints; i++ ) + points[i].print(); +} + + +PolyLineZ::PolyLineZ(): + ShapeObject(ShapeTypePolyLineZ), + numParts(0), + numPoints(0), + parts(0L), + points(0L), + zArray(0L) , + mArray(0L) +{} + +PolyLineZ::PolyLineZ(const PolyLineZ &p): + ShapeObject(ShapeTypePolyLineZ), + numParts(p.numParts), + numPoints(p.numPoints), + parts(0L), + points(0L), + zArray(0L) , + mArray(0L) +{ + parts = new Integer[numParts]; + for( Integer i = 0; i < numParts; i++ ) + parts[i] = p.parts[i]; + + points = new Point[numPoints]; + zArray = new Double[numPoints]; + mArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + points[i] = p.points[i]; + zArray[i] = p.zArray[i]; + mArray[i] = p.mArray[i]; + } +} + +PolyLineZ::~PolyLineZ() +{ + delete [] parts; + delete [] points; + delete [] zArray; + if( mArray != 0L ) + delete [] mArray; +} + +bool PolyLineZ::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePolyLineZ ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numParts, LittleEndian ) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + parts = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, parts[i], LittleEndian ) == false ) + return false; + + } + points = new struct Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd ) == false ) + return false; + } + + zRange.read(fd); + zArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, zArray[i], LittleEndian ) == false ) + return false; + } + + int X = 44 + (4 * numParts); + int Y = X + (15 * numPoints); + int Z = Y + 16 + (8 * numPoints); + + if( rh.contentLength > Z ) + { + mRange.read(fd); + mArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, mArray[i], LittleEndian ) == false ) + return false; + } + } + + return true; +} + + +PolygonZ::PolygonZ(): + ShapeObject(ShapeTypePolygonZ), + numParts(0), + numPoints(0), + parts(0L), + points(0L) , + mArray(0L) +{} + +PolygonZ::PolygonZ(const PolygonZ &p): + ShapeObject(ShapeTypePolygonZ), + numParts(p.numParts), + numPoints(p.numPoints), + parts(0L), + points(0L) , + mArray(0L) +{ + parts = new Integer[numParts]; + for( Integer i = 0; i < numParts; i++ ) + parts[i] = p.parts[i]; + + points = new Point[numPoints]; + mArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + points[i] = p.points[i]; + mArray[i] = p.mArray[i]; + } +} + +PolygonZ::~PolygonZ() +{ + delete [] parts; + delete [] points; + delete [] zArray; + if( mArray != 0L ) + delete [] mArray; +} + +bool PolygonZ::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypePolygonZ ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numParts, LittleEndian ) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + parts = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, parts[i], LittleEndian ) == false ) + return false; + } + points = new struct Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd ) == false ) + return false; + } + + if( zRange.read(fd) == false ) + return false; + + zArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, zArray[i], LittleEndian ) == false ) + return false; + } + + int X = 44 + (4*numParts); + int Y = X + (16*numPoints); + int Z = Y + 16 + (8*numPoints); + if( rh.contentLength > Z ) + { + if( mRange.read(fd) == false ) + return false; + + mArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, mArray[i], LittleEndian ) == false ) + return false; + } + } + + return true; +} + + +////////////////////////////////////////////////////////////////////// + +/* +struct MultiPatch +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + Integer *partTypes; + struct Point *points; + Range zRange; + Double *zArray; + Range mRange; + Double *mArray; + + MultiPatch(); + MultiPatch( const MultiPatch &); + virtual ~MultiPatch(); + bool read( fd ); +}; +*/ + +MultiPatch::MultiPatch(): + numParts(0), + numPoints(0), + parts(0L), + partTypes(0L), + points(0L), + zArray(0L), + mArray(0L) +{ } + +MultiPatch::MultiPatch( const MultiPatch &mp): + bbox(mp.bbox), + numParts(mp.numParts), + numPoints(mp.numPoints), + zRange(mp.zRange), + mRange(mp.mRange) +{ + parts = new Integer[numParts]; + partTypes = new Integer[numParts]; + for( Integer i = 0; i < numParts; i++ ) + { + parts[i] = mp.parts[i]; + partTypes[i] = mp.partTypes[i]; + } + points = new Point[numPoints]; + zArray = new Double[numPoints]; + mArray = new Double[numPoints]; + for( Integer i = 0; i < numPoints; i++ ) + { + points[i] = mp.points[i]; + zArray[i] = mp.zArray[i]; + if( mp.mArray != 0L ) + mArray[i] = mp.mArray[i]; + } +} + +MultiPatch::~MultiPatch() +{ + delete [] parts; + delete [] partTypes; + delete [] points; + delete [] zArray; + if( mArray != 0L ) + delete [] mArray; +} + +bool MultiPatch::read( int fd ) +{ + RecordHeader rh; + if( rh.read(fd) == false ) + return false; + + Integer shapeType; + if( readVal(fd, shapeType, LittleEndian ) == false ) + return false; + + if( shapeType != ShapeTypeMultiPatch ) + return false; + + if( bbox.read(fd) == false ) + return false; + + if( readVal(fd, numParts, LittleEndian ) == false ) + return false; + + if( readVal(fd, numPoints, LittleEndian ) == false ) + return false; + + parts = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, parts[i], LittleEndian ) == false ) + return false; + } + + partTypes = new Integer[numParts]; + for( int i = 0; i < numParts; i++ ) + { + if( readVal(fd, partTypes[i], LittleEndian ) == false ) + return false; + } + + points = new struct Point[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( points[i].read(fd ) == false ) + return false; + } + + if( zRange.read(fd) == false ) + return false; + + zArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, zArray[i], LittleEndian ) == false ) + return false; + } + + int W = 44 + (4*numParts); + int X = W + (4 * numParts); + int Y = X + (16 *numPoints); + int Z = Y + 16 + (8 *numPoints); + if( rh.contentLength > Z ) + { + if( mRange.read(fd) == false ) + return false; + + mArray = new Double[numPoints]; + for( int i = 0; i < numPoints; i++ ) + { + if( readVal(fd, mArray[i], LittleEndian ) == false ) + return false; + } + } + + return true; +} + diff --git a/src/osgPlugins/ESRIShape/ESRIShape.h b/src/osgPlugins/ESRIShape/ESRIShape.h new file mode 100644 index 000000000..743a810cb --- /dev/null +++ b/src/osgPlugins/ESRIShape/ESRIShape.h @@ -0,0 +1,400 @@ +#ifndef OSG_SHAPE_H +#define OSG_SHAPE_H + +#include +#include +#include + +namespace ESRIShape { + +typedef int Integer; +typedef short Short; +typedef unsigned char Byte; +typedef double Double; +typedef unsigned char * BytePtr; + +enum ByteOrder { + LittleEndian, + BigEndian +}; + +enum PartType{ + TriangleStrip = 0, + TriangleFan = 1, + OuterRing = 2, + InnerRing = 3, + FirstRing = 4, + Ring = 5 +}; + +enum ShapeType { + ShapeTypeNullShape = 0, + ShapeTypePoint = 1, + ShapeTypePolyLine = 3, + ShapeTypePolygon = 5, + ShapeTypeMultiPoint = 8, + ShapeTypePointZ = 11, + ShapeTypePolyLineZ = 13, + ShapeTypePolygonZ = 15, + ShapeTypeMultiPointZ = 18, + ShapeTypePointM = 21, + ShapeTypePolyLineM = 23, + ShapeTypePolygonM = 25, + ShapeTypeMultiPointM = 28, + ShapeTypeMultiPatch = 31 +}; + + +struct BoundingBox +{ + Double Xmin; + Double Ymin; + Double Xmax; + Double Ymax; + Double Zmin; + Double Zmax; + Double Mmin; + Double Mmax; + + bool read( int fd ); + + void print(); +}; + +/////////////// + +struct ShapeHeader +{ + Integer fileCode; + Byte _unused_0[20]; + Integer fileLength; + Integer version; + Integer shapeType; + BoundingBox bbox; + + bool read(int fd); + + void print(); +}; + +struct RecordHeader +{ + Integer recordNumber; + Integer contentLength; + + RecordHeader(); + + bool read( int fd ); + + void print(); +}; + + +struct NullRecord +{ + Integer shapeType; + NullRecord(); + + bool read( int fd ); +}; + +////////////////////////////////////////////////////////////////////// + +struct Box +{ + Double Xmin, Ymin, Xmax, Ymax; + + Box(); + Box(const Box &b ); + bool read( int fd ); +}; + +struct Range { + Double min, max; + Range(); + Range( const Range &r ); + + bool read( int fd ); +}; + +struct ShapeObject : public osg::Referenced +{ + ShapeType shapeType; + ShapeObject(ShapeType s); + virtual ~ShapeObject(); +}; + + +struct Point : public ShapeObject +{ + Double x, y; + + Point(); + Point(const Point &p); + virtual ~Point(); + + bool read( int fd ); + void print(); +}; + +struct PointRecord +{ + Point point; + bool read( int fd ); +}; + +struct MultiPoint: public ShapeObject +{ + Box bbox; + Integer numPoints; + struct Point *points; + + MultiPoint(); + + MultiPoint( const struct MultiPoint &mpoint ); + + virtual ~MultiPoint(); + + bool read( int fd ); + + void print(); +}; + +struct PolyLine: public ShapeObject +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + struct Point *points; + + PolyLine(); + + PolyLine( const PolyLine &p ); + + virtual ~PolyLine(); + + bool read( int fd ); +}; + + + +struct Polygon : public ShapeObject +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + Point *points; + + Polygon(); + + Polygon( const Polygon &p ); + + virtual ~Polygon(); + + + bool read( int fd ); +}; + +////////////////////////////////////////////////////////////////////// +struct PointM : public ShapeObject +{ + Double x, y, m; + + PointM(); + + PointM(const PointM &p); + + virtual ~PointM(); + + bool read( int fd ); + + void print(); +}; + +struct PointMRecord +{ + PointM pointM; + + bool read( int fd ); +}; + + +struct MultiPointM: public ShapeObject +{ + Box bbox; + Integer numPoints; + struct Point *points; + struct Range mRange; + Double *mArray; + + MultiPointM(); + + MultiPointM( const struct MultiPointM &mpointm ); + + virtual ~MultiPointM(); + + bool read( int fd ); + + void print(); +}; + + +struct PolyLineM: public ShapeObject +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + struct Point *points; + struct Range mRange; + Double *mArray; + + PolyLineM(); + + PolyLineM(const PolyLineM &p); + + virtual ~PolyLineM(); + + bool read( int fd ); +}; + + +struct PolygonM : public ShapeObject +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + Point *points; + struct Range mRange; + Double *mArray; + + PolygonM(); + + PolygonM(const PolygonM &p); + + bool read( int fd ); +}; + + + + +////////////////////////////////////////////////////////////////////// + + + + +struct PointZ : public ShapeObject +{ + Double x, y, z, m; + + PointZ(); + PointZ(const PointZ &p); + virtual ~PointZ(); + + bool read( int fd ); + + void print(); +}; + +struct PointZRecord +{ + PointZ pointZ; + bool read( int fd ); +}; + +struct MultiPointZ: public ShapeObject +{ + Box bbox; + Integer numPoints; + struct Point *points; + struct Range zRange; + Double *zArray; + struct Range mRange; + Double *mArray; + + MultiPointZ(); + + MultiPointZ( const struct MultiPointZ &); + + virtual ~MultiPointZ(); + + bool read( int fd ); + + void print(); +}; + + + +struct PolyLineZ: public ShapeObject +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + struct Point *points; + struct Range zRange; + Double *zArray; + struct Range mRange; + Double *mArray; + + PolyLineZ(); + + PolyLineZ( const PolyLineZ &p ); + + virtual ~PolyLineZ(); + + bool read( int fd ); +}; + + +struct PolygonZ : public ShapeObject +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + Point *points; + struct Range zRange; + Double *zArray; + struct Range mRange; + Double *mArray; + + PolygonZ(); + + PolygonZ( const PolygonZ &p ); + + virtual ~PolygonZ(); + + + bool read( int fd ); +}; + + +////////////////////////////////////////////////////////////////////// + + +struct MultiPatch +{ + Box bbox; + Integer numParts; + Integer numPoints; + Integer *parts; + Integer *partTypes; + struct Point *points; + Range zRange; + Double *zArray; + Range mRange; + Double *mArray; + + MultiPatch(); + MultiPatch( const MultiPatch &); + virtual ~MultiPatch(); + bool read( int ); +}; + +} + +#endif diff --git a/src/osgPlugins/ESRIShape/ESRIShapeParser.cpp b/src/osgPlugins/ESRIShape/ESRIShapeParser.cpp new file mode 100644 index 000000000..58ff035e8 --- /dev/null +++ b/src/osgPlugins/ESRIShape/ESRIShapeParser.cpp @@ -0,0 +1,582 @@ +#include +#include +#include + +#include "ESRIShapeParser.h" + +using namespace ESRIShape; + +ESRIShapeParser::ESRIShapeParser( const std::string fileName ): + _valid(false) +{ + int fd = 0; + if( !fileName.empty() ) + { + if( (fd = open( fileName.c_str(), O_RDONLY )) <= 0 ) + { + perror( fileName.c_str() ); + return ; + } + } + + _valid = true; + + ESRIShape::ShapeHeader head; + head.read(fd); + + //head.print(); + + _geode = new osg::Geode; + + switch( head.shapeType ) + { + case ESRIShape::ShapeTypeNullShape : + break; + + case ESRIShape::ShapeTypePoint : + { + std::vector pts; + ESRIShape::PointRecord pointRecord; + while( pointRecord.read(fd) ) + pts.push_back( pointRecord.point ); + _process( pts ); + } + break; + + case ESRIShape::ShapeTypeMultiPoint : + { + std::vector mpts; + ESRIShape::MultiPoint mpoint; + + while( mpoint.read(fd) ) + mpts.push_back( mpoint ); + + _process( mpts ); + } + break; + + case ESRIShape::ShapeTypePolyLine : + { + std::vector plines; + ESRIShape::PolyLine pline; + + while( pline.read(fd) ) + plines.push_back( pline ); + + _process( plines ); + + } + break; + + case ESRIShape::ShapeTypePolygon : + { + std::vector polys; + ESRIShape::Polygon poly; + + while( poly.read(fd) ) + polys.push_back( poly ); + + _process( polys ); + } + break; + + case ESRIShape::ShapeTypePointM : + { + std::vector ptms; + ESRIShape::PointMRecord pointMRecord; + while( pointMRecord.read(fd) ) + ptms.push_back( pointMRecord.pointM ); + _process( ptms ); + } + break; + + case ESRIShape::ShapeTypeMultiPointM : + { + std::vector mptms; + ESRIShape::MultiPointM mpointm; + + while( mpointm.read(fd) ) + mptms.push_back( mpointm ); + + _process( mptms ); + } + break; + + case ESRIShape::ShapeTypePolyLineM : + { + std::vector plinems; + ESRIShape::PolyLineM plinem; + + while( plinem.read(fd) ) + plinems.push_back( plinem ); + + _process( plinems ); + } + break; + + case ESRIShape::ShapeTypePolygonM : + { + std::vector polyms; + ESRIShape::PolygonM polym; + + while( polym.read(fd) ) + polyms.push_back( polym ); + + _process( polyms ); + } + break; + + + case ESRIShape::ShapeTypePointZ : + { + std::vector ptzs; + ESRIShape::PointZRecord pointZRecord; + while( pointZRecord.read(fd) ) + ptzs.push_back( pointZRecord.pointZ ); + _process( ptzs ); + } + break; + + case ESRIShape::ShapeTypeMultiPointZ : + { + std::vector mptzs; + ESRIShape::MultiPointZ mpointz; + + while( mpointz.read(fd) ) + mptzs.push_back( mpointz ); + + _process( mptzs ); + } + break; + + case ESRIShape::ShapeTypePolyLineZ : + { + std::vector plinezs; + ESRIShape::PolyLineZ plinez; + + while( plinez.read(fd) ) + plinezs.push_back( plinez ); + + _process( plinezs ); + } + break; + + case ESRIShape::ShapeTypePolygonZ : + { + std::vector polyzs; + ESRIShape::PolygonZ polyz; + + while( polyz.read(fd) ) + polyzs.push_back( polyz ); + + _process( polyzs ); + } + break; + + + case ESRIShape::ShapeTypeMultiPatch : + { + std::vector mpatches; + ESRIShape::MultiPatch mpatch; + + while( mpatch.read( fd ) ) + mpatches.push_back( mpatch ); + + _process(mpatches); + } + break; + + default: + break; + } +} + +osg::Geode *ESRIShapeParser::getGeode() +{ + return _geode.get(); +} + +void ESRIShapeParser::_combinePointToMultipoint() +{ + if( !_valid ) return; + + osg::ref_ptr coords = new osg::Vec3Array; + unsigned int numDrawables = _geode->getNumDrawables(); + + for( unsigned int i = 0; i < numDrawables; i++ ) + { + osg::Geometry *geom = dynamic_cast(_geode->getDrawable(i)); + if( geom != 0L ) + { + osg::Vec3Array *va = dynamic_cast(geom->getVertexArray()); + if( va != 0L ) + coords->push_back( va->front() ); + } + } + + _geode->removeDrawable( 0, numDrawables ); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, coords->size())); + _geode->addDrawable( geometry.get() ); +} + +void ESRIShapeParser::_process( const std::vector &pts ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = pts.begin(); p != pts.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + coords->push_back( osg::Vec3( p->x, p->y, 0.0 )); + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 1)); + _geode->addDrawable( geometry.get() ); + } + if( _geode->getNumDrawables() > 1 ) + _combinePointToMultipoint(); +} + + +void ESRIShapeParser::_process( const std::vector &mpts ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = mpts.begin(); p != mpts.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + for( int i = 0; i < p->numPoints ; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, 0.0 )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, coords->size())); + + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process(const std::vector &lines ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = lines.begin(); p != lines.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + + for( int i = 0; i < p->numPoints; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, 0.0 )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + + for( int i = 0; i < p->numParts; i++ ) + { + int index = p->parts[i]; + int len = i < p->numParts - 1 ? + p->parts[i+1] - p->parts[i] : + p->numPoints - p->parts[i]; + + geometry->addPrimitiveSet( + new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, index, len)); + } + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process( const std::vector &polys ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = polys.begin(); p != polys.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + for( int i = 0; i < p->numPoints; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, 0.0 )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + + for( int i = 0; i < p->numParts; i++ ) + { + int index = p->parts[i]; + int len = i < p->numParts - 1 ? + p->parts[i+1] - p->parts[i] : + p->numPoints - p->parts[i]; + + geometry->addPrimitiveSet( + new osg::DrawArrays(osg::PrimitiveSet::POLYGON, index, len)); + } + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process( const std::vector &ptms ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = ptms.begin(); p != ptms.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + coords->push_back( osg::Vec3( p->x, p->y, 0.0 )); + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 1)); + _geode->addDrawable( geometry.get() ); + } + if( _geode->getNumDrawables() > 1 ) + _combinePointToMultipoint(); +} + +void ESRIShapeParser::_process( const std::vector &mptms ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = mptms.begin(); p != mptms.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + + // Here is where we would use the 'M' (?) + for( int i = 0; i < p->numPoints ; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, 0.0 )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, coords->size())); + + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process(const std::vector &linems ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = linems.begin(); p != linems.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + + for( int i = 0; i < p->numPoints; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, 0.0 )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + + for( int i = 0; i < p->numParts; i++ ) + { + int index = p->parts[i]; + int len = i < p->numParts - 1 ? + p->parts[i+1] - p->parts[i] : + p->numPoints - p->parts[i]; + + geometry->addPrimitiveSet( + new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, index, len)); + } + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process( const std::vector &polyms ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = polyms.begin(); p != polyms.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + for( int i = 0; i < p->numPoints; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, 0.0 )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + + for( int i = 0; i < p->numParts; i++ ) + { + int index = p->parts[i]; + int len = i < p->numParts - 1 ? + p->parts[i+1] - p->parts[i] : + p->numPoints - p->parts[i]; + + geometry->addPrimitiveSet( + new osg::DrawArrays(osg::PrimitiveSet::POLYGON, index, len)); + } + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process( const std::vector &ptzs ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = ptzs.begin(); p != ptzs.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + coords->push_back( osg::Vec3( p->x, p->y, p->z )); + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 1)); + _geode->addDrawable( geometry.get() ); + } + if( _geode->getNumDrawables() > 1 ) + _combinePointToMultipoint(); +} + +void ESRIShapeParser::_process( const std::vector &mptzs ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = mptzs.begin(); p != mptzs.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + + // Here is where we would use the 'M' (?) + for( int i = 0; i < p->numPoints ; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, p->zArray[i] )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, coords->size())); + + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process(const std::vector &linezs ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = linezs.begin(); p != linezs.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + + for( int i = 0; i < p->numPoints; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, p->zArray[i] )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + + for( int i = 0; i < p->numParts; i++ ) + { + int index = p->parts[i]; + int len = i < p->numParts - 1 ? + p->parts[i+1] - p->parts[i] : + p->numPoints - p->parts[i]; + + geometry->addPrimitiveSet( + new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, index, len)); + } + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process( const std::vector &polyzs ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = polyzs.begin(); p != polyzs.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + for( int i = 0; i < p->numPoints; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, p->zArray[i] )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + + for( int i = 0; i < p->numParts; i++ ) + { + int index = p->parts[i]; + int len = i < p->numParts - 1 ? + p->parts[i+1] - p->parts[i] : + p->numPoints - p->parts[i]; + + geometry->addPrimitiveSet( + new osg::DrawArrays(osg::PrimitiveSet::POLYGON, index, len)); + } + _geode->addDrawable( geometry.get() ); + } +} + +void ESRIShapeParser::_process( const std::vector &mpatches ) +{ + if( !_valid ) return; + + std::vector::const_iterator p; + for( p = mpatches.begin(); p != mpatches.end(); p++ ) + { + osg::ref_ptr coords = new osg::Vec3Array; + for( int i = 0; i < p->numPoints; i++ ) + coords->push_back( osg::Vec3( p->points[i].x, p->points[i].y, p->zArray[i] )); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setVertexArray(coords.get()); + + // Lets mark poorly supported primitives with red, otherwise white + osg::ref_ptr colors = new osg::Vec4Array; + geometry->setColorArray(colors.get()); + geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX ); + + for( int i = 0; i < p->numParts; i++ ) + { + int index = p->parts[i]; + int len = i < p->numParts - 1 ? + p->parts[i+1] - p->parts[i] : + p->numPoints - p->parts[i]; + + int mode = + p->partTypes[i] == TriangleStrip ? osg::PrimitiveSet::TRIANGLE_STRIP : + p->partTypes[i] == TriangleFan ? osg::PrimitiveSet::TRIANGLE_FAN : + // HACK for now + p->partTypes[i] == OuterRing ? osg::PrimitiveSet::LINE_STRIP : + p->partTypes[i] == InnerRing ? osg::PrimitiveSet::LINE_STRIP : + p->partTypes[i] == FirstRing ? osg::PrimitiveSet::LINE_STRIP : + p->partTypes[i] == Ring ? osg::PrimitiveSet::LINE_STRIP : + osg::PrimitiveSet::POINTS ; + + if( p->partTypes[i] == OuterRing || + p->partTypes[i] == InnerRing || + p->partTypes[i] == FirstRing || p->partTypes[i] == Ring ) + { + osg::notify(osg::WARN) << "ESRIShapeParser - MultiPatch type " << + (p->partTypes[i] == TriangleStrip ? "TriangleStrip": + p->partTypes[i] == TriangleFan ? "TriangleFan": + p->partTypes[i] == OuterRing ? "OuterRing": + p->partTypes[i] == InnerRing ? "InnerRing": + p->partTypes[i] == FirstRing ? "FirstRing": + p->partTypes[i] == Ring ? "Ring": "Dunno") << + " poorly supported. Will be represented by a red line strip" << std::endl; + } + + + + // Lets mark poorly supported primitives with red, otherwise white + osg::Vec4 color = + p->partTypes[i] == TriangleStrip ? osg::Vec4(1.0,1.0,1.0,1.0) : + p->partTypes[i] == TriangleFan ? osg::Vec4(1.0,1.0,1.0,1.0) : + // HACK for now + p->partTypes[i] == OuterRing ? osg::Vec4(1.0,0.0,0.0,1.0) : + p->partTypes[i] == InnerRing ? osg::Vec4(1.0,0.0,0.0,1.0) : + p->partTypes[i] == FirstRing ? osg::Vec4(1.0,0.0,0.0,1.0) : + p->partTypes[i] == Ring ? osg::Vec4(1.0,0.0,0.0,1.0) : + osg::Vec4(1.0,0.0,0.0,1.0) ; + for( int i = 0; i < len; i++ ) + colors->push_back( color ); + + geometry->addPrimitiveSet( new osg::DrawArrays(mode, index, len )); + } + + _geode->addDrawable( geometry.get() ); + } +} diff --git a/src/osgPlugins/ESRIShape/ESRIShapeParser.h b/src/osgPlugins/ESRIShape/ESRIShapeParser.h new file mode 100644 index 000000000..1af1586c5 --- /dev/null +++ b/src/osgPlugins/ESRIShape/ESRIShapeParser.h @@ -0,0 +1,43 @@ +#ifndef ESRI_SHAPE_PARSER_H +#define ESRI_SHAPE_PARSER_H + +#include +#include + +#include "ESRIShape.h" + +namespace ESRIShape { + +class ESRIShapeParser +{ + public: + ESRIShapeParser( const std::string fileName="" ); + + osg::Geode *getGeode(); + + private: + bool _valid; + osg::ref_ptr _geode; + + void _combinePointToMultipoint(); + void _process( const std::vector &); + void _process( const std::vector &); + void _process( const std::vector &); + void _process( const std::vector &); + + void _process( const std::vector &); + void _process( const std::vector &); + void _process( const std::vector &); + void _process( const std::vector &); + + void _process( const std::vector &); + void _process( const std::vector &); + void _process( const std::vector &); + void _process( const std::vector &); + void _process( const std::vector &); + +}; + +} + +#endif diff --git a/src/osgPlugins/ESRIShape/ESRIShapeReaderWriter.cpp b/src/osgPlugins/ESRIShape/ESRIShapeReaderWriter.cpp new file mode 100644 index 000000000..72c6bd9bd --- /dev/null +++ b/src/osgPlugins/ESRIShape/ESRIShapeReaderWriter.cpp @@ -0,0 +1,36 @@ +#include +#include + +#include "ESRIShape.h" +#include "ESRIShapeParser.h" + +class ESRIShapeReaderWriter : public osgDB::ReaderWriter +{ + public: + ESRIShapeReaderWriter() {} + + virtual const char* className() { return "ESRI Shape ReaderWriter"; } + + virtual bool acceptsExtension(const std::string& extension) const + { + return osgDB::equalCaseInsensitive(extension,"shp"); + } + + virtual ReadResult readObject(const std::string& fileName, const Options* opt) const + { return readNode(fileName,opt); } + + virtual ReadResult readNode(const std::string& fileName, const Options* ) const + { + std::string ext = osgDB::getFileExtension(fileName); + if (!acceptsExtension(ext)) + return ReadResult::FILE_NOT_HANDLED; + + ESRIShape::ESRIShapeParser sp(fileName); + return sp.getGeode(); + } + + private: +}; + +osgDB::RegisterReaderWriterProxy g_esriShapeReaderWriter_Proxy; + diff --git a/src/osgPlugins/ESRIShape/GNUmakefile b/src/osgPlugins/ESRIShape/GNUmakefile new file mode 100644 index 000000000..d77ce5059 --- /dev/null +++ b/src/osgPlugins/ESRIShape/GNUmakefile @@ -0,0 +1,15 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + ESRIShape.cpp\ + ESRIShapeParser.cpp\ + ESRIShapeReaderWriter.cpp\ + +LIBS += $(OSG_LIBS) $(OTHER_LIBS) $(SOCKET_LIBS) + +TARGET_BASENAME = shp +include $(TOPDIR)/Make/cygwin_plugin_def +PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT) + +include $(TOPDIR)/Make/makerules diff --git a/src/osgPlugins/logo/ReaderWriterLOGO.cpp b/src/osgPlugins/logo/ReaderWriterLOGO.cpp index 161ba2722..7e632dd1a 100644 --- a/src/osgPlugins/logo/ReaderWriterLOGO.cpp +++ b/src/osgPlugins/logo/ReaderWriterLOGO.cpp @@ -23,56 +23,56 @@ class Logos: public osg::Drawable { public: enum RelativePosition{ - Center, - UpperLeft, - UpperRight, - LowerLeft, - LowerRight, - UpperCenter, - LowerCenter, - last_position + Center, + UpperLeft, + UpperRight, + LowerLeft, + LowerRight, + UpperCenter, + LowerCenter, + last_position }; - struct logosCullCallback : public osg::Drawable::CullCallback - { + struct logosCullCallback : public osg::Drawable::CullCallback + { virtual bool cull(osg::NodeVisitor *visitor, osg::Drawable* drawable, osg::State*) const - { - Logos *logos = dynamic_cast (drawable); - osgUtil::CullVisitor *cv = dynamic_cast(visitor); - if( logos != NULL && cv != NULL ) - { - osg::Viewport *vp = cv->getViewport(); - if( vp != NULL ) - { - int x, y, aw, ah, bw, bh; - logos->getViewport()->getViewport( x, y, aw, ah ); - vp->getViewport(x, y, bw, bh ); - if( aw != bw || ah != bh ) - { - logos->getViewport()->setViewport( x, y, bw, bh ); - logos->dirtyDisplayList(); - } - } - } - return false; - } - }; + { + Logos *logos = dynamic_cast (drawable); + osgUtil::CullVisitor *cv = dynamic_cast(visitor); + if( logos != NULL && cv != NULL ) + { + osg::Viewport *vp = cv->getViewport(); + if( vp != NULL ) + { + int x, y, aw, ah, bw, bh; + logos->getViewport()->getViewport( x, y, aw, ah ); + vp->getViewport(x, y, bw, bh ); + if( aw != bw || ah != bh ) + { + logos->getViewport()->setViewport( x, y, bw, bh ); + logos->dirtyDisplayList(); + } + } + } + return false; + } + }; - Logos() - { - osg::StateSet *sset = new osg::StateSet; - osg::BlendFunc *transp = new osg::BlendFunc; - transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - sset->setAttribute( transp ); - sset->setMode( GL_BLEND, osg::StateAttribute::ON ); - sset->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF ); - sset->setTextureMode( 0, GL_TEXTURE_2D, osg::StateAttribute::OFF ); - sset->setRenderBinDetails( StateSet::TRANSPARENT_BIN + 1 , "RenderBin" ); - setStateSet( sset ); - viewport = new osg::Viewport; - setCullCallback( new logosCullCallback ); - _contextID = 0; - } + Logos() + { + osg::StateSet *sset = new osg::StateSet; + osg::BlendFunc *transp = new osg::BlendFunc; + transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + sset->setAttribute( transp ); + sset->setMode( GL_BLEND, osg::StateAttribute::ON ); + sset->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF ); + sset->setTextureMode( 0, GL_TEXTURE_2D, osg::StateAttribute::OFF ); + sset->setRenderBinDetails( StateSet::TRANSPARENT_BIN + 1 , "RenderBin" ); + setStateSet( sset ); + viewport = new osg::Viewport; + setCullCallback( new logosCullCallback ); + _contextID = 0; + } Logos(const Logos& logo, const CopyOp& copyop=CopyOp::SHALLOW_COPY) :Drawable( logo, copyop ) {} @@ -82,92 +82,93 @@ class Logos: public osg::Drawable virtual const char* className() const { return "Logos"; } virtual void drawImplementation(osg::State &state ) const - { - if( state.getContextID() != _contextID ) return; + { + if( state.getContextID() != _contextID ) + return; - int x = 0, y = 0, w = 1, h = 1; - if( viewport != NULL ) - viewport->getViewport( x, y, w, h ); - float vx = x; - float vy = y; - float vw = w; - float vh = h; + int x = 0, y = 0, w = 1, h = 1; + if( viewport != NULL ) + viewport->getViewport( x, y, w, h ); + float vx = x; + float vy = y; + float vw = w; + float vh = h; - glMatrixMode( GL_PROJECTION ); + glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); - glOrtho( 0.0, vw, 0.0, vh, -1.0, 1.0 ); + glOrtho( 0.0, vw, 0.0, vh, -1.0, 1.0 ); - glMatrixMode( GL_MODELVIEW ); - glPushMatrix(); - glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); - glColor4f( 1, 1, 1, 1 ); + glColor4f( 1, 1, 1, 1 ); - std::vector ::const_iterator p; - float th = 0.0; - for( p = logos[Center].begin(); p != logos[Center].end(); p++ ) - th += (*p)->t(); + std::vector ::const_iterator p; + float th = 0.0; + for( p = logos[Center].begin(); p != logos[Center].end(); p++ ) + th += (*p)->t(); - float place[][4] = { - { vw*0.5, ((vh*0.5) + th*0.5), -0.5, -1.0 }, - { vx, vh, 0.0, -1.0 }, - { vw, vh, -1.0, -1.0 }, - { vx, vy, 0.0, 1.0 }, - { vw, vy, -1.0, 1.0 }, - { vw*0.5, vh , -0.5, -1.0 }, - { vw*0.5, 0.0 , -0.5, 1.0 }, - }; + float place[][4] = { + { vw*0.5, ((vh*0.5) + th*0.5), -0.5, -1.0 }, + { vx, vh, 0.0, -1.0 }, + { vw, vh, -1.0, -1.0 }, + { vx, vy, 0.0, 1.0 }, + { vw, vy, -1.0, 1.0 }, + { vw*0.5, vh , -0.5, -1.0 }, + { vw*0.5, 0.0 , -0.5, 1.0 }, + }; - for( int i = Center; i < last_position; i++ ) - { - if( logos[i].size() != 0 ) - { - float x = place[i][0]; - float y = place[i][1]; - float xi = place[i][2]; - float yi = place[i][3]; - for( p = logos[i].begin(); p != logos[i].end(); p++ ) - { - osg::Image *img = *p; - x = place[i][0] + xi * img->s(); - if( i == Center || i == UpperLeft || i == UpperRight || i == UpperCenter) - y += yi * img->t(); - glRasterPos2f( x, y ); - glDrawPixels( img->s(), img->t(), img->getPixelFormat(), img->getDataType(), img->data() ); - if( i == LowerLeft || i == LowerRight || i == LowerCenter) - y += yi * img->t(); - } - } - } + for( int i = Center; i < last_position; i++ ) + { + if( logos[i].size() != 0 ) + { + float x = place[i][0]; + float y = place[i][1]; + float xi = place[i][2]; + float yi = place[i][3]; + for( p = logos[i].begin(); p != logos[i].end(); p++ ) + { + osg::Image *img = *p; + x = place[i][0] + xi * img->s(); + if( i == Center || i == UpperLeft || i == UpperRight || i == UpperCenter) + y += yi * img->t(); + glRasterPos2f( x, y ); + glDrawPixels( img->s(), img->t(), img->getPixelFormat(), img->getDataType(), img->data() ); + if( i == LowerLeft || i == LowerRight || i == LowerCenter) + y += yi * img->t(); + } + } + } - glPopMatrix(); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - } + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + } - void addLogo( RelativePosition pos, std::string name ) - { - osg::Image *image = osgDB::readImageFile( name.c_str() ); - if( image != NULL ) - logos[pos].push_back( image ); - } + void addLogo( RelativePosition pos, std::string name ) + { + osg::Image *image = osgDB::readImageFile( name.c_str() ); + if( image != NULL ) + logos[pos].push_back( image ); + } - osg::Viewport *getViewport() { return viewport; } - void setContextID( unsigned int id ) { _contextID = id; } + osg::Viewport *getViewport() { return viewport; } + void setContextID( unsigned int id ) { _contextID = id; } - bool hasLogos() - { - int n = 0; - for( int i = Center; i <= last_position; i++ ) - n += logos[i].size(); - return (n != 0); - } + bool hasLogos() + { + int n = 0; + for( int i = Center; i <= last_position; i++ ) + n += logos[i].size(); + return (n != 0); + } virtual osg::BoundingBox computeBound() const - { - return osg::BoundingBox( -1, -1, -1, 1, 1, 1); + { + return osg::BoundingBox( -1, -1, -1, 1, 1, 1); } protected: @@ -175,15 +176,15 @@ class Logos: public osg::Drawable virtual ~Logos() {} private : - std::vector logos[last_position]; - osg::Viewport *viewport; - unsigned int _contextID; + std::vector logos[last_position]; + osg::Viewport *viewport; + unsigned int _contextID; }; class LOGOReaderWriter : public osgDB::ReaderWriter { -public: + public: virtual const char* className() const { return "Logo Database Reader/Writer"; } virtual bool acceptsExtension(const std::string& extension) const @@ -197,80 +198,81 @@ public: if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); - if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + if (fileName.empty()) + return ReadResult::FILE_NOT_FOUND; osg::notify(osg::INFO)<< "ReaderWriterLOGO::readNode( "<setContextID( screen ); + Logos* ld = new Logos; + ld->setContextID( screen ); - Logos::RelativePosition pos = Logos::LowerRight; + Logos::RelativePosition pos = Logos::LowerRight; - FILE *fp; - if( (fp = fopen( fileName.c_str(), "r")) == NULL ) - return NULL; - while( !feof(fp)) - { - char buff[128]; + FILE *fp; + if( (fp = fopen( fileName.c_str(), "r")) == NULL ) + return NULL; + while( !feof(fp)) + { + char buff[128]; - if( fscanf( fp, "%s", buff ) != 1 ) - break; + if( fscanf( fp, "%s", buff ) != 1 ) + break; - std::string str(buff); + std::string str(buff); - if( str == "Center" ) - pos = Logos::Center; - else if( str == "UpperLeft" ) - pos = Logos::UpperLeft; - else if( str == "UpperRight" ) - pos = Logos::UpperRight; - else if( str == "LowerLeft" ) - pos = Logos::LowerLeft; - else if( str == "LowerRight" ) - pos = Logos::LowerRight; - else if( str == "UpperCenter" ) - pos = Logos::UpperCenter; - else if( str == "LowerCenter" ) - pos = Logos::LowerCenter; - else if( str == "Camera" ) - { - unsigned int n; - if( (fscanf( fp, "%d", &n )) != 1 ) - { - osg::notify(osg::WARN) << "Error... Camera requires an integer argument\n"; - break; - } - if( screen != n ) - { - screen = n; - if( ld->hasLogos() ) - { - geode->addDrawable( ld ); - ld = new Logos; - ld->setContextID( screen ); - } - else - ld->setContextID( screen ); - } - } - else - { - if( str.length() ) - ld->addLogo( pos, str ); - } - } - fclose( fp ); - - if( ld->hasLogos() ) - geode->addDrawable( ld ); - - geode->setCullingActive(false); - return geode; - } + if( str == "Center" ) + pos = Logos::Center; + else if( str == "UpperLeft" ) + pos = Logos::UpperLeft; + else if( str == "UpperRight" ) + pos = Logos::UpperRight; + else if( str == "LowerLeft" ) + pos = Logos::LowerLeft; + else if( str == "LowerRight" ) + pos = Logos::LowerRight; + else if( str == "UpperCenter" ) + pos = Logos::UpperCenter; + else if( str == "LowerCenter" ) + pos = Logos::LowerCenter; + else if( str == "Camera" ) + { + unsigned int n; + if( (fscanf( fp, "%d", &n )) != 1 ) + { + osg::notify(osg::WARN) << "Error... Camera requires an integer argument\n"; + break; + } + if( screen != n ) + { + screen = n; + if( ld->hasLogos() ) + { + geode->addDrawable( ld ); + ld = new Logos; + ld->setContextID( screen ); + } + else + ld->setContextID( screen ); + } + } + else + { + if( str.length() ) + ld->addLogo( pos, str ); + } + } + fclose( fp ); + + if( ld->hasLogos() ) + geode->addDrawable( ld ); + + geode->setCullingActive(false); + return geode; + } }; diff --git a/src/osgPlugins/net/ReaderWriterNET.cpp b/src/osgPlugins/net/ReaderWriterNET.cpp index 65d8f18a1..3cb1b10fe 100644 --- a/src/osgPlugins/net/ReaderWriterNET.cpp +++ b/src/osgPlugins/net/ReaderWriterNET.cpp @@ -136,7 +136,7 @@ class NetReader : public osgDB::ReaderWriter { osg::Timer_t start = osg::Timer::instance()->tick(); - osg::notify(osg::NOTICE) << "osgPlugin .net: start load" << inFileName << std::endl; + //osg::notify(osg::NOTICE) << "osgPlugin .net: start load" << inFileName << std::endl; std::string hostname; std::string serverPrefix; @@ -234,8 +234,8 @@ class NetReader : public osgDB::ReaderWriter if( !serverPrefix.empty() ) fileName = serverPrefix + '/' + fileName; - osg::notify(osg::WARN) << "hostname " << hostname << std::endl; - osg::notify(osg::WARN) << "filename " << fileName << std::endl; + //osg::notify(osg::WARN) << "hostname " << hostname << std::endl; + //osg::notify(osg::WARN) << "filename " << fileName << std::endl; // Invoke the reader corresponding to the extension