OGRLineString* OGRMSSQLGeometryParser::ReadLineString(int iShape) { int iFigure, iPoint, iNextPoint, i; iFigure = FigureOffset(iShape); OGRLineString* poLineString = new OGRLineString(); iPoint = PointOffset(iFigure); iNextPoint = NextPointOffset(iFigure); poLineString->setNumPoints(iNextPoint - iPoint); i = 0; while (iPoint < iNextPoint) { if (nColType == MSSQLCOLTYPE_GEOGRAPHY) { if ( chProps & SP_HASZVALUES ) poLineString->setPoint(i, ReadY(iPoint), ReadX(iPoint), ReadZ(iPoint) ); else poLineString->setPoint(i, ReadY(iPoint), ReadX(iPoint) ); } else { if ( chProps & SP_HASZVALUES ) poLineString->setPoint(i, ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) ); else poLineString->setPoint(i, ReadX(iPoint), ReadY(iPoint) ); } ++iPoint; ++i; } return poLineString; }
OGRPolygon* OGRMSSQLGeometryParser::ReadPolygon(int iShape) { int iFigure, iPoint, iNextPoint, i; int iNextFigure = NextFigureOffset(iShape); OGRPolygon* poPoly = new OGRPolygon(); for (iFigure = FigureOffset(iShape); iFigure < iNextFigure; iFigure++) { OGRLinearRing* poRing = new OGRLinearRing(); iPoint = PointOffset(iFigure); iNextPoint = NextPointOffset(iFigure); poRing->setNumPoints(iNextPoint - iPoint); i = 0; while (iPoint < iNextPoint) { if ( chProps & SP_HASZVALUES ) poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) ); else poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint) ); ++iPoint; ++i; } poPoly->addRingDirectly( poRing ); } return poPoly; }
OGRPoint* OGRMSSQLGeometryParser::ReadPoint(int iShape) { int iFigure = FigureOffset(iShape); if ( iFigure < nNumFigures ) { int iPoint = PointOffset(iFigure); if ( iPoint < nNumPoints ) { if (nColType == MSSQLCOLTYPE_GEOGRAPHY) { if ( chProps & SP_HASZVALUES ) return new OGRPoint( ReadY(iPoint), ReadX(iPoint), ReadZ(iPoint) ); else return new OGRPoint( ReadY(iPoint), ReadX(iPoint) ); } else { if ( chProps & SP_HASZVALUES ) return new OGRPoint( ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) ); else return new OGRPoint( ReadX(iPoint), ReadY(iPoint) ); } } } return NULL; }
mapnik::geometry::polygon<double> sqlserver_geometry_parser::ReadPolygon(int iShape) { mapnik::geometry::polygon<double> geom; int iNextFigure = NextFigureOffset(iShape); for (int iFigure = FigureOffset(iShape); iFigure < iNextFigure; iFigure++) { mapnik::geometry::linear_ring<double> ring; int iPoint = PointOffset(iFigure); int iNextPoint = NextPointOffset(iFigure); while (iPoint < iNextPoint) { if (colType == Geography) { ring.emplace_back(ReadY(iPoint), ReadX(iPoint)); } else { ring.emplace_back(ReadX(iPoint), ReadY(iPoint)); } ++iPoint; } if (iFigure == 0) { geom.set_exterior_ring(std::move(ring)); } else { geom.add_hole(std::move(ring)); } } return geom; }
// Get a single valid sample u8 TouchSample(int* xx, int* yy) { int z1,z2,x; ReadZ(&z1,&z2); // left edge // z2 = 0, z1 = 1 // As pressure increases z2->z1 (1-z2/z1)*x // (z1-z2)*x/z1 measures resistance if (z2 < 8) return 0; // not touching x = ReadX(); int t = (long)z2*x/z1; t += abs(512-x)>>3; // horrible hack to make it slightly more linear across x t -= 84; if (t <= 0) return 0; t += t; *yy = ReadY(); *xx = x; if (t > 255) t = 255; return t; // Range to 0..255 }
mapnik::geometry::point<double> sqlserver_geometry_parser::ReadPoint(int iShape) { mapnik::geometry::point<double> geom; int iFigure = FigureOffset(iShape); if ( iFigure < nNumFigures ) { int iPoint = PointOffset(iFigure); if ( iPoint < nNumPoints ) { if (colType == Geography) { geom.x = ReadY(iPoint); geom.y = ReadX(iPoint); } else { geom.x = ReadX(iPoint); geom.y = ReadY(iPoint); } } } return geom; }
mapnik::geometry::line_string<double> sqlserver_geometry_parser::ReadLineString(int iShape) { mapnik::geometry::line_string<double> geom; int iFigure = FigureOffset(iShape); int iPoint = PointOffset(iFigure); int iNextPoint = NextPointOffset(iFigure); while (iPoint < iNextPoint) { if (colType == Geography) { geom.emplace_back(ReadY(iPoint), ReadX(iPoint)); } else { geom.emplace_back(ReadX(iPoint), ReadY(iPoint)); } ++iPoint; } return geom; }
OGRMultiPoint* OGRMSSQLGeometryParser::ReadMultiPoint(int iShape) { int iFigure, iPoint, iNextPoint; iFigure = FigureOffset(iShape); OGRMultiPoint* poMultiPoint = new OGRMultiPoint(); iNextPoint = NextPointOffset(iFigure); for (iPoint = PointOffset(iFigure); iPoint < iNextPoint; iPoint++) { OGRPoint* poPoint; if ( chProps & SP_HASZVALUES ) poPoint = new OGRPoint( ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) ); else poPoint = new OGRPoint( ReadX(iPoint), ReadY(iPoint) ); if ( poPoint ) poMultiPoint->addGeometryDirectly( poPoint ); } return poMultiPoint; }
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; }
void TestTouch(int* s) { s[0] = ReadX(); s[1] = ReadY(); ReadZ(&s[2],&s[3]); }
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; }