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

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgeomediageometry.cpp 21561 2011-01-23 12:22:58Z 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 21561 2011-01-23 12:22:58Z 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 (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 :         if (poInteriorGeom->getGeometryType() == wkbPolygon)
     214                 :         {
     215               0 :             ((OGRPolygon*)poExteriorGeom)->addRing(((OGRPolygon*)poInteriorGeom)->getExteriorRing());
     216               0 :             delete poInteriorGeom;
     217               0 :             *ppoGeom = poExteriorGeom;
     218                 :         }
     219                 :         else
     220                 :         {
     221               0 :             delete poExteriorGeom;
     222               0 :             delete poInteriorGeom;
     223               0 :             return OGRERR_FAILURE;
     224                 :         }
     225                 : 
     226               0 :         return OGRERR_NONE;
     227                 :     }
     228               0 :     else if ( nGeomType == GEOMEDIA_COLLECTION ||
     229                 :               nGeomType == GEOMEDIA_MULTILINE ||
     230                 :               nGeomType == GEOMEDIA_MULTIPOLYGON )
     231                 :     {
     232               0 :         if (nBytes < 4)
     233               0 :             return OGRERR_FAILURE;
     234                 : 
     235                 :         int i;
     236                 :         int nParts;
     237               0 :         memcpy(&nParts, pabyGeom, 4);
     238                 :         CPL_LSBPTR32(&nParts);
     239                 : 
     240               0 :         pabyGeom += 4;
     241               0 :         nBytes -= 4;
     242                 : 
     243               0 :         if (nParts < 0 || nParts > INT_MAX / (4 + 16) || nBytes < nParts * (4 + 16))
     244               0 :             return OGRERR_FAILURE;
     245                 : 
     246                 :         /* Can this collection be considered as a multipolyline or multipolygon ? */
     247               0 :         if ( nGeomType == GEOMEDIA_COLLECTION )
     248                 :         {
     249               0 :             GByte* pabyGeomBackup = pabyGeom;
     250               0 :             int nBytesBackup = nBytes;
     251                 : 
     252               0 :             int bAllPolyline = TRUE;
     253               0 :             int bAllPolygon = TRUE;
     254                 : 
     255               0 :             for(i=0;i<nParts;i++)
     256                 :             {
     257               0 :                 if (nBytes < 4)
     258               0 :                     return OGRERR_FAILURE;
     259                 :                 int nSubBytes;
     260               0 :                 memcpy(&nSubBytes, pabyGeom, 4);
     261                 :                 CPL_LSBPTR32(&nSubBytes);
     262                 : 
     263               0 :                 if (nSubBytes < 0)
     264                 :                 {
     265               0 :                     return OGRERR_FAILURE;
     266                 :                 }
     267                 : 
     268               0 :                 pabyGeom += 4;
     269               0 :                 nBytes -= 4;
     270                 : 
     271               0 :                 if (nBytes < nSubBytes)
     272                 :                 {
     273               0 :                     return OGRERR_FAILURE;
     274                 :                 }
     275                 : 
     276               0 :                 if( nSubBytes < 16 )
     277               0 :                     return OGRERR_FAILURE;
     278                 : 
     279               0 :                 if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) )
     280               0 :                     return OGRERR_FAILURE;
     281                 : 
     282               0 :                 int nSubGeomType = pabyGeom[0];
     283               0 :                 if ( nSubGeomType != GEOMEDIA_POLYLINE )
     284               0 :                     bAllPolyline = FALSE;
     285               0 :                 if ( nSubGeomType != GEOMEDIA_POLYGON )
     286               0 :                     bAllPolygon = FALSE;
     287                 : 
     288               0 :                 pabyGeom += nSubBytes;
     289               0 :                 nBytes -= nSubBytes;
     290                 :             }
     291                 : 
     292               0 :             pabyGeom = pabyGeomBackup;
     293               0 :             nBytes = nBytesBackup;
     294                 : 
     295               0 :             if (bAllPolyline)
     296               0 :                 nGeomType = GEOMEDIA_MULTILINE;
     297               0 :             else if (bAllPolygon)
     298               0 :                 nGeomType = GEOMEDIA_MULTIPOLYGON;
     299                 :         }
     300                 : 
     301                 :         OGRGeometryCollection* poColl = (nGeomType == GEOMEDIA_MULTILINE) ? new OGRMultiLineString() :
     302                 :                                         (nGeomType == GEOMEDIA_MULTIPOLYGON) ? new OGRMultiPolygon() :
     303               0 :                                                               new OGRGeometryCollection();
     304                 : 
     305               0 :         for(i=0;i<nParts;i++)
     306                 :         {
     307               0 :             if (nBytes < 4)
     308               0 :                 return OGRERR_FAILURE;
     309                 :             int nSubBytes;
     310               0 :             memcpy(&nSubBytes, pabyGeom, 4);
     311                 :             CPL_LSBPTR32(&nSubBytes);
     312                 : 
     313               0 :             if (nSubBytes < 0)
     314                 :             {
     315               0 :                 delete poColl;
     316               0 :                 return OGRERR_FAILURE;
     317                 :             }
     318                 : 
     319               0 :             pabyGeom += 4;
     320               0 :             nBytes -= 4;
     321                 : 
     322               0 :             if (nBytes < nSubBytes)
     323                 :             {
     324               0 :                 delete poColl;
     325               0 :                 return OGRERR_FAILURE;
     326                 :             }
     327                 : 
     328               0 :             OGRGeometry* poSubGeom = NULL;
     329               0 :             if (OGRCreateFromGeomedia( pabyGeom, &poSubGeom, nSubBytes ) == OGRERR_NONE)
     330                 :             {
     331               0 :                 if (wkbFlatten(poColl->getGeometryType()) == wkbMultiPolygon &&
     332               0 :                     wkbFlatten(poSubGeom->getGeometryType()) == wkbLineString)
     333                 :                 {
     334               0 :                     OGRPolygon* poPoly = new OGRPolygon();
     335               0 :                     OGRLinearRing* poRing = new OGRLinearRing();
     336               0 :                     poRing->addSubLineString((OGRLineString*)poSubGeom);
     337               0 :                     poPoly->addRingDirectly(poRing);
     338               0 :                     delete poSubGeom;
     339               0 :                     poSubGeom = poPoly;
     340                 :                 }
     341                 : 
     342               0 :                 if (poColl->addGeometryDirectly(poSubGeom) != OGRERR_NONE)
     343                 :                 {
     344                 :                     //printf("%d %d\n", poColl->getGeometryType() & ~wkb25DBit, poSubGeom->getGeometryType() & ~wkb25DBit);
     345               0 :                     delete poSubGeom;
     346                 :                 }
     347                 :             }
     348                 : 
     349               0 :             pabyGeom += nSubBytes;
     350               0 :             nBytes -= nSubBytes;
     351                 :         }
     352                 : 
     353               0 :         *ppoGeom = poColl;
     354                 : 
     355               0 :         return OGRERR_NONE;
     356                 :     }
     357                 :     else
     358                 :     {
     359               0 :         CPLDebug("GEOMEDIA", "Unhandled type %d", nGeomType);
     360                 :     }
     361                 : 
     362               0 :     return OGRERR_FAILURE;
     363                 : }
     364                 : 
     365                 : 
     366                 : /************************************************************************/
     367                 : /*                         OGRGetGeomediaSRS()                          */
     368                 : /************************************************************************/
     369                 : 
     370               0 : OGRSpatialReference* OGRGetGeomediaSRS(OGRFeature* poFeature)
     371                 : {
     372               0 :     if (poFeature == NULL)
     373               0 :         return NULL;
     374                 : 
     375               0 :     int nGeodeticDatum = poFeature->GetFieldAsInteger("GeodeticDatum");
     376               0 :     int nEllipsoid = poFeature->GetFieldAsInteger("Ellipsoid");
     377               0 :     int nProjAlgorithm = poFeature->GetFieldAsInteger("ProjAlgorithm");
     378                 : 
     379               0 :     if (nGeodeticDatum == 17 && nEllipsoid == 22)
     380                 :     {
     381               0 :         if (nProjAlgorithm == 12)
     382                 :         {
     383               0 :             OGRSpatialReference* poSRS = new OGRSpatialReference();
     384                 : 
     385               0 :             const char* pszDescription = poFeature->GetFieldAsString("Description");
     386               0 :             if (pszDescription && pszDescription[0] != 0)
     387               0 :                 poSRS->SetNode( "PROJCS", pszDescription );
     388               0 :             poSRS->SetWellKnownGeogCS("WGS84");
     389                 : 
     390               0 :             double dfStdP1 = poFeature->GetFieldAsDouble("StandPar1");
     391               0 :             double dfStdP2 = poFeature->GetFieldAsDouble("StandPar2");
     392               0 :             double dfCenterLat = poFeature->GetFieldAsDouble("LatOfOrigin");
     393               0 :             double dfCenterLong = poFeature->GetFieldAsDouble("LonOfOrigin");
     394               0 :             double dfFalseEasting = poFeature->GetFieldAsDouble("FalseX");
     395               0 :             double dfFalseNorthing = poFeature->GetFieldAsDouble("FalseY");
     396                 :             poSRS->SetACEA( dfStdP1, dfStdP2,
     397                 :                             dfCenterLat, dfCenterLong,
     398               0 :                             dfFalseEasting, dfFalseNorthing );
     399               0 :             return poSRS;
     400                 :         }
     401                 :     }
     402                 : 
     403               0 :     return NULL;
     404                 : }

Generated by: LCOV version 1.7