void QgsMssqlGeometryParser::ReadGeometryCollection( int iShape ) { int i; int iCount = nNumShapes - iShape - 1;; if ( iCount <= 0 ) return; // copy byte order CopyBytes( &chByteOrder, 1 ); // copy type int wkbType = QGis::WKBUnknown;; CopyBytes( &wkbType, 4 ); // copy geom count CopyBytes( &iCount, 4 ); for ( i = iShape + 1; i < nNumShapes; i++ ) { if ( ParentOffset( i ) == ( unsigned int )iShape ) { switch ( ShapeType( i ) ) { case ST_POINT: ReadPoint( i ); break; case ST_LINESTRING: ReadLineString( i ); break; case ST_POLYGON: ReadPolygon( i ); break; case ST_MULTIPOINT: ReadMultiPoint( i ); break; case ST_MULTILINESTRING: ReadMultiLineString( i ); break; case ST_MULTIPOLYGON: ReadMultiPolygon( i ); break; case ST_GEOMETRYCOLLECTION: ReadGeometryCollection( i ); break; } } } }
OGRGeometryCollection* OGRMSSQLGeometryParser::ReadGeometryCollection(int iShape) { int i; OGRGeometryCollection* poGeomColl = new OGRGeometryCollection(); OGRGeometry* poGeom; for (i = iShape + 1; i < nNumShapes; i++) { poGeom = NULL; if (ParentOffset(i) == (unsigned int)iShape) { switch (ShapeType(i)) { case ST_POINT: poGeom = ReadPoint(i); break; case ST_LINESTRING: poGeom = ReadLineString(i); break; case ST_POLYGON: poGeom = ReadPolygon(i); break; case ST_MULTIPOINT: poGeom = ReadMultiPoint(i); break; case ST_MULTILINESTRING: poGeom = ReadMultiLineString(i); break; case ST_MULTIPOLYGON: poGeom = ReadMultiPolygon(i); break; case ST_GEOMETRYCOLLECTION: poGeom = ReadGeometryCollection(i); break; } } if ( poGeom ) poGeomColl->addGeometryDirectly( poGeom ); } return poGeomColl; }
mapnik::geometry::geometry_collection<double> sqlserver_geometry_parser::ReadGeometryCollection(int iShape) { mapnik::geometry::geometry_collection<double> geom; for (int i = iShape + 1; i < nNumShapes; i++) { mapnik::geometry::geometry<double> shape = mapnik::geometry::geometry_empty(); if (ParentOffset(i) == (unsigned int)iShape) { switch (ShapeType(i)) { case ST_POINT: shape = ReadPoint(i); break; case ST_LINESTRING: shape = ReadLineString(i); break; case ST_POLYGON: shape = ReadPolygon(i); break; case ST_MULTIPOINT: shape = ReadMultiPoint(i); break; case ST_MULTILINESTRING: shape = ReadMultiLineString(i); break; case ST_MULTIPOLYGON: shape = ReadMultiPolygon(i); break; case ST_GEOMETRYCOLLECTION: shape = ReadGeometryCollection(i); break; } } geom.push_back(shape); } return geom; }
unsigned char* QgsMssqlGeometryParser::ParseSqlGeometry( unsigned char* pszInput, int nLen ) { if ( nLen < 10 ) { QgsDebugMsg( "ParseSqlGeometry not enough data" ); DumpMemoryToLog( "Not enough data", pszInput, nLen ); return NULL; } pszData = pszInput; nWkbMaxLen = nLen; /* store the SRS id for further use */ nSRSId = ReadInt32( 0 ); if ( ReadByte( 4 ) != 1 ) { QgsDebugMsg( "ParseSqlGeometry corrupt data" ); DumpMemoryToLog( "Corrupt data", pszInput, nLen ); return NULL; } chProps = ReadByte( 5 ); if ( chProps & SP_HASZVALUES && chProps & SP_HASMVALUES ) nPointSize = 32; else if ( chProps & SP_HASZVALUES || chProps & SP_HASMVALUES ) nPointSize = 24; else nPointSize = 16; /* store byte order */ chByteOrder = QgsApplication::endian(); pszWkb = new unsigned char[nLen]; // wkb should be less or equal in size nWkbLen = 0; if ( chProps & SP_ISSINGLEPOINT ) { // single point geometry nNumPoints = 1; nPointPos = 6; if ( nLen < 6 + nPointSize ) { delete [] pszWkb; QgsDebugMsg( "ParseSqlGeometry not enough data" ); DumpMemoryToLog( "Not enough data", pszInput, nLen ); return NULL; } CopyPoint( 0 ); } else if ( chProps & SP_ISSINGLELINESEGMENT ) { // single line segment with 2 points nNumPoints = 2; nPointPos = 6; if ( nLen < 6 + 2 * nPointSize ) { delete [] pszWkb; QgsDebugMsg( "ParseSqlGeometry not enough data" ); DumpMemoryToLog( "Not enough data", pszInput, nLen ); return NULL; } // copy byte order CopyBytes( &chByteOrder, 1 ); // copy type int wkbType; if ( chProps & SP_HASZVALUES ) wkbType = QGis::WKBLineString25D; else wkbType = QGis::WKBLineString; CopyBytes( &wkbType, 4 ); // copy point count int iCount = 2; CopyBytes( &iCount, 4 ); // copy points CopyCoordinates( 0 ); CopyCoordinates( 1 ); } else { // complex geometries nNumPoints = ReadInt32( 6 ); if ( nNumPoints <= 0 ) { delete [] pszWkb; return NULL; } // position of the point array nPointPos = 10; // position of the figures nFigurePos = nPointPos + nPointSize * nNumPoints + 4; if ( nLen < nFigurePos ) { delete [] pszWkb; QgsDebugMsg( "ParseSqlGeometry not enough data" ); DumpMemoryToLog( "Not enough data", pszInput, nLen ); return NULL; } nNumFigures = ReadInt32( nFigurePos - 4 ); if ( nNumFigures <= 0 ) { delete [] pszWkb; return NULL; } // position of the shapes nShapePos = nFigurePos + 5 * nNumFigures + 4; if ( nLen < nShapePos ) { delete [] pszWkb; QgsDebugMsg( "ParseSqlGeometry not enough data" ); DumpMemoryToLog( "Not enough data", pszInput, nLen ); return NULL; } nNumShapes = ReadInt32( nShapePos - 4 ); if ( nLen < nShapePos + 9 * nNumShapes ) { delete [] pszWkb; QgsDebugMsg( "ParseSqlGeometry not enough data" ); DumpMemoryToLog( "Not enough data", pszInput, nLen ); return NULL; } if ( nNumShapes <= 0 ) { delete [] pszWkb; return NULL; } // pick up the root shape if ( ParentOffset( 0 ) != 0xFFFFFFFF ) { delete [] pszWkb; QgsDebugMsg( "ParseSqlGeometry corrupt data" ); DumpMemoryToLog( "Not enough data", pszInput, nLen ); return NULL; } // determine the shape type switch ( ShapeType( 0 ) ) { case ST_POINT: ReadPoint( 0 ); break; case ST_LINESTRING: ReadLineString( 0 ); break; case ST_POLYGON: ReadPolygon( 0 ); break; case ST_MULTIPOINT: ReadMultiPoint( 0 ); break; case ST_MULTILINESTRING: ReadMultiLineString( 0 ); break; case ST_MULTIPOLYGON: ReadMultiPolygon( 0 ); break; //case ST_GEOMETRYCOLLECTION: //ReadGeometryCollection(0); //break; default: delete [] pszWkb; QgsDebugMsg( "ParseSqlGeometry unsupported geometry type" ); DumpMemoryToLog( "Unsupported geometry type", pszInput, nLen ); return NULL; } } return pszWkb; }
OGRErr OGRMSSQLGeometryParser::ParseSqlGeometry(unsigned char* pszInput, int nLen, OGRGeometry **poGeom) { if (nLen < 10) return OGRERR_NOT_ENOUGH_DATA; pszData = pszInput; /* store the SRS id for further use */ nSRSId = ReadInt32(0); if ( ReadByte(4) != 1 ) { return OGRERR_CORRUPT_DATA; } chProps = ReadByte(5); if ( chProps & SP_HASMVALUES ) nPointSize = 32; else if ( chProps & SP_HASZVALUES ) nPointSize = 24; else nPointSize = 16; if ( chProps & SP_ISSINGLEPOINT ) { // single point geometry nNumPoints = 1; nPointPos = 6; if (nLen < 6 + nPointSize) { return OGRERR_NOT_ENOUGH_DATA; } if (nColType == MSSQLCOLTYPE_GEOGRAPHY) { if (chProps & SP_HASZVALUES) *poGeom = new OGRPoint(ReadY(0), ReadX(0), ReadZ(0)); else *poGeom = new OGRPoint(ReadY(0), ReadX(0)); } else { if (chProps & SP_HASZVALUES) *poGeom = new OGRPoint(ReadX(0), ReadY(0), ReadZ(0)); else *poGeom = new OGRPoint(ReadX(0), ReadY(0)); } } else if ( chProps & SP_ISSINGLELINESEGMENT ) { // single line segment with 2 points nNumPoints = 2; nPointPos = 6; if (nLen < 6 + 2 * nPointSize) { return OGRERR_NOT_ENOUGH_DATA; } OGRLineString* line = new OGRLineString(); line->setNumPoints(2); if (nColType == MSSQLCOLTYPE_GEOGRAPHY) { if ( chProps & SP_HASZVALUES ) { line->setPoint(0, ReadY(0), ReadX(0), ReadZ(0)); line->setPoint(1, ReadY(1), ReadX(1), ReadZ(1)); } else { line->setPoint(0, ReadY(0), ReadX(0)); line->setPoint(1, ReadY(1), ReadX(1)); } } else { if ( chProps & SP_HASZVALUES ) { line->setPoint(0, ReadX(0), ReadY(0), ReadZ(0)); line->setPoint(1, ReadX(1), ReadY(1), ReadZ(1)); } else { line->setPoint(0, ReadX(0), ReadY(0)); line->setPoint(1, ReadX(1), ReadY(1)); } } *poGeom = line; } else { // complex geometries nNumPoints = ReadInt32(6); if ( nNumPoints <= 0 ) { return OGRERR_NONE; } // position of the point array nPointPos = 10; // position of the figures nFigurePos = nPointPos + nPointSize * nNumPoints + 4; if (nLen < nFigurePos) { return OGRERR_NOT_ENOUGH_DATA; } nNumFigures = ReadInt32(nFigurePos - 4); if ( nNumFigures <= 0 ) { return OGRERR_NONE; } // position of the shapes nShapePos = nFigurePos + 5 * nNumFigures + 4; if (nLen < nShapePos) { return OGRERR_NOT_ENOUGH_DATA; } nNumShapes = ReadInt32(nShapePos - 4); if (nLen < nShapePos + 9 * nNumShapes) { return OGRERR_NOT_ENOUGH_DATA; } if ( nNumShapes <= 0 ) { return OGRERR_NONE; } // pick up the root shape if ( ParentOffset(0) != 0xFFFFFFFF) { return OGRERR_CORRUPT_DATA; } // determine the shape type switch (ShapeType(0)) { case ST_POINT: *poGeom = ReadPoint(0); break; case ST_LINESTRING: *poGeom = ReadLineString(0); break; case ST_POLYGON: *poGeom = ReadPolygon(0); break; case ST_MULTIPOINT: *poGeom = ReadMultiPoint(0); break; case ST_MULTILINESTRING: *poGeom = ReadMultiLineString(0); break; case ST_MULTIPOLYGON: *poGeom = ReadMultiPolygon(0); break; case ST_GEOMETRYCOLLECTION: *poGeom = ReadGeometryCollection(0); break; default: return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } } return OGRERR_NONE; }
mapnik::geometry::geometry<double> sqlserver_geometry_parser::parse(unsigned char* pszInput, int nLen) { if (nLen < 10) { throw sqlserver_geometry_parser_exception("not enough data, nLen < 10"); } pszData = pszInput; /* store the SRS id for further use */ nSRSId = ReadInt32(0); if ( ReadByte(4) != 1 ) { throw sqlserver_geometry_parser_exception("corrupt data, ReadByte(4) != 1"); } chProps = ReadByte(5); if ( chProps & SP_HASMVALUES ) nPointSize = 32; else if ( chProps & SP_HASZVALUES ) nPointSize = 24; else nPointSize = 16; mapnik::geometry::geometry<double> geom; if ( chProps & SP_ISSINGLEPOINT ) { // single point geometry nNumPoints = 1; nPointPos = 6; if (nLen < 6 + nPointSize) { throw sqlserver_geometry_parser_exception("not enough data, nLen < 6 + nPointSize"); } mapnik::geometry::point<double> point; if (colType == Geography) { point.x = ReadY(0); point.y = ReadX(0); } else { point.x = ReadX(0); point.y = ReadY(0); } geom = point; } else if ( chProps & SP_ISSINGLELINESEGMENT ) { // single line segment with 2 points nNumPoints = 2; nPointPos = 6; if (nLen < 6 + 2 * nPointSize) { throw sqlserver_geometry_parser_exception("not enough data, nLen < 6 + 2 * nPointSize"); } mapnik::geometry::line_string<double> line; if (colType == Geography) { line.emplace_back(ReadY(0), ReadX(0)); line.emplace_back(ReadY(1), ReadX(1)); } else { line.emplace_back(ReadX(0), ReadY(0)); line.emplace_back(ReadX(1), ReadY(1)); } geom = line; } else { // complex geometries nNumPoints = ReadInt32(6); if ( nNumPoints <= 0 ) { throw sqlserver_geometry_parser_exception("negative number of points, nNumPoints <= 0"); } // position of the point array nPointPos = 10; // position of the figures nFigurePos = nPointPos + nPointSize * nNumPoints + 4; if (nLen < nFigurePos) { throw sqlserver_geometry_parser_exception("not enough data, nLen < nFigurePos"); } nNumFigures = ReadInt32(nFigurePos - 4); if ( nNumFigures <= 0 ) { throw sqlserver_geometry_parser_exception("negative number of figures, nNumFigures <= 0"); } // position of the shapes nShapePos = nFigurePos + 5 * nNumFigures + 4; if (nLen < nShapePos) { throw sqlserver_geometry_parser_exception("not enough data, nLen < nShapePos"); } nNumShapes = ReadInt32(nShapePos - 4); if (nLen < nShapePos + 9 * nNumShapes) { throw sqlserver_geometry_parser_exception("not enough data, nLen < nShapePos + 9 * nNumShapes"); } if ( nNumShapes <= 0 ) { throw sqlserver_geometry_parser_exception("negative number of shapes, nNumShapes <= 0"); } // pick up the root shape if ( ParentOffset(0) != 0xFFFFFFFF) { throw sqlserver_geometry_parser_exception("corrupt data, ParentOffset(0) != 0xFFFFFFFF"); } // determine the shape type switch (ShapeType(0)) { case ST_POINT: geom = ReadPoint(0); break; case ST_LINESTRING: geom = ReadLineString(0); break; case ST_POLYGON: geom = ReadPolygon(0); break; case ST_MULTIPOINT: geom = ReadMultiPoint(0); break; case ST_MULTILINESTRING: geom = ReadMultiLineString(0); break; case ST_MULTIPOLYGON: geom = ReadMultiPolygon(0); break; case ST_GEOMETRYCOLLECTION: geom = ReadGeometryCollection(0); break; default: throw sqlserver_geometry_parser_exception("unsupported geometry type"); } } return geom; }