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

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmssqlgeometryvalidator.cpp 21933 2011-03-11 16:50:10Z tamas $
       3                 :  *
       4                 :  * Project:  MSSQL Spatial driver
       5                 :  * Purpose:  Implements OGRMSSQLGeometryValidator class to create valid 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: ogrmssqlgeometryvalidator.cpp 21933 2011-03-11 16:50:10Z tamas $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                   OGRMSSQLGeometryValidator()                        */
      37                 : /************************************************************************/
      38                 : 
      39               0 : OGRMSSQLGeometryValidator::OGRMSSQLGeometryValidator(OGRGeometry *poGeom)
      40                 : {
      41               0 :     poOriginalGeometry = poGeom;
      42               0 :     poValidGeometry = NULL;
      43               0 :     bIsValid = ValidateGeometry(poGeom);
      44               0 : }
      45                 : 
      46                 : /************************************************************************/
      47                 : /*                      ~OGRMSSQLGeometryValidator()                    */
      48                 : /************************************************************************/
      49                 : 
      50               0 : OGRMSSQLGeometryValidator::~OGRMSSQLGeometryValidator()
      51                 : {
      52               0 :     if (poValidGeometry)
      53               0 :         delete poValidGeometry;
      54               0 : }
      55                 : 
      56                 : /************************************************************************/
      57                 : /*                         ValidatePoint()                              */
      58                 : /************************************************************************/
      59                 : 
      60               0 : int OGRMSSQLGeometryValidator::ValidatePoint(OGRPoint* poGeom)
      61                 : {
      62               0 :     return TRUE;
      63                 : }
      64                 : 
      65                 : /************************************************************************/
      66                 : /*                     ValidateMultiPoint()                             */
      67                 : /************************************************************************/
      68                 : 
      69               0 : int OGRMSSQLGeometryValidator::ValidateMultiPoint(OGRMultiPoint* poGeom)
      70                 : {
      71               0 :     return TRUE;
      72                 : }
      73                 : 
      74                 : /************************************************************************/
      75                 : /*                         ValidateLineString()                         */
      76                 : /************************************************************************/
      77                 : 
      78               0 : int OGRMSSQLGeometryValidator::ValidateLineString(OGRLineString * poGeom)
      79                 : {
      80               0 :     OGRPoint* poPoint0 = NULL;
      81                 :     int i;
      82               0 :     int bResult = FALSE;
      83                 : 
      84               0 :     for (i = 0; i < poGeom->getNumPoints(); i++)
      85                 :     {
      86               0 :         if (poPoint0 == NULL)
      87                 :         {
      88               0 :             poPoint0 = new OGRPoint();
      89               0 :             poGeom->getPoint(i, poPoint0);
      90               0 :             continue;
      91                 :         }
      92                 : 
      93               0 :         if (poPoint0->getX() == poGeom->getX(i) && poPoint0->getY() == poGeom->getY(i))
      94               0 :             continue;
      95                 : 
      96               0 :         bResult = TRUE;
      97               0 :         break;
      98                 :     }
      99                 : 
     100               0 :     if (!bResult)
     101                 :     {
     102               0 :         if (poValidGeometry)
     103               0 :             delete poValidGeometry;
     104                 : 
     105               0 :         poValidGeometry = NULL;
     106                 : 
     107                 :         // create a compatible geometry
     108               0 :         if (poPoint0 != NULL)
     109                 :         {
     110                 :             CPLError( CE_Warning, CPLE_NotSupported,
     111               0 :                       "Linestring has no distinct points constructing point geometry instead." );
     112                 :             
     113                 :             // create a point
     114               0 :             poValidGeometry = poPoint0;
     115               0 :             poPoint0 = NULL;
     116                 :         }
     117                 :         else
     118                 :         {
     119                 :             CPLError( CE_Warning, CPLE_NotSupported,
     120               0 :                       "Linestring has no points. Removing the geometry from the output." );
     121                 :         }
     122                 :     }
     123                 : 
     124               0 :     if (poPoint0)
     125               0 :         delete poPoint0;
     126                 : 
     127               0 :     return bResult;
     128                 : }
     129                 : 
     130                 : /************************************************************************/
     131                 : /*                         ValidateLinearRing()                         */
     132                 : /************************************************************************/
     133                 : 
     134               0 : int OGRMSSQLGeometryValidator::ValidateLinearRing(OGRLinearRing * poGeom)
     135                 : {
     136               0 :     OGRPoint* poPoint0 = NULL;
     137               0 :     OGRPoint* poPoint1 = NULL;
     138                 :     int i;
     139               0 :     int bResult = FALSE;
     140                 : 
     141               0 :     poGeom->closeRings();
     142                 : 
     143               0 :     for (i = 0; i < poGeom->getNumPoints(); i++)
     144                 :     {
     145               0 :         if (poPoint0 == NULL)
     146                 :         {
     147               0 :             poPoint0 = new OGRPoint();
     148               0 :             poGeom->getPoint(i, poPoint0);
     149               0 :             continue;
     150                 :         }
     151                 : 
     152               0 :         if (poPoint0->getX() == poGeom->getX(i) && poPoint0->getY() == poGeom->getY(i))
     153               0 :             continue;
     154                 : 
     155               0 :         if (poPoint1 == NULL)
     156                 :         {
     157               0 :             poPoint1 = new OGRPoint();
     158               0 :             poGeom->getPoint(i, poPoint1);
     159               0 :             continue;
     160                 :         }
     161                 : 
     162               0 :         if (poPoint1->getX() == poGeom->getX(i) && poPoint1->getY() == poGeom->getY(i))
     163               0 :             continue;
     164                 : 
     165               0 :         bResult = TRUE;
     166               0 :         break;
     167                 :     }
     168                 : 
     169               0 :     if (!bResult)
     170                 :     {
     171               0 :         if (poValidGeometry)
     172               0 :             delete poValidGeometry;
     173                 :         
     174               0 :         poValidGeometry = NULL;
     175                 : 
     176                 :         // create a compatible geometry
     177               0 :         if (poPoint1 != NULL)
     178                 :         {
     179                 :             CPLError( CE_Warning, CPLE_NotSupported,
     180               0 :                       "Linear ring has only 2 distinct points constructing linestring geometry instead." );
     181                 :             
     182                 :             // create a linestring
     183               0 :             poValidGeometry = new OGRLineString();
     184               0 :             ((OGRLineString*)poValidGeometry)->setNumPoints( 2 );
     185               0 :             ((OGRLineString*)poValidGeometry)->addPoint(poPoint0);
     186               0 :             ((OGRLineString*)poValidGeometry)->addPoint(poPoint1);
     187                 :         }
     188               0 :         else if (poPoint0 != NULL)
     189                 :         {
     190                 :             CPLError( CE_Warning, CPLE_NotSupported,
     191               0 :                       "Linear ring has no distinct points constructing point geometry instead." );
     192                 :             
     193                 :             // create a point
     194               0 :             poValidGeometry = poPoint0;
     195               0 :             poPoint0 = NULL;
     196                 :         }
     197                 :         else
     198                 :         {
     199                 :             CPLError( CE_Warning, CPLE_NotSupported,
     200               0 :                       "Linear ring has no points. Removing the geometry from the output." );
     201                 :         }
     202                 :     }
     203                 : 
     204               0 :     if (poPoint0)
     205               0 :         delete poPoint0;
     206                 : 
     207               0 :     if (poPoint1)
     208               0 :         delete poPoint1;
     209                 : 
     210               0 :     return bResult;
     211                 : }
     212                 : 
     213                 : /************************************************************************/
     214                 : /*                     ValidateMultiLineString()                        */
     215                 : /************************************************************************/
     216                 : 
     217               0 : int OGRMSSQLGeometryValidator::ValidateMultiLineString(OGRMultiLineString * poGeom)
     218                 : {
     219                 :     int i, j;
     220                 :     OGRGeometry* poLineString;
     221               0 :     OGRGeometryCollection* poGeometries = NULL;
     222                 : 
     223               0 :     for (i = 0; i < poGeom->getNumGeometries(); i++)
     224                 :     {
     225               0 :         poLineString = poGeom->getGeometryRef(i);
     226               0 :         if (poLineString->getGeometryType() != wkbLineString && poLineString->getGeometryType() != wkbLineString25D)
     227                 :         {
     228                 :             // non linestring geometry
     229               0 :             if (!poGeometries)
     230                 :             {
     231               0 :                 poGeometries = new OGRGeometryCollection();
     232               0 :                 for (j = 0; j < i; j++)
     233               0 :                     poGeometries->addGeometry(poGeom->getGeometryRef(j));
     234                 :             }
     235               0 :             if (ValidateGeometry(poLineString))
     236               0 :                 poGeometries->addGeometry(poLineString);
     237                 :             else
     238               0 :                 poGeometries->addGeometry(poValidGeometry);
     239                 : 
     240               0 :             continue;
     241                 :         }
     242                 : 
     243               0 :         if (!ValidateLineString((OGRLineString*)poLineString))
     244                 :         {
     245                 :             // non valid linestring
     246               0 :             if (!poGeometries)
     247                 :             {
     248               0 :                 poGeometries = new OGRGeometryCollection();
     249               0 :                 for (j = 0; j < i; j++)
     250               0 :                     poGeometries->addGeometry(poGeom->getGeometryRef(j));
     251                 :             }
     252                 :             
     253               0 :             poGeometries->addGeometry(poValidGeometry);
     254               0 :             continue;
     255                 :         }
     256                 : 
     257               0 :         if (poGeometries)
     258               0 :             poGeometries->addGeometry(poLineString);
     259                 :     }
     260                 : 
     261               0 :     if (poGeometries)
     262                 :     {
     263               0 :          if (poValidGeometry)
     264               0 :             delete poValidGeometry;
     265                 : 
     266               0 :         poValidGeometry = poGeometries;
     267                 :     }
     268                 : 
     269               0 :     return (poValidGeometry == NULL);
     270                 : }
     271                 : 
     272                 : /************************************************************************/
     273                 : /*                         ValidatePolygon()                            */
     274                 : /************************************************************************/
     275                 : 
     276               0 : int OGRMSSQLGeometryValidator::ValidatePolygon(OGRPolygon* poGeom)
     277                 : {
     278                 :     int i,j;
     279               0 :     OGRLinearRing* poRing = poGeom->getExteriorRing();
     280                 :     OGRGeometry* poInteriorRing;
     281                 : 
     282               0 :     if (poRing == NULL)
     283               0 :         return FALSE;
     284                 : 
     285               0 :     OGRGeometryCollection* poGeometries = NULL;
     286                 : 
     287               0 :     if (!ValidateLinearRing(poRing))
     288                 :     {
     289               0 :         if (poGeom->getNumInteriorRings() > 0)
     290                 :         {
     291               0 :             poGeometries = new OGRGeometryCollection();
     292               0 :             poGeometries->addGeometryDirectly(poValidGeometry);
     293                 :         }
     294                 :     }
     295                 : 
     296               0 :     for (i = 0; i < poGeom->getNumInteriorRings(); i++)
     297                 :     {
     298               0 :         poInteriorRing = poGeom->getInteriorRing(i);
     299               0 :         if (!ValidateLinearRing((OGRLinearRing*)poInteriorRing))
     300                 :         {
     301               0 :             if (!poGeometries)
     302                 :             {
     303               0 :                 poGeometries = new OGRGeometryCollection();
     304               0 :                 poGeometries->addGeometry(poRing);
     305               0 :                 for (j = 0; j < i; j++)
     306               0 :                     poGeometries->addGeometry(poGeom->getInteriorRing(j));
     307                 :             }
     308                 : 
     309               0 :             poGeometries->addGeometry(poValidGeometry);
     310               0 :             continue;
     311                 :         }
     312                 : 
     313               0 :         if (poGeometries)
     314               0 :             poGeometries->addGeometry(poInteriorRing);
     315                 :     }
     316                 : 
     317               0 :     if (poGeometries)
     318                 :     {
     319               0 :         if (poValidGeometry)
     320               0 :             delete poValidGeometry;
     321                 : 
     322               0 :         poValidGeometry = poGeometries;
     323                 :     }
     324                 : 
     325               0 :     return (poValidGeometry == NULL);
     326                 : }
     327                 : 
     328                 : /************************************************************************/
     329                 : /*                         ValidateMultiPolygon()                       */
     330                 : /************************************************************************/
     331                 : 
     332               0 : int OGRMSSQLGeometryValidator::ValidateMultiPolygon(OGRMultiPolygon* poGeom)
     333                 : {
     334                 :     int i, j;
     335                 :     OGRGeometry* poPolygon;
     336               0 :     OGRGeometryCollection* poGeometries = NULL;
     337                 : 
     338               0 :     for (i = 0; i < poGeom->getNumGeometries(); i++)
     339                 :     {
     340               0 :         poPolygon = poGeom->getGeometryRef(i);
     341               0 :         if (poPolygon->getGeometryType() != wkbPolygon && poPolygon->getGeometryType() != wkbPolygon25D)
     342                 :         {
     343                 :             // non polygon geometry
     344               0 :             if (!poGeometries)
     345                 :             {
     346               0 :                 poGeometries = new OGRGeometryCollection();
     347               0 :                 for (j = 0; j < i; j++)
     348               0 :                     poGeometries->addGeometry(poGeom->getGeometryRef(j));
     349                 :             }
     350               0 :             if (ValidateGeometry(poPolygon))
     351               0 :                 poGeometries->addGeometry(poPolygon);
     352                 :             else
     353               0 :                 poGeometries->addGeometry(poValidGeometry);
     354                 : 
     355               0 :             continue;
     356                 :         }
     357                 : 
     358               0 :         if (!ValidatePolygon((OGRPolygon*)poPolygon))
     359                 :         {
     360                 :             // non valid polygon
     361               0 :             if (!poGeometries)
     362                 :             {
     363               0 :                 poGeometries = new OGRGeometryCollection();
     364               0 :                 for (j = 0; j < i; j++)
     365               0 :                     poGeometries->addGeometry(poGeom->getGeometryRef(j));
     366                 :             }
     367                 :             
     368               0 :             poGeometries->addGeometry(poValidGeometry);
     369               0 :             continue;
     370                 :         }
     371                 : 
     372               0 :         if (poGeometries)
     373               0 :             poGeometries->addGeometry(poPolygon);
     374                 :     }
     375                 : 
     376               0 :     if (poGeometries)
     377                 :     {
     378               0 :         if (poValidGeometry)
     379               0 :             delete poValidGeometry;
     380                 : 
     381               0 :         poValidGeometry = poGeometries;
     382                 :     }
     383                 : 
     384               0 :     return poValidGeometry == NULL;
     385                 : }
     386                 : 
     387                 : /************************************************************************/
     388                 : /*                     ValidateGeometryCollection()                     */
     389                 : /************************************************************************/
     390                 : 
     391               0 : int OGRMSSQLGeometryValidator::ValidateGeometryCollection(OGRGeometryCollection* poGeom)
     392                 : {
     393                 :     int i, j;
     394                 :     OGRGeometry* poGeometry;
     395               0 :     OGRGeometryCollection* poGeometries = NULL;
     396                 : 
     397               0 :     for (i = 0; i < poGeom->getNumGeometries(); i++)
     398                 :     {
     399               0 :         poGeometry = poGeom->getGeometryRef(i);
     400                 :         
     401               0 :         if (!ValidateGeometry(poGeometry))
     402                 :         {
     403                 :             // non valid geometry
     404               0 :             if (!poGeometries)
     405                 :             {
     406               0 :                 poGeometries = new OGRGeometryCollection();
     407               0 :                 for (j = 0; j < i; j++)
     408               0 :                     poGeometries->addGeometry(poGeom->getGeometryRef(j));
     409                 :             }
     410                 :             
     411               0 :             if (poValidGeometry)
     412               0 :                 poGeometries->addGeometry(poValidGeometry);
     413               0 :             continue;
     414                 :         }
     415                 : 
     416               0 :         if (poGeometries)
     417               0 :             poGeometries->addGeometry(poGeometry);
     418                 :     }
     419                 : 
     420               0 :     if (poGeometries)
     421                 :     {
     422               0 :         if (poValidGeometry)
     423               0 :             delete poValidGeometry;
     424                 : 
     425               0 :         poValidGeometry = poGeometries;
     426                 :     }
     427                 : 
     428               0 :     return (poValidGeometry == NULL);
     429                 : }
     430                 : 
     431                 : /************************************************************************/
     432                 : /*                         ValidateGeometry()                           */
     433                 : /************************************************************************/
     434                 : 
     435               0 : int OGRMSSQLGeometryValidator::ValidateGeometry(OGRGeometry* poGeom)
     436                 : {
     437               0 :     if (!poGeom)
     438               0 :         return FALSE;
     439                 :     
     440               0 :     switch (poGeom->getGeometryType())
     441                 :     {
     442                 :     case wkbPoint:
     443                 :     case wkbPoint25D:
     444               0 :         return ValidatePoint((OGRPoint*)poGeom);
     445                 :     case wkbLineString:
     446                 :     case wkbLineString25D:
     447               0 :         return ValidateLineString((OGRLineString*)poGeom);
     448                 :     case wkbPolygon:
     449                 :     case wkbPolygon25D:
     450               0 :         return ValidatePolygon((OGRPolygon*)poGeom);
     451                 :     case wkbMultiPoint:
     452                 :     case wkbMultiPoint25D:
     453               0 :         return ValidateMultiPoint((OGRMultiPoint*)poGeom);
     454                 :     case wkbMultiLineString:
     455                 :     case wkbMultiLineString25D:
     456               0 :         return ValidateMultiLineString((OGRMultiLineString*)poGeom);
     457                 :     case wkbMultiPolygon:
     458                 :     case wkbMultiPolygon25D:
     459               0 :         return ValidateMultiPolygon((OGRMultiPolygon*)poGeom);
     460                 :     case wkbGeometryCollection:
     461                 :     case wkbGeometryCollection25D:
     462               0 :         return ValidateGeometryCollection((OGRGeometryCollection*)poGeom);
     463                 :     case wkbLinearRing:
     464               0 :         return ValidateLinearRing((OGRLinearRing*)poGeom);
     465                 :     default:
     466               0 :         return FALSE;
     467                 :     }
     468                 : }
     469                 : 
     470                 : /************************************************************************/
     471                 : /*                      GetValidGeometryRef()                           */
     472                 : /************************************************************************/
     473               0 : OGRGeometry* OGRMSSQLGeometryValidator::GetValidGeometryRef()
     474                 : {
     475               0 :     if (bIsValid || poOriginalGeometry == NULL)
     476               0 :         return poOriginalGeometry;
     477                 : 
     478               0 :     if (poValidGeometry)
     479                 :     {
     480                 :         CPLError( CE_Warning, CPLE_NotSupported,
     481                 :                       "Invalid geometry has been converted from %s to %s.",
     482               0 :                       poOriginalGeometry->getGeometryName(),
     483               0 :                       poValidGeometry->getGeometryName() );
     484                 :     }
     485                 :     else
     486                 :     {
     487                 :         CPLError( CE_Warning, CPLE_NotSupported,
     488                 :                       "Invalid geometry has been converted from %s to null.",
     489               0 :                       poOriginalGeometry->getGeometryName());
     490                 :     }
     491                 : 
     492               0 :     return poValidGeometry;
     493                 : }
     494                 : 
     495                 : 

Generated by: LCOV version 1.7