LCOV - code coverage report
Current view: directory - ogr - ogrgeomediageometry.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 191 0 0.0 %
Date: 2012-12-26 Functions: 2 0 0.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgeomediageometry.cpp 24656 2012-07-03 17:35:34Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements decoder of geomedia geometry blobs
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault, <even dot rouault at mines dash paris dot org>
      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 "ogrgeomediageometry.h"
      31                 : #include "cpl_string.h"
      32                 : 
      33                 : CPL_CVSID("$Id: ogrgeomediageometry.cpp 24656 2012-07-03 17:35:34Z rouault $");
      34                 : 
      35                 : #define GEOMEDIA_POINT          0xC0
      36                 : #define GEOMEDIA_ORIENTED_POINT 0xC8
      37                 : #define GEOMEDIA_POLYLINE       0xC2
      38                 : #define GEOMEDIA_POLYGON        0xC3
      39                 : #define GEOMEDIA_BOUNDARY       0xC5
      40                 : #define GEOMEDIA_COLLECTION     0xC6
      41                 : #define GEOMEDIA_MULTILINE      0xCB
      42                 : #define GEOMEDIA_MULTIPOLYGON   0xCC
      43                 : 
      44                 : /************************************************************************/
      45                 : /*                       OGRCreateFromGeomedia()                        */
      46                 : /************************************************************************/
      47                 : 
      48               0 : OGRErr OGRCreateFromGeomedia( GByte *pabyGeom,
      49                 :                               OGRGeometry **ppoGeom,
      50                 :                               int nBytes )
      51                 : 
      52                 : {
      53               0 :     *ppoGeom = NULL;
      54                 : 
      55               0 :     if( nBytes < 16 )
      56               0 :         return OGRERR_FAILURE;
      57                 : 
      58               0 :     if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) )
      59               0 :         return OGRERR_FAILURE;
      60                 : 
      61               0 :     int nGeomType = pabyGeom[0];
      62               0 :     pabyGeom += 16;
      63               0 :     nBytes -= 16;
      64                 : 
      65               0 :     if( nGeomType == GEOMEDIA_POINT ||
      66                 :         nGeomType == GEOMEDIA_ORIENTED_POINT )
      67                 :     {
      68               0 :         if (nBytes < 3 * 8)
      69               0 :             return OGRERR_FAILURE;
      70                 : 
      71                 :         double dfX, dfY, dfZ;
      72               0 :         memcpy(&dfX, pabyGeom, 8);
      73                 :         CPL_LSBPTR64(&dfX);
      74               0 :         memcpy(&dfY, pabyGeom + 8, 8);
      75                 :         CPL_LSBPTR64(&dfY);
      76               0 :         memcpy(&dfZ, pabyGeom + 16, 8);
      77                 :         CPL_LSBPTR64(&dfZ);
      78                 : 
      79               0 :         *ppoGeom = new OGRPoint( dfX, dfY, dfZ );
      80                 : 
      81               0 :          return OGRERR_NONE;
      82                 :     }
      83               0 :     else if ( nGeomType == GEOMEDIA_POLYLINE )
      84                 :     {
      85               0 :         if (nBytes < 4)
      86               0 :             return OGRERR_FAILURE;
      87                 : 
      88                 :         int nPoints;
      89               0 :         memcpy(&nPoints, pabyGeom, 4);
      90                 :         CPL_LSBPTR32(&nPoints);
      91                 : 
      92               0 :         pabyGeom += 4;
      93               0 :         nBytes -= 4;
      94                 : 
      95               0 :         if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24)
      96               0 :             return OGRERR_FAILURE;
      97                 : 
      98               0 :         OGRLineString* poLS = new OGRLineString();
      99               0 :         poLS->setNumPoints(nPoints);
     100                 :         int i;
     101               0 :         for(i=0;i<nPoints;i++)
     102                 :         {
     103                 :             double dfX, dfY, dfZ;
     104               0 :             memcpy(&dfX, pabyGeom, 8);
     105                 :             CPL_LSBPTR64(&dfX);
     106               0 :             memcpy(&dfY, pabyGeom + 8, 8);
     107                 :             CPL_LSBPTR64(&dfY);
     108               0 :             memcpy(&dfZ, pabyGeom + 16, 8);
     109                 :             CPL_LSBPTR64(&dfZ);
     110                 : 
     111               0 :             poLS->setPoint(i, dfX, dfY, dfZ);
     112                 : 
     113               0 :             pabyGeom += 24;
     114                 :         }
     115                 : 
     116               0 :         *ppoGeom = poLS;
     117                 : 
     118               0 :         return OGRERR_NONE;
     119                 :     }
     120               0 :     else if ( nGeomType == GEOMEDIA_POLYGON )
     121                 :     {
     122               0 :         if (nBytes < 4)
     123               0 :             return OGRERR_FAILURE;
     124                 : 
     125                 :         int nPoints;
     126               0 :         memcpy(&nPoints, pabyGeom, 4);
     127                 :         CPL_LSBPTR32(&nPoints);
     128                 : 
     129               0 :         pabyGeom += 4;
     130               0 :         nBytes -= 4;
     131                 : 
     132               0 :         if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24)
     133               0 :             return OGRERR_FAILURE;
     134                 : 
     135               0 :         OGRLinearRing* poRing = new OGRLinearRing();
     136               0 :         poRing->setNumPoints(nPoints);
     137                 :         int i;
     138               0 :         for(i=0;i<nPoints;i++)
     139                 :         {
     140                 :             double dfX, dfY, dfZ;
     141               0 :             memcpy(&dfX, pabyGeom, 8);
     142                 :             CPL_LSBPTR64(&dfX);
     143               0 :             memcpy(&dfY, pabyGeom + 8, 8);
     144                 :             CPL_LSBPTR64(&dfY);
     145               0 :             memcpy(&dfZ, pabyGeom + 16, 8);
     146                 :             CPL_LSBPTR64(&dfZ);
     147                 : 
     148               0 :             poRing->setPoint(i, dfX, dfY, dfZ);
     149                 : 
     150               0 :             pabyGeom += 24;
     151                 :         }
     152                 : 
     153               0 :         OGRPolygon* poPoly = new OGRPolygon();
     154               0 :         poPoly->addRingDirectly(poRing);
     155               0 :         *ppoGeom = poPoly;
     156                 : 
     157               0 :         return OGRERR_NONE;
     158                 :     }
     159               0 :     else if ( nGeomType == GEOMEDIA_BOUNDARY )
     160                 :     {
     161               0 :         if (nBytes < 4)
     162               0 :             return OGRERR_FAILURE;
     163                 : 
     164                 :         int nExteriorSize;
     165               0 :         memcpy(&nExteriorSize, pabyGeom, 4);
     166                 :         CPL_LSBPTR32(&nExteriorSize);
     167                 : 
     168               0 :         pabyGeom += 4;
     169               0 :         nBytes -= 4;
     170                 : 
     171               0 :         if (nBytes < nExteriorSize)
     172               0 :             return OGRERR_FAILURE;
     173                 : 
     174               0 :         OGRGeometry* poExteriorGeom = NULL;
     175               0 :         if (OGRCreateFromGeomedia( pabyGeom, &poExteriorGeom, nExteriorSize ) != OGRERR_NONE)
     176               0 :             return OGRERR_FAILURE;
     177                 : 
     178               0 :         if ( wkbFlatten( poExteriorGeom->getGeometryType() ) != wkbPolygon )
     179                 :         {
     180               0 :             delete poExteriorGeom;
     181               0 :             return OGRERR_FAILURE;
     182                 :         }
     183                 : 
     184               0 :         pabyGeom += nExteriorSize;
     185               0 :         nBytes -= nExteriorSize;
     186                 : 
     187               0 :         if (nBytes < 4)
     188                 :         {
     189               0 :             delete poExteriorGeom;
     190               0 :             return OGRERR_FAILURE;
     191                 :         }
     192                 : 
     193                 :         int nInteriorSize;
     194               0 :         memcpy(&nInteriorSize, pabyGeom, 4);
     195                 :         CPL_LSBPTR32(&nInteriorSize);
     196                 : 
     197               0 :         pabyGeom += 4;
     198               0 :         nBytes -= 4;
     199                 : 
     200               0 :         if (nBytes < nInteriorSize)
     201                 :         {
     202               0 :             delete poExteriorGeom;
     203               0 :             return OGRERR_FAILURE;
     204                 :         }
     205                 : 
     206               0 :         OGRGeometry* poInteriorGeom = NULL;
     207               0 :         if (OGRCreateFromGeomedia( pabyGeom, &poInteriorGeom, nInteriorSize ) != OGRERR_NONE)
     208                 :         {
     209               0 :             delete poExteriorGeom;
     210               0 :             return OGRERR_FAILURE;
     211                 :         }
     212                 : 
     213               0 :         OGRwkbGeometryType interiorGeomType = wkbFlatten( poInteriorGeom->getGeometryType() );
     214               0 :         if ( interiorGeomType == wkbPolygon )
     215                 :         {
     216               0 :             ((OGRPolygon*)poExteriorGeom)->addRing(((OGRPolygon*)poInteriorGeom)->getExteriorRing());
     217                 :         }
     218               0 :         else if ( interiorGeomType == wkbMultiPolygon )
     219                 :         {
     220               0 :             int numGeom = ((OGRMultiPolygon*)poInteriorGeom)->getNumGeometries();
     221               0 :             for ( int i = 0; i < numGeom; ++i )
     222                 :             {
     223                 :                 OGRPolygon* poInteriorPolygon = 
     224               0 :                     (OGRPolygon*)((OGRMultiPolygon*)poInteriorGeom)->getGeometryRef(i);
     225               0 :                 ((OGRPolygon*)poExteriorGeom)->addRing( poInteriorPolygon->getExteriorRing() );
     226                 :             }
     227                 :         }
     228                 :         else
     229                 :         {
     230               0 :             delete poExteriorGeom;
     231               0 :             delete poInteriorGeom;
     232               0 :             return OGRERR_FAILURE;
     233                 :         }
     234                 : 
     235               0 :         delete poInteriorGeom;
     236               0 :         *ppoGeom = poExteriorGeom;
     237                 : 
     238               0 :         return OGRERR_NONE;
     239                 :     }
     240               0 :     else if ( nGeomType == GEOMEDIA_COLLECTION ||
     241                 :               nGeomType == GEOMEDIA_MULTILINE ||
     242                 :               nGeomType == GEOMEDIA_MULTIPOLYGON )
     243                 :     {
     244               0 :         if (nBytes < 4)
     245               0 :             return OGRERR_FAILURE;
     246                 : 
     247                 :         int i;
     248                 :         int nParts;
     249               0 :         memcpy(&nParts, pabyGeom, 4);
     250                 :         CPL_LSBPTR32(&nParts);
     251                 : 
     252               0 :         pabyGeom += 4;
     253               0 :         nBytes -= 4;
     254                 : 
     255               0 :         if (nParts < 0 || nParts > INT_MAX / (4 + 16) || nBytes < nParts * (4 + 16))
     256               0 :             return OGRERR_FAILURE;
     257                 : 
     258                 :         /* Can this collection be considered as a multipolyline or multipolygon ? */
     259               0 :         if ( nGeomType == GEOMEDIA_COLLECTION )
     260                 :         {
     261               0 :             GByte* pabyGeomBackup = pabyGeom;
     262               0 :             int nBytesBackup = nBytes;
     263                 : 
     264               0 :             int bAllPolyline = TRUE;
     265               0 :             int bAllPolygon = TRUE;
     266                 : 
     267               0 :             for(i=0;i<nParts;i++)
     268                 :             {
     269               0 :                 if (nBytes < 4)
     270               0 :                     return OGRERR_FAILURE;
     271                 :                 int nSubBytes;
     272               0 :                 memcpy(&nSubBytes, pabyGeom, 4);
     273                 :                 CPL_LSBPTR32(&nSubBytes);
     274                 : 
     275               0 :                 if (nSubBytes < 0)
     276                 :                 {
     277               0 :                     return OGRERR_FAILURE;
     278                 :                 }
     279                 : 
     280               0 :                 pabyGeom += 4;
     281               0 :                 nBytes -= 4;
     282                 : 
     283               0 :                 if (nBytes < nSubBytes)
     284                 :                 {
     285               0 :                     return OGRERR_FAILURE;
     286                 :                 }
     287                 : 
     288               0 :                 if( nSubBytes < 16 )
     289               0 :                     return OGRERR_FAILURE;
     290                 : 
     291               0 :                 if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) )
     292               0 :                     return OGRERR_FAILURE;
     293                 : 
     294               0 :                 int nSubGeomType = pabyGeom[0];
     295               0 :                 if ( nSubGeomType != GEOMEDIA_POLYLINE )
     296               0 :                     bAllPolyline = FALSE;
     297               0 :                 if ( nSubGeomType != GEOMEDIA_POLYGON )
     298               0 :                     bAllPolygon = FALSE;
     299                 : 
     300               0 :                 pabyGeom += nSubBytes;
     301               0 :                 nBytes -= nSubBytes;
     302                 :             }
     303                 : 
     304               0 :             pabyGeom = pabyGeomBackup;
     305               0 :             nBytes = nBytesBackup;
     306                 : 
     307               0 :             if (bAllPolyline)
     308               0 :                 nGeomType = GEOMEDIA_MULTILINE;
     309               0 :             else if (bAllPolygon)
     310               0 :                 nGeomType = GEOMEDIA_MULTIPOLYGON;
     311                 :         }
     312                 : 
     313                 :         OGRGeometryCollection* poColl = (nGeomType == GEOMEDIA_MULTILINE) ? new OGRMultiLineString() :
     314                 :                                         (nGeomType == GEOMEDIA_MULTIPOLYGON) ? new OGRMultiPolygon() :
     315               0 :                                                               new OGRGeometryCollection();
     316                 : 
     317               0 :         for(i=0;i<nParts;i++)
     318                 :         {
     319               0 :             if (nBytes < 4)
     320               0 :                 return OGRERR_FAILURE;
     321                 :             int nSubBytes;
     322               0 :             memcpy(&nSubBytes, pabyGeom, 4);
     323                 :             CPL_LSBPTR32(&nSubBytes);
     324                 : 
     325               0 :             if (nSubBytes < 0)
     326                 :             {
     327               0 :                 delete poColl;
     328               0 :                 return OGRERR_FAILURE;
     329                 :             }
     330                 : 
     331               0 :             pabyGeom += 4;
     332               0 :             nBytes -= 4;
     333                 : 
     334               0 :             if (nBytes < nSubBytes)
     335                 :             {
     336               0 :                 delete poColl;
     337               0 :                 return OGRERR_FAILURE;
     338                 :             }
     339                 : 
     340               0 :             OGRGeometry* poSubGeom = NULL;
     341               0 :             if (OGRCreateFromGeomedia( pabyGeom, &poSubGeom, nSubBytes ) == OGRERR_NONE)
     342                 :             {
     343               0 :                 if (wkbFlatten(poColl->getGeometryType()) == wkbMultiPolygon &&
     344               0 :                     wkbFlatten(poSubGeom->getGeometryType()) == wkbLineString)
     345                 :                 {
     346               0 :                     OGRPolygon* poPoly = new OGRPolygon();
     347               0 :                     OGRLinearRing* poRing = new OGRLinearRing();
     348               0 :                     poRing->addSubLineString((OGRLineString*)poSubGeom);
     349               0 :                     poPoly->addRingDirectly(poRing);
     350               0 :                     delete poSubGeom;
     351               0 :                     poSubGeom = poPoly;
     352                 :                 }
     353                 : 
     354               0 :                 if (poColl->addGeometryDirectly(poSubGeom) != OGRERR_NONE)
     355                 :                 {
     356                 :                     //printf("%d %d\n", poColl->getGeometryType() & ~wkb25DBit, poSubGeom->getGeometryType() & ~wkb25DBit);
     357               0 :                     delete poSubGeom;
     358                 :                 }
     359                 :             }
     360                 : 
     361               0 :             pabyGeom += nSubBytes;
     362               0 :             nBytes -= nSubBytes;
     363                 :         }
     364                 : 
     365               0 :         *ppoGeom = poColl;
     366                 : 
     367               0 :         return OGRERR_NONE;
     368                 :     }
     369                 :     else
     370                 :     {
     371               0 :         CPLDebug("GEOMEDIA", "Unhandled type %d", nGeomType);
     372                 :     }
     373                 : 
     374               0 :     return OGRERR_FAILURE;
     375                 : }
     376                 : 
     377                 : 
     378                 : /************************************************************************/
     379                 : /*                         OGRGetGeomediaSRS()                          */
     380                 : /************************************************************************/
     381                 : 
     382               0 : OGRSpatialReference* OGRGetGeomediaSRS(OGRFeature* poFeature)
     383                 : {
     384               0 :     if (poFeature == NULL)
     385               0 :         return NULL;
     386                 : 
     387               0 :     int nGeodeticDatum = poFeature->GetFieldAsInteger("GeodeticDatum");
     388               0 :     int nEllipsoid = poFeature->GetFieldAsInteger("Ellipsoid");
     389               0 :     int nProjAlgorithm = poFeature->GetFieldAsInteger("ProjAlgorithm");
     390                 : 
     391               0 :     if (nGeodeticDatum == 17 && nEllipsoid == 22)
     392                 :     {
     393               0 :         if (nProjAlgorithm == 12)
     394                 :         {
     395               0 :             OGRSpatialReference* poSRS = new OGRSpatialReference();
     396                 : 
     397               0 :             const char* pszDescription = poFeature->GetFieldAsString("Description");
     398               0 :             if (pszDescription && pszDescription[0] != 0)
     399               0 :                 poSRS->SetNode( "PROJCS", pszDescription );
     400               0 :             poSRS->SetWellKnownGeogCS("WGS84");
     401                 : 
     402               0 :             double dfStdP1 = poFeature->GetFieldAsDouble("StandPar1");
     403               0 :             double dfStdP2 = poFeature->GetFieldAsDouble("StandPar2");
     404               0 :             double dfCenterLat = poFeature->GetFieldAsDouble("LatOfOrigin");
     405               0 :             double dfCenterLong = poFeature->GetFieldAsDouble("LonOfOrigin");
     406               0 :             double dfFalseEasting = poFeature->GetFieldAsDouble("FalseX");
     407               0 :             double dfFalseNorthing = poFeature->GetFieldAsDouble("FalseY");
     408                 :             poSRS->SetACEA( dfStdP1, dfStdP2,
     409                 :                             dfCenterLat, dfCenterLong,
     410               0 :                             dfFalseEasting, dfFalseNorthing );
     411               0 :             return poSRS;
     412                 :         }
     413                 :     }
     414                 : 
     415               0 :     return NULL;
     416                 : }

Generated by: LCOV version 1.7