LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mssqlspatial - ogrmssqlgeometryparser.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 164 0 0.0 %
Date: 2011-12-18 Functions: 10 0 0.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmssqlgeometryparser.cpp 20591 2010-09-12 17:27:42Z tamas $
       3                 :  *
       4                 :  * Project:  MSSQL Spatial driver
       5                 :  * Purpose:  Implements OGRMSSQLGeometryParser class to parse native SqlGeometries.
       6                 :  * Author:   Tamas Szekeres, szekerest at gmail.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2010, Tamas Szekeres
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "cpl_conv.h"
      31                 : #include "ogr_mssqlspatial.h"
      32                 : 
      33                 : CPL_CVSID("$Id: ogrmssqlgeometryparser.cpp 20591 2010-09-12 17:27:42Z tamas $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                         Geometry parser macros                       */
      37                 : /************************************************************************/
      38                 : 
      39                 : #define SP_NONE 0
      40                 : #define SP_HASZVALUES 1
      41                 : #define SP_HASMVALUES 2
      42                 : #define SP_ISVALID 4
      43                 : #define SP_ISSINGLEPOINT 8
      44                 : #define SP_ISSINGLELINESEGMENT 0x10
      45                 : #define SP_ISWHOLEGLOBE 0x20
      46                 : 
      47                 : #define ST_UNKNOWN 0
      48                 : #define ST_POINT 1
      49                 : #define ST_LINESTRING 2
      50                 : #define ST_POLYGON 3
      51                 : #define ST_MULTIPOINT 4
      52                 : #define ST_MULTILINESTRING 5
      53                 : #define ST_MULTIPOLYGON 6
      54                 : #define ST_GEOMETRYCOLLECTION 7
      55                 : 
      56                 : #define ReadInt32(nPos) (*((unsigned int*)(pszData + (nPos))))
      57                 : 
      58                 : #define ReadByte(nPos) (pszData[nPos])
      59                 : 
      60                 : #define ReadDouble(nPos) (*((double*)(pszData + (nPos))))
      61                 : 
      62                 : #define ParentOffset(iShape) (ReadInt32(nShapePos + (iShape) * 9 ))
      63                 : #define FigureOffset(iShape) (ReadInt32(nShapePos + (iShape) * 9 + 4))
      64                 : #define ShapeType(iShape) (ReadByte(nShapePos + (iShape) * 9 + 8))
      65                 : 
      66                 : #define NextFigureOffset(iShape) (iShape + 1 < nNumShapes? FigureOffset((iShape) +1) : nNumFigures)
      67                 : 
      68                 : #define FigureAttribute(iFigure) (ReadByte(nFigurePos + (iFigure) * 5))
      69                 : #define PointOffset(iFigure) (ReadInt32(nFigurePos + (iFigure) * 5 + 1))
      70                 : #define NextPointOffset(iFigure) (iFigure + 1 < nNumFigures? PointOffset((iFigure) +1) : nNumPoints)
      71                 : 
      72                 : #define ReadX(iPoint) (ReadDouble(nPointPos + nPointSize * (iPoint)))
      73                 : #define ReadY(iPoint) (ReadDouble(nPointPos + nPointSize * (iPoint) + 8))
      74                 : #define ReadZ(iPoint) (ReadDouble(nPointPos + nPointSize * (iPoint) + 16))
      75                 : 
      76                 : /************************************************************************/
      77                 : /*                   OGRMSSQLGeometryParser()                           */
      78                 : /************************************************************************/
      79                 : 
      80               0 : OGRMSSQLGeometryParser::OGRMSSQLGeometryParser()
      81                 : {
      82               0 : }
      83                 : 
      84                 : /************************************************************************/
      85                 : /*                         ReadPoint()                                  */
      86                 : /************************************************************************/
      87                 : 
      88               0 : OGRPoint* OGRMSSQLGeometryParser::ReadPoint(int iShape)
      89                 : {
      90               0 :     int iFigure = FigureOffset(iShape);
      91               0 :     if ( iFigure < nNumFigures )
      92                 :     {
      93               0 :         int iPoint = PointOffset(iFigure);
      94               0 :         if ( iPoint < nNumPoints )
      95                 :         {
      96               0 :             if ( chProps & SP_HASZVALUES )
      97               0 :                 return new OGRPoint( ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) );
      98                 :             else
      99               0 :                 return new OGRPoint( ReadX(iPoint), ReadY(iPoint) );
     100                 :         }
     101                 :     }
     102               0 :     return NULL;
     103                 : }
     104                 : 
     105                 : /************************************************************************/
     106                 : /*                         ReadMultiPoint()                             */
     107                 : /************************************************************************/
     108                 : 
     109               0 : OGRMultiPoint* OGRMSSQLGeometryParser::ReadMultiPoint(int iShape)
     110                 : {
     111                 :     int iFigure, iPoint, iNextPoint;
     112               0 :     iFigure = FigureOffset(iShape);
     113                 : 
     114               0 :     OGRMultiPoint* poMultiPoint = new OGRMultiPoint();
     115               0 :     iNextPoint = NextPointOffset(iFigure);
     116               0 :     for (iPoint = PointOffset(iFigure); iPoint < iNextPoint; iPoint++)
     117                 :     {
     118                 :         OGRPoint* poPoint;
     119                 :         
     120               0 :         if ( chProps & SP_HASZVALUES )
     121               0 :             poPoint = new OGRPoint( ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) );
     122                 :         else
     123               0 :             poPoint = new OGRPoint( ReadX(iPoint), ReadY(iPoint) );
     124                 : 
     125               0 :         if ( poPoint )
     126               0 :             poMultiPoint->addGeometryDirectly( poPoint );
     127                 :     }
     128                 : 
     129               0 :     return poMultiPoint;
     130                 : }
     131                 : 
     132                 : /************************************************************************/
     133                 : /*                         ReadLineString()                             */
     134                 : /************************************************************************/
     135                 : 
     136               0 : OGRLineString* OGRMSSQLGeometryParser::ReadLineString(int iShape)
     137                 : {
     138                 :     int iFigure, iPoint, iNextPoint, i;
     139               0 :     iFigure = FigureOffset(iShape);
     140                 : 
     141               0 :     OGRLineString* poLineString = new OGRLineString();
     142               0 :     iPoint = PointOffset(iFigure);
     143               0 :     iNextPoint = NextPointOffset(iFigure);
     144               0 :     poLineString->setNumPoints(iNextPoint - iPoint);
     145               0 :     i = 0;
     146               0 :     while (iPoint < iNextPoint)
     147                 :     {
     148               0 :         if ( chProps & SP_HASZVALUES )
     149               0 :             poLineString->setPoint(i, ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) );
     150                 :         else
     151               0 :             poLineString->setPoint(i, ReadX(iPoint), ReadY(iPoint) );
     152                 :         
     153               0 :         ++iPoint;
     154               0 :         ++i;
     155                 :     }
     156                 : 
     157               0 :     return poLineString;
     158                 : }
     159                 : 
     160                 : /************************************************************************/
     161                 : /*                         ReadMultiLineString()                        */
     162                 : /************************************************************************/
     163                 : 
     164               0 : OGRMultiLineString* OGRMSSQLGeometryParser::ReadMultiLineString(int iShape)
     165                 : {
     166                 :     int i;
     167               0 :     OGRMultiLineString* poMultiLineString = new OGRMultiLineString();
     168                 :     OGRGeometry* poGeom;
     169                 : 
     170               0 :     for (i = iShape + 1; i < nNumShapes; i++)
     171                 :     {
     172               0 :         poGeom = NULL;
     173               0 :         if (ParentOffset(i) == (unsigned int)iShape)
     174                 :         {
     175               0 :             if  ( ShapeType(i) == ST_LINESTRING )
     176               0 :                 poGeom = ReadLineString(i);
     177                 :         }
     178               0 :         if ( poGeom )
     179               0 :             poMultiLineString->addGeometryDirectly( poGeom );
     180                 :     }
     181                 : 
     182               0 :     return poMultiLineString;
     183                 : }
     184                 : 
     185                 : /************************************************************************/
     186                 : /*                         ReadPolygon()                                */
     187                 : /************************************************************************/
     188                 : 
     189               0 : OGRPolygon* OGRMSSQLGeometryParser::ReadPolygon(int iShape)
     190                 : {
     191                 :     int iFigure, iPoint, iNextPoint, i;
     192               0 :     int iNextFigure = NextFigureOffset(iShape);
     193                 :     
     194               0 :     OGRPolygon* poPoly = new OGRPolygon();
     195               0 :     for (iFigure = FigureOffset(iShape); iFigure < iNextFigure; iFigure++)
     196                 :     {
     197               0 :         OGRLinearRing* poRing = new OGRLinearRing();
     198               0 :         iPoint = PointOffset(iFigure);
     199               0 :         iNextPoint = NextPointOffset(iFigure);
     200               0 :         poRing->setNumPoints(iNextPoint - iPoint);
     201               0 :         i = 0;
     202               0 :         while (iPoint < iNextPoint)
     203                 :         {
     204               0 :             if ( chProps & SP_HASZVALUES )
     205               0 :                 poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) );
     206                 :             else
     207               0 :                 poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint) );
     208                 : 
     209               0 :             ++iPoint;
     210               0 :             ++i;
     211                 :         }
     212               0 :         poPoly->addRingDirectly( poRing );
     213                 :     }
     214               0 :     return poPoly;
     215                 : }
     216                 : 
     217                 : /************************************************************************/
     218                 : /*                         ReadMultiPolygon()                           */
     219                 : /************************************************************************/
     220                 : 
     221               0 : OGRMultiPolygon* OGRMSSQLGeometryParser::ReadMultiPolygon(int iShape)
     222                 : {
     223                 :     int i;
     224               0 :     OGRMultiPolygon* poMultiPolygon = new OGRMultiPolygon();
     225                 :     OGRGeometry* poGeom;
     226                 : 
     227               0 :     for (i = iShape + 1; i < nNumShapes; i++)
     228                 :     {
     229               0 :         poGeom = NULL;
     230               0 :         if (ParentOffset(i) == (unsigned int)iShape)
     231                 :         {
     232               0 :             if ( ShapeType(i) == ST_POLYGON )
     233               0 :                 poGeom = ReadPolygon(i);
     234                 :         }
     235               0 :         if ( poGeom )
     236               0 :             poMultiPolygon->addGeometryDirectly( poGeom );
     237                 :     }
     238                 : 
     239               0 :     return poMultiPolygon;
     240                 : }
     241                 : 
     242                 : /************************************************************************/
     243                 : /*                         ReadGeometryCollection()                     */
     244                 : /************************************************************************/
     245                 : 
     246               0 : OGRGeometryCollection* OGRMSSQLGeometryParser::ReadGeometryCollection(int iShape)
     247                 : {
     248                 :     int i;
     249               0 :     OGRGeometryCollection* poGeomColl = new OGRGeometryCollection();
     250                 :     OGRGeometry* poGeom;
     251                 : 
     252               0 :     for (i = iShape + 1; i < nNumShapes; i++)
     253                 :     {
     254               0 :         poGeom = NULL;
     255               0 :         if (ParentOffset(i) == (unsigned int)iShape)
     256                 :         {
     257               0 :             switch (ShapeType(i))
     258                 :             {
     259                 :             case ST_POINT:
     260               0 :                 poGeom = ReadPoint(i);
     261               0 :                 break;
     262                 :             case ST_LINESTRING:
     263               0 :                 poGeom = ReadLineString(i);
     264               0 :                 break;
     265                 :             case ST_POLYGON:
     266               0 :                 poGeom = ReadPolygon(i);
     267               0 :                 break;
     268                 :             case ST_MULTIPOINT:
     269               0 :                 poGeom = ReadMultiPoint(i);
     270               0 :                 break;
     271                 :             case ST_MULTILINESTRING:
     272               0 :                 poGeom = ReadMultiLineString(i);
     273               0 :                 break;
     274                 :             case ST_MULTIPOLYGON:
     275               0 :                 poGeom = ReadMultiPolygon(i);
     276               0 :                 break;
     277                 :             case ST_GEOMETRYCOLLECTION:
     278               0 :                 poGeom = ReadGeometryCollection(i);
     279                 :                 break;
     280                 :             }
     281                 :         }
     282               0 :         if ( poGeom )
     283               0 :             poGeomColl->addGeometryDirectly( poGeom );
     284                 :     }
     285                 : 
     286               0 :     return poGeomColl;
     287                 : }
     288                 : 
     289                 : /************************************************************************/
     290                 : /*                         ParseSqlGeometry()                           */
     291                 : /************************************************************************/
     292                 : 
     293                 : 
     294               0 : OGRErr OGRMSSQLGeometryParser::ParseSqlGeometry(unsigned char* pszInput, 
     295                 :                                 int nLen, OGRGeometry **poGeom)
     296                 : {
     297               0 :     if (nLen < 10)
     298               0 :         return OGRERR_NOT_ENOUGH_DATA;
     299                 : 
     300               0 :     pszData = pszInput;
     301                 :     
     302                 :     /* store the SRS id for further use */
     303               0 :     nSRSId = ReadInt32(0);
     304                 :     
     305               0 :     if ( ReadByte(4) != 1 )
     306                 :     {
     307               0 :         return OGRERR_CORRUPT_DATA;
     308                 :     }
     309                 : 
     310               0 :     chProps = ReadByte(5);
     311                 : 
     312               0 :     if ( chProps & SP_HASMVALUES )
     313               0 :         nPointSize = 32;
     314               0 :     else if ( chProps & SP_HASZVALUES )
     315               0 :         nPointSize = 24;
     316                 :     else
     317               0 :         nPointSize = 16;
     318                 : 
     319               0 :     if ( chProps & SP_ISSINGLEPOINT )
     320                 :     {
     321                 :         // single point geometry
     322               0 :         nPointPos = 6;
     323                 : 
     324               0 :         if (nLen < 6 + nPointSize)
     325                 :         {
     326               0 :             return OGRERR_NOT_ENOUGH_DATA;
     327                 :         }
     328                 : 
     329               0 :         if (chProps & SP_HASZVALUES)
     330               0 :             *poGeom = new OGRPoint(ReadX(0), ReadY(0), ReadZ(0));
     331                 :         else
     332               0 :             *poGeom = new OGRPoint(ReadX(0), ReadY(0));
     333                 :     }
     334               0 :     else if ( chProps & SP_ISSINGLELINESEGMENT )
     335                 :     {
     336                 :         // single line segment with 2 points
     337               0 :         nPointPos = 6;
     338                 : 
     339               0 :         if (nLen < 6 + 2 * nPointSize)
     340                 :         {
     341               0 :             return OGRERR_NOT_ENOUGH_DATA;
     342                 :         }
     343                 : 
     344               0 :         OGRLineString* line = new OGRLineString();
     345               0 :         line->setNumPoints(2);
     346                 :         
     347               0 :         if ( chProps & SP_HASZVALUES )
     348                 :         {
     349               0 :             line->setPoint(0, ReadX(0), ReadY(0), ReadZ(0));
     350               0 :             line->setPoint(1, ReadX(1), ReadY(1), ReadZ(1));
     351                 :         }
     352                 :         else
     353                 :         {
     354               0 :             line->setPoint(0, ReadX(0), ReadY(0));
     355               0 :             line->setPoint(1, ReadX(1), ReadY(1));
     356                 :         }
     357                 :         
     358               0 :         *poGeom = line;
     359                 :     }
     360                 :     else
     361                 :     {
     362                 :         // complex geometries
     363               0 :         nNumPoints = ReadInt32(6);
     364                 : 
     365               0 :         if ( nNumPoints <= 0 )
     366                 :         {
     367               0 :             return OGRERR_NONE;
     368                 :         }
     369                 : 
     370                 :         // position of the point array
     371               0 :         nPointPos = 10;
     372                 : 
     373                 :         // position of the figures
     374               0 :         nFigurePos = nPointPos + nPointSize * nNumPoints + 4;
     375                 :         
     376               0 :         if (nLen < nFigurePos)
     377                 :         {
     378               0 :             return OGRERR_NOT_ENOUGH_DATA;
     379                 :         }
     380                 : 
     381               0 :         nNumFigures = ReadInt32(nFigurePos - 4);
     382                 : 
     383               0 :         if ( nNumFigures <= 0 )
     384                 :         {
     385               0 :             return OGRERR_NONE;
     386                 :         }
     387                 :         
     388                 :         // position of the shapes
     389               0 :         nShapePos = nFigurePos + 5 * nNumFigures + 4;
     390                 : 
     391               0 :         if (nLen < nShapePos)
     392                 :         {
     393               0 :             return OGRERR_NOT_ENOUGH_DATA;
     394                 :         }
     395                 : 
     396               0 :         nNumShapes = ReadInt32(nShapePos - 4);
     397                 : 
     398               0 :         if (nLen < nShapePos + 9 * nNumShapes)
     399                 :         {
     400               0 :             return OGRERR_NOT_ENOUGH_DATA;
     401                 :         }
     402                 : 
     403               0 :         if ( nNumShapes <= 0 )
     404                 :         {
     405               0 :             return OGRERR_NONE;
     406                 :         }
     407                 : 
     408                 :         // pick up the root shape
     409               0 :         if ( ParentOffset(0) != 0xFFFFFFFF)
     410                 :         {
     411               0 :             return OGRERR_CORRUPT_DATA;
     412                 :         }
     413                 : 
     414                 :         // determine the shape type
     415               0 :         switch (ShapeType(0))
     416                 :         {
     417                 :         case ST_POINT:
     418               0 :             *poGeom = ReadPoint(0);
     419               0 :             break;
     420                 :         case ST_LINESTRING:
     421               0 :             *poGeom = ReadLineString(0);
     422               0 :             break;
     423                 :         case ST_POLYGON:
     424               0 :             *poGeom = ReadPolygon(0);
     425               0 :             break;
     426                 :         case ST_MULTIPOINT:
     427               0 :             *poGeom = ReadMultiPoint(0);
     428               0 :             break;
     429                 :         case ST_MULTILINESTRING:
     430               0 :             *poGeom = ReadMultiLineString(0);
     431               0 :             break;
     432                 :         case ST_MULTIPOLYGON:
     433               0 :             *poGeom = ReadMultiPolygon(0);
     434               0 :             break;
     435                 :         case ST_GEOMETRYCOLLECTION:
     436               0 :             *poGeom = ReadGeometryCollection(0);
     437               0 :             break;
     438                 :         default:
     439               0 :             return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
     440                 :         }
     441                 :     }
     442                 : 
     443               0 :     return OGRERR_NONE;
     444                 : }
     445                 : 

Generated by: LCOV version 1.7