LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/libkml - ogrlibkmlgeometry.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 277 208 75.1 %
Date: 2012-12-26 Functions: 7 5 71.4 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Project:  KML Translator
       4                 :  * Purpose:  Implements OGRLIBKMLDriver
       5                 :  * Author:   Brian Case, rush at winkey dot org
       6                 :  *
       7                 :  ******************************************************************************
       8                 :  * Copyright (c) 2010, Brian Case
       9                 :  *
      10                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      11                 :  * copy of this software and associated documentation files (the "Software"),
      12                 :  * to deal in the Software without restriction, including without limitation
      13                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14                 :  * and/or sell copies of the Software, and to permit persons to whom the
      15                 :  * Software is furnished to do so, subject to the following conditions:
      16                 :  *
      17                 :  * The above copyright notice and this permission notice shall be included
      18                 :  * in all copies or substantial portions of the Software.
      19                 :  *
      20                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26                 :  * DEALINGS IN THE SOFTWARE.
      27                 :  *****************************************************************************/
      28                 : 
      29                 : #include <ogr_geometry.h>
      30                 : #include "ogr_p.h"
      31                 : #include <kml/dom.h>
      32                 : 
      33                 : using kmldom::KmlFactory;
      34                 : using kmldom::CoordinatesPtr;
      35                 : using kmldom::PointPtr;
      36                 : using kmldom::LatLonBoxPtr;
      37                 : using kmldom::LineStringPtr;
      38                 : using kmldom::LinearRingPtr;
      39                 : using kmldom::OuterBoundaryIsPtr;
      40                 : using kmldom::InnerBoundaryIsPtr;
      41                 : using kmldom::PolygonPtr;
      42                 : using kmldom::MultiGeometryPtr;
      43                 : using kmldom::GeometryPtr;
      44                 : using kmldom::ElementPtr;
      45                 : using kmldom::GeometryPtr;
      46                 : using kmldom::GxLatLonQuadPtr;
      47                 : 
      48                 : using kmlbase::Vec3;
      49                 : 
      50                 : #include "ogrlibkmlgeometry.h"
      51                 : 
      52                 : /******************************************************************************
      53                 :  funtion to write out a ogr geometry to kml
      54                 : 
      55                 : args:
      56                 :           poOgrGeom     the ogr geometry
      57                 :           extra         used in recursion, just pass -1
      58                 :           wkb25D        used in recursion, just pass 0
      59                 :           poKmlFactory  pointer to the libkml dom factory
      60                 : 
      61                 : returns:
      62                 :           ElementPtr to the geometry created
      63                 : 
      64                 : ******************************************************************************/
      65                 : 
      66              69 : ElementPtr geom2kml (
      67                 :     OGRGeometry * poOgrGeom,
      68                 :     int extra,
      69                 :     int wkb25D,
      70                 :     KmlFactory * poKmlFactory )
      71                 : {
      72                 :     int i;
      73                 : 
      74              69 :     if ( !poOgrGeom ) {
      75               0 :         return NULL;
      76                 :     }
      77                 : 
      78                 :     /***** ogr geom vars *****/
      79                 : 
      80              69 :     OGRPoint *poOgrPoint = NULL;
      81                 :     OGRLineString *poOgrLineString;
      82                 :     OGRPolygon *poOgrPolygon;
      83                 :     OGRGeometryCollection *poOgrMultiGeom;
      84                 : 
      85                 :     /***** libkml geom vars *****/
      86                 : 
      87              69 :     CoordinatesPtr coordinates;
      88              69 :     PointPtr poKmlPoint;
      89              69 :     LineStringPtr poKmlLineString;
      90              69 :     LinearRingPtr poKmlLinearRing;
      91              69 :     OuterBoundaryIsPtr poKmlOuterRing;
      92              69 :     InnerBoundaryIsPtr poKmlInnerRing;
      93              69 :     PolygonPtr poKmlPolygon;
      94              69 :     MultiGeometryPtr poKmlMultiGeometry;
      95                 : 
      96              69 :     ElementPtr poKmlGeometry;
      97              69 :     ElementPtr poKmlTmpGeometry;
      98                 : 
      99                 :     /***** other vars *****/
     100                 : 
     101                 :     double x,
     102                 :         y,
     103                 :         z;
     104                 : 
     105              69 :     int numpoints = 0;
     106                 :     int nGeom;
     107              69 :     int type = poOgrGeom->getGeometryType (  );
     108                 : 
     109              69 :     wkb25D = type & wkb25DBit;
     110                 : 
     111              69 :     switch ( type ) {
     112                 : 
     113                 :     case wkbPoint:
     114                 : 
     115              12 :         poOgrPoint = ( OGRPoint * ) poOgrGeom;
     116              12 :         if (poOgrPoint->getCoordinateDimension() == 0)
     117                 :         {
     118               0 :             poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint (  );
     119                 :         }
     120                 :         else
     121                 :         {
     122              12 :             x = poOgrPoint->getX (  );
     123              12 :             y = poOgrPoint->getY (  );
     124                 : 
     125              12 :             if ( x > 180 )
     126               0 :                 x -= 360;
     127                 : 
     128              12 :             coordinates = poKmlFactory->CreateCoordinates (  );
     129              12 :             coordinates->add_latlng ( y, x );
     130              12 :             poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint (  );
     131              12 :             poKmlPoint->set_coordinates ( coordinates );
     132                 :         }
     133                 : 
     134              12 :         break;
     135                 : 
     136                 :     case wkbPoint25D:
     137               6 :         poOgrPoint = ( OGRPoint * ) poOgrGeom;
     138                 : 
     139               6 :         x = poOgrPoint->getX (  );
     140               6 :         y = poOgrPoint->getY (  );
     141               6 :         z = poOgrPoint->getZ (  );
     142                 : 
     143               6 :         if ( x > 180 )
     144               0 :             x -= 360;
     145                 : 
     146               6 :         coordinates = poKmlFactory->CreateCoordinates (  );
     147               6 :         coordinates->add_latlngalt ( y, x, z );
     148               6 :         poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint (  );
     149               6 :         poKmlPoint->set_coordinates ( coordinates );
     150                 : 
     151               6 :         break;
     152                 : 
     153                 :     case wkbLineString:
     154              12 :         poOgrLineString = ( OGRLineString * ) poOgrGeom;
     155                 : 
     156              12 :         coordinates = poKmlFactory->CreateCoordinates (  );
     157                 : 
     158              12 :         numpoints = poOgrLineString->getNumPoints (  );
     159              12 :         poOgrPoint = new OGRPoint (  );
     160                 : 
     161              36 :         for ( i = 0; i < numpoints; i++ ) {
     162              24 :             poOgrLineString->getPoint ( i, poOgrPoint );
     163                 : 
     164              24 :             x = poOgrPoint->getX (  );
     165              24 :             y = poOgrPoint->getY (  );
     166                 : 
     167              24 :             if ( x > 180 )
     168               0 :                 x -= 360;
     169                 : 
     170              24 :             coordinates->add_latlng ( y, x );
     171                 :         }
     172              12 :         delete poOgrPoint;
     173                 : 
     174                 :         /***** check if its a wkbLinearRing *****/
     175                 : 
     176              12 :         if ( extra < 0 ) {
     177                 : 
     178                 :             poKmlGeometry = poKmlLineString =
     179              12 :                 poKmlFactory->CreateLineString (  );
     180              12 :             poKmlLineString->set_coordinates ( coordinates );
     181                 : 
     182              12 :             break;
     183                 :         }
     184                 : 
     185                 :       /***** fallthough *****/
     186                 : 
     187                 :     case wkbLinearRing:        //this case is for readability only
     188                 : 
     189               0 :         poKmlLinearRing = poKmlFactory->CreateLinearRing (  );
     190               0 :         poKmlLinearRing->set_coordinates ( coordinates );
     191                 : 
     192               0 :         if ( !extra ) {
     193               0 :             poKmlOuterRing = poKmlFactory->CreateOuterBoundaryIs (  );
     194               0 :             poKmlOuterRing->set_linearring ( poKmlLinearRing );
     195               0 :             poKmlGeometry = poKmlOuterRing;
     196                 :         }
     197                 :         else {
     198                 :             poKmlGeometry = poKmlInnerRing =
     199               0 :                 poKmlFactory->CreateInnerBoundaryIs (  );
     200               0 :             poKmlInnerRing->set_linearring ( poKmlLinearRing );
     201                 :         }
     202                 : 
     203                 :     case wkbLineString25D:
     204                 : 
     205              18 :         poOgrLineString = ( OGRLineString * ) poOgrGeom;
     206                 : 
     207              18 :         coordinates = poKmlFactory->CreateCoordinates (  );
     208              18 :         poOgrPoint = new OGRPoint (  );
     209              36 :         numpoints = poOgrLineString->getNumPoints (  );
     210              90 :         for ( i = 0; i < numpoints; i++ ) {
     211              72 :             poOgrLineString->getPoint ( i, poOgrPoint );
     212                 : 
     213              72 :             x = poOgrPoint->getX (  );
     214              72 :             y = poOgrPoint->getY (  );
     215              72 :             z = poOgrPoint->getZ (  );
     216                 : 
     217              72 :             if ( x > 180 )
     218               0 :                 x -= 360;
     219                 : 
     220              72 :             coordinates->add_latlngalt ( y, x, z );
     221                 :         }
     222              18 :         delete poOgrPoint;
     223                 : 
     224                 :         /***** check if its a wkbLinearRing *****/
     225                 : 
     226              18 :         if ( extra < 0 ) {
     227                 : 
     228                 :             poKmlGeometry = poKmlLineString =
     229               0 :                 poKmlFactory->CreateLineString (  );
     230               0 :             poKmlLineString->set_coordinates ( coordinates );
     231                 : 
     232               0 :             break;
     233                 :         }
     234                 :             /***** fallthough *****/
     235                 : 
     236                 :         //case wkbLinearRing25D: // this case is for readability only
     237                 : 
     238              18 :         poKmlLinearRing = poKmlFactory->CreateLinearRing (  );
     239              18 :         poKmlLinearRing->set_coordinates ( coordinates );
     240                 : 
     241              18 :         if ( !extra ) {
     242                 :             poKmlGeometry = poKmlOuterRing =
     243               9 :                 poKmlFactory->CreateOuterBoundaryIs (  );
     244               9 :             poKmlOuterRing->set_linearring ( poKmlLinearRing );
     245                 :         }
     246                 :         else {
     247                 :             poKmlGeometry = poKmlInnerRing =
     248               9 :                 poKmlFactory->CreateInnerBoundaryIs (  );
     249               9 :             poKmlInnerRing->set_linearring ( poKmlLinearRing );
     250                 :         }
     251                 : 
     252              18 :         break;
     253                 : 
     254                 :     case wkbPolygon:
     255                 : 
     256               0 :         poOgrPolygon = ( OGRPolygon * ) poOgrGeom;
     257                 : 
     258               0 :         poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon (  );
     259                 : 
     260                 :         poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing (  ),
     261               0 :                                       0, wkb25D, poKmlFactory );
     262                 :         poKmlPolygon->
     263               0 :             set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) );
     264                 : 
     265               0 :         nGeom = poOgrPolygon->getNumInteriorRings (  );
     266               0 :         for ( i = 0; i < nGeom; i++ ) {
     267                 :             poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ),
     268               0 :                                           i + 1, wkb25D, poKmlFactory );
     269                 :             poKmlPolygon->
     270               0 :                 add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) );
     271                 :         }
     272                 : 
     273               0 :         break;
     274                 : 
     275                 :     case wkbPolygon25D:
     276                 : 
     277               9 :         poOgrPolygon = ( OGRPolygon * ) poOgrGeom;
     278                 : 
     279               9 :         poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon (  );
     280                 : 
     281                 :         poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing (  ),
     282               9 :                                       0, wkb25D, poKmlFactory );
     283                 :         poKmlPolygon->
     284               9 :             set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) );
     285                 : 
     286               9 :         nGeom = poOgrPolygon->getNumInteriorRings (  );
     287              18 :         for ( i = 0; i < nGeom; i++ ) {
     288                 :             poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ),
     289               9 :                                           i + 1, wkb25D, poKmlFactory );
     290                 :             poKmlPolygon->
     291               9 :                 add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) );
     292                 :         }
     293                 : 
     294               9 :         break;
     295                 : 
     296                 :     case wkbMultiPoint:
     297                 :     case wkbMultiLineString:
     298                 :     case wkbMultiPolygon:
     299                 :     case wkbGeometryCollection:
     300                 :     case wkbMultiPoint25D:
     301                 :     case wkbMultiLineString25D:
     302                 :     case wkbMultiPolygon25D:
     303                 :     case wkbGeometryCollection25D:
     304                 : 
     305              12 :         poOgrMultiGeom = ( OGRGeometryCollection * ) poOgrGeom;
     306                 : 
     307                 :         poKmlGeometry = poKmlMultiGeometry =
     308              12 :             poKmlFactory->CreateMultiGeometry (  );
     309                 : 
     310              12 :         nGeom = poOgrMultiGeom->getNumGeometries (  );
     311              36 :         for ( i = 0; i < nGeom; i++ ) {
     312                 :             poKmlTmpGeometry = geom2kml ( poOgrMultiGeom->getGeometryRef ( i ),
     313              24 :                                           -1, wkb25D, poKmlFactory );
     314                 :             poKmlMultiGeometry->
     315              24 :                 add_geometry ( AsGeometry ( poKmlTmpGeometry ) );
     316                 :         }
     317                 : 
     318                 :         break;
     319                 : 
     320                 :     case wkbUnknown:
     321                 :     case wkbNone:
     322                 :     default:
     323                 :         break;
     324                 : 
     325                 :     }
     326                 : 
     327              69 :     return poKmlGeometry;
     328                 : }
     329                 : 
     330                 : /******************************************************************************
     331                 :  recursive function to read a kml geometry and translate to ogr
     332                 : 
     333                 : Args:
     334                 :             poKmlGeometry   pointer to the kml geometry to translate
     335                 :             poOgrSRS        pointer to the spatial ref to set on the geometry 
     336                 : 
     337                 : Returns:
     338                 :             pointer to the new ogr geometry object
     339                 : 
     340                 : ******************************************************************************/
     341                 : 
     342             557 : OGRGeometry *kml2geom_rec (
     343                 :     GeometryPtr poKmlGeometry,
     344                 :     OGRSpatialReference *poOgrSRS)
     345                 : 
     346                 : {
     347                 : 
     348                 :     /***** ogr geom vars *****/
     349                 : 
     350                 :     OGRPoint *poOgrPoint;
     351                 :     OGRLineString *poOgrLineString;
     352                 :     OGRLinearRing *poOgrLinearRing;
     353                 :     OGRPolygon *poOgrPolygon;
     354                 :     OGRGeometryCollection *poOgrMultiGeometry;
     355             557 :     OGRGeometry *poOgrGeometry = NULL;
     356             557 :     OGRGeometry *poOgrTmpGeometry = NULL;
     357                 : 
     358                 : 
     359                 :     /***** libkml geom vars *****/
     360                 : 
     361             557 :     CoordinatesPtr poKmlCoordinates;
     362             557 :     PointPtr poKmlPoint;
     363             557 :     LineStringPtr poKmlLineString;
     364             557 :     LinearRingPtr poKmlLinearRing;
     365             557 :     OuterBoundaryIsPtr poKmlOuterRing;
     366             557 :     InnerBoundaryIsPtr poKmlInnerRing;
     367             557 :     PolygonPtr poKmlPolygon;
     368             557 :     MultiGeometryPtr poKmlMultiGeometry;
     369             557 :     GeometryPtr poKmlTmpGeometry;
     370                 : 
     371             557 :     Vec3 oKmlVec;
     372                 : 
     373                 :     size_t nRings,
     374                 :         nCoords,
     375                 :         nGeom,
     376                 :         i;
     377                 : 
     378             557 :     switch ( poKmlGeometry->Type (  ) ) {
     379                 :     case kmldom::Type_Point:
     380              91 :         poKmlPoint = AsPoint ( poKmlGeometry );
     381              91 :         if ( poKmlPoint->has_coordinates (  ) ) {
     382              90 :             poKmlCoordinates = poKmlPoint->get_coordinates (  );
     383              90 :             nCoords = poKmlCoordinates->get_coordinates_array_size (  );
     384              90 :             if (nCoords > 0)
     385                 :             {
     386              89 :                 oKmlVec = poKmlCoordinates->get_coordinates_array_at ( 0 );
     387                 : 
     388              89 :                 if ( oKmlVec.has_altitude (  ) )
     389                 :                     poOgrPoint = new OGRPoint ( oKmlVec.get_longitude (  ),
     390                 :                                                 oKmlVec.get_latitude (  ),
     391              84 :                                                 oKmlVec.get_altitude (  ) );
     392                 :                 else
     393                 :                     poOgrPoint = new OGRPoint ( oKmlVec.get_longitude (  ),
     394               5 :                                                 oKmlVec.get_latitude (  ) );
     395                 : 
     396              89 :                 poOgrGeometry = poOgrPoint;
     397                 :             }
     398                 :             else
     399                 :             {
     400               1 :                 poOgrGeometry = new OGRPoint();
     401                 :             }
     402                 :         }
     403                 :         else
     404                 :         {
     405               1 :             poOgrGeometry = new OGRPoint();
     406                 :         }
     407                 : 
     408              91 :         break;
     409                 : 
     410                 :     case kmldom::Type_LineString:
     411             105 :         poKmlLineString = AsLineString ( poKmlGeometry );
     412             105 :         poOgrLineString = new OGRLineString (  );
     413             210 :         if ( poKmlLineString->has_coordinates (  ) ) {
     414             104 :             poKmlCoordinates = poKmlLineString->get_coordinates (  );
     415                 : 
     416             104 :             nCoords = poKmlCoordinates->get_coordinates_array_size (  );
     417             796 :             for ( i = 0; i < nCoords; i++ ) {
     418             692 :                 oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
     419             692 :                 if ( oKmlVec.has_altitude (  ) )
     420                 :                     poOgrLineString->
     421                 :                         addPoint ( oKmlVec.get_longitude (  ),
     422                 :                                    oKmlVec.get_latitude (  ),
     423             686 :                                    oKmlVec.get_altitude (  ) );
     424                 :                 else
     425                 :                     poOgrLineString->
     426                 :                         addPoint ( oKmlVec.get_longitude (  ),
     427               6 :                                    oKmlVec.get_latitude (  ) );
     428                 :             }
     429                 :         }
     430             105 :         poOgrGeometry = poOgrLineString;
     431                 : 
     432             105 :         break;
     433                 :     case kmldom::Type_LinearRing:
     434             186 :         poKmlLinearRing = AsLinearRing ( poKmlGeometry );
     435             186 :         poOgrLinearRing = new OGRLinearRing (  );
     436             372 :         if ( poKmlLinearRing->has_coordinates (  ) ) {
     437             183 :             poKmlCoordinates = poKmlLinearRing->get_coordinates (  );
     438                 : 
     439             183 :             nCoords = poKmlCoordinates->get_coordinates_array_size (  );
     440            2318 :             for ( i = 0; i < nCoords; i++ ) {
     441            2135 :                 oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
     442            2135 :                 if ( oKmlVec.has_altitude (  ) )
     443                 :                     poOgrLinearRing->
     444                 :                         addPoint ( oKmlVec.get_longitude (  ),
     445                 :                                    oKmlVec.get_latitude (  ),
     446            2098 :                                    oKmlVec.get_altitude (  ) );
     447                 :                 else
     448                 :                     poOgrLinearRing->
     449                 :                         addPoint ( oKmlVec.get_longitude (  ),
     450              37 :                                    oKmlVec.get_latitude (  ) );
     451                 :             }
     452                 :         }
     453             186 :         poOgrGeometry = poOgrLinearRing;
     454                 : 
     455             186 :         break;
     456                 :     case kmldom::Type_Polygon:
     457             156 :         poKmlPolygon = AsPolygon ( poKmlGeometry );
     458                 : 
     459             156 :         poOgrPolygon = new OGRPolygon (  );
     460             312 :         if ( poKmlPolygon->has_outerboundaryis (  ) ) {
     461                 : 
     462             155 :             poKmlOuterRing = poKmlPolygon->get_outerboundaryis (  );
     463             155 :             poKmlLinearRing = poKmlOuterRing->get_linearring (  );
     464             155 :             if (poKmlLinearRing)
     465                 :             {
     466             154 :                 poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS );
     467                 : 
     468                 :                 poOgrPolygon->
     469             154 :                     addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry );
     470                 :             }
     471                 : 
     472                 :         }
     473             156 :         nRings = poKmlPolygon->get_innerboundaryis_array_size (  );
     474             186 :         for ( i = 0; i < nRings; i++ ) {
     475              30 :             poKmlInnerRing = poKmlPolygon->get_innerboundaryis_array_at ( i );
     476              30 :             poKmlLinearRing = poKmlInnerRing->get_linearring (  );
     477              30 :             if (poKmlLinearRing)
     478                 :             {
     479              29 :                 poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS );
     480                 : 
     481                 :                 poOgrPolygon->
     482              29 :                     addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry );
     483                 :             }
     484                 :         }
     485             156 :         poOgrGeometry = poOgrPolygon;
     486                 : 
     487             156 :         break;
     488                 :     case kmldom::Type_MultiGeometry:
     489                 :     {
     490              19 :         poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
     491              19 :         nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
     492                 : 
     493                 :         /* Detect subgeometry type to instanciate appropriate Multi geometry type */
     494              19 :         kmldom::KmlDomType type = kmldom::Type_Unknown;
     495              46 :         for ( i = 0; i < nGeom; i++ ) {
     496              31 :             poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i );
     497              31 :             if (type == kmldom::Type_Unknown)
     498              17 :                 type = poKmlTmpGeometry->Type();
     499              14 :             else if (type != poKmlTmpGeometry->Type())
     500                 :             {
     501               4 :                 type = kmldom::Type_Unknown;
     502               4 :                 break;
     503                 :             }
     504                 :         }
     505                 : 
     506              19 :         if (type == kmldom::Type_Point)
     507               5 :             poOgrMultiGeometry = new OGRMultiPoint();
     508              14 :         else if (type == kmldom::Type_LineString)
     509               4 :             poOgrMultiGeometry = new OGRMultiLineString();
     510              10 :         else if (type == kmldom::Type_Polygon)
     511               4 :             poOgrMultiGeometry = new OGRMultiPolygon();
     512                 :         else
     513               6 :             poOgrMultiGeometry = new OGRGeometryCollection ();
     514                 : 
     515              50 :         for ( i = 0; i < nGeom; i++ ) {
     516              31 :             poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i );
     517              31 :             poOgrTmpGeometry = kml2geom_rec ( poKmlTmpGeometry, poOgrSRS );
     518                 : 
     519              31 :             poOgrMultiGeometry->addGeometryDirectly ( poOgrTmpGeometry );
     520                 :         }
     521              19 :         poOgrGeometry = poOgrMultiGeometry;
     522                 :         break;
     523                 :     }
     524                 :     default:
     525                 :         break;
     526                 :     }
     527                 : 
     528             557 :     if (poOgrGeometry)
     529             557 :         poOgrGeometry->assignSpatialReference(poOgrSRS);
     530                 : 
     531             557 :     return poOgrGeometry;
     532                 : }
     533                 : 
     534                 : static
     535              18 : OGRGeometry *kml2geom_latlonbox_int (
     536                 :     LatLonBoxPtr poKmlLatLonBox,
     537                 :     OGRSpatialReference *poOgrSRS)
     538                 : 
     539                 : {
     540                 :     OGRPolygon *poOgrPolygon;
     541                 :     double north, south, east, west;
     542              18 :     poOgrPolygon = new OGRPolygon (  );
     543              36 :     if ( !poKmlLatLonBox->has_north (  ) ||
     544                 :          !poKmlLatLonBox->has_south (  ) ||
     545                 :          !poKmlLatLonBox->has_east (  ) ||
     546                 :          !poKmlLatLonBox->has_west (  ) ) {
     547                 : 
     548               0 :         return NULL;
     549                 :     }
     550              18 :     north = poKmlLatLonBox->get_north (  );
     551              18 :     south = poKmlLatLonBox->get_south (  );
     552              18 :     east = poKmlLatLonBox->get_east (  );
     553              18 :     west = poKmlLatLonBox->get_west (  );
     554              18 :     OGRLinearRing* poOgrRing = new OGRLinearRing (  );
     555              18 :     poOgrRing->addPoint ( east, north, 0.0 );
     556              18 :     poOgrRing->addPoint ( east, south, 0.0 );
     557              18 :     poOgrRing->addPoint ( west, south, 0.0 );
     558              18 :     poOgrRing->addPoint ( west, north, 0.0 );
     559              18 :     poOgrRing->addPoint ( east, north, 0.0 );
     560                 :     poOgrPolygon->
     561              18 :         addRingDirectly ( poOgrRing );
     562              18 :     poOgrPolygon->assignSpatialReference(poOgrSRS);
     563                 : 
     564              18 :     return poOgrPolygon;
     565                 : }
     566                 : 
     567                 : static
     568               0 : OGRGeometry *kml2geom_latlonquad_int (
     569                 :     GxLatLonQuadPtr poKmlLatLonQuad,
     570                 :     OGRSpatialReference *poOgrSRS)
     571                 : 
     572                 : {
     573               0 :     if( !poKmlLatLonQuad->has_coordinates() )
     574               0 :         return NULL;
     575                 : 
     576                 :     const CoordinatesPtr& poKmlCoordinates =
     577               0 :         poKmlLatLonQuad->get_coordinates();
     578                 : 
     579               0 :     OGRLinearRing* poOgrLinearRing = new OGRLinearRing (  );
     580                 : 
     581               0 :     size_t nCoords = poKmlCoordinates->get_coordinates_array_size (  );
     582               0 :     for ( size_t i = 0; i < nCoords; i++ ) {
     583               0 :         Vec3 oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
     584               0 :         if ( oKmlVec.has_altitude (  ) )
     585                 :             poOgrLinearRing->
     586                 :                 addPoint ( oKmlVec.get_longitude (  ),
     587                 :                            oKmlVec.get_latitude (  ),
     588               0 :                            oKmlVec.get_altitude (  ) );
     589                 :         else
     590                 :             poOgrLinearRing->
     591                 :                 addPoint ( oKmlVec.get_longitude (  ),
     592               0 :                            oKmlVec.get_latitude (  ) );
     593                 :     }
     594               0 :     poOgrLinearRing->closeRings();
     595                 : 
     596               0 :     OGRPolygon *poOgrPolygon = new OGRPolygon();
     597                 :     poOgrPolygon->
     598               0 :         addRingDirectly ( poOgrLinearRing );
     599               0 :     poOgrPolygon->assignSpatialReference(poOgrSRS);
     600                 : 
     601               0 :     return poOgrPolygon;
     602                 : }
     603                 : 
     604                 : /******************************************************************************
     605                 :  main function to read a kml geometry and translate to ogr
     606                 : 
     607                 : Args:
     608                 :             poKmlGeometry   pointer to the kml geometry to translate
     609                 :             poOgrSRS        pointer to the spatial ref to set on the geometry 
     610                 : 
     611                 : Returns:
     612                 :             pointer to the new ogr geometry object
     613                 : 
     614                 : ******************************************************************************/
     615                 : 
     616             343 : OGRGeometry *kml2geom (
     617                 :     GeometryPtr poKmlGeometry,
     618                 :     OGRSpatialReference *poOgrSRS)
     619                 : 
     620                 : {
     621                 : 
     622                 :     /***** get the geometry *****/
     623                 :     
     624             343 :     OGRGeometry *poOgrGeometry = kml2geom_rec (poKmlGeometry, poOgrSRS);
     625                 : 
     626                 :     /***** split the geometry at the dateline? *****/
     627                 :     
     628             343 :     const char *pszWrap = CPLGetConfigOption ( "LIBKML_WRAPDATELINE", "no" );
     629             343 :     if (CSLTestBoolean(pszWrap)) {
     630                 :         
     631               0 :         char **papszTransformOptions = NULL;
     632                 :         papszTransformOptions = CSLAddString( papszTransformOptions,
     633               0 :                                                 "WRAPDATELINE=YES");
     634                 : 
     635                 :         /***** transform *****/
     636                 :         
     637                 :         OGRGeometry *poOgrDstGeometry = 
     638                 :             OGRGeometryFactory::transformWithOptions(poOgrGeometry,
     639                 :                                                         NULL,
     640               0 :                                                         papszTransformOptions);
     641                 : 
     642                 :         /***** replace the original geom *****/
     643                 :         
     644               0 :         if (poOgrDstGeometry) {
     645               0 :             delete poOgrGeometry;
     646               0 :             poOgrGeometry = poOgrDstGeometry;
     647                 :         }
     648                 :         
     649               0 :         CSLDestroy(papszTransformOptions);
     650                 :     }
     651                 : 
     652             343 :     return poOgrGeometry;
     653                 : }
     654                 : 
     655              18 : OGRGeometry *kml2geom_latlonbox (
     656                 :     LatLonBoxPtr poKmlLatLonBox,
     657                 :     OGRSpatialReference *poOgrSRS)
     658                 : 
     659                 : {
     660                 : 
     661                 :     /***** get the geometry *****/
     662                 :     
     663              18 :     OGRGeometry *poOgrGeometry = kml2geom_latlonbox_int (poKmlLatLonBox, poOgrSRS);
     664                 : 
     665                 :     /***** split the geometry at the dateline? *****/
     666                 :     
     667              18 :     const char *pszWrap = CPLGetConfigOption ( "LIBKML_WRAPDATELINE", "no" );
     668              18 :     if (CSLTestBoolean(pszWrap)) {
     669                 :         
     670               0 :         char **papszTransformOptions = NULL;
     671                 :         papszTransformOptions = CSLAddString( papszTransformOptions,
     672               0 :                                                 "WRAPDATELINE=YES");
     673                 : 
     674                 :         /***** transform *****/
     675                 :         
     676                 :         OGRGeometry *poOgrDstGeometry = 
     677                 :             OGRGeometryFactory::transformWithOptions(poOgrGeometry,
     678                 :                                                         NULL,
     679               0 :                                                         papszTransformOptions);
     680                 : 
     681                 :         /***** replace the original geom *****/
     682                 :         
     683               0 :         if (poOgrDstGeometry) {
     684               0 :             delete poOgrGeometry;
     685               0 :             poOgrGeometry = poOgrDstGeometry;
     686                 :         }
     687                 :         
     688               0 :         CSLDestroy(papszTransformOptions);
     689                 :     }
     690                 : 
     691              18 :     return poOgrGeometry;
     692                 : }
     693                 : 
     694               0 : OGRGeometry *kml2geom_latlonquad (
     695                 :     GxLatLonQuadPtr poKmlLatLonQuad,
     696                 :     OGRSpatialReference *poOgrSRS)
     697                 : 
     698                 : {
     699                 : 
     700                 :     /***** get the geometry *****/
     701                 :     
     702               0 :     OGRGeometry *poOgrGeometry = kml2geom_latlonquad_int (poKmlLatLonQuad, poOgrSRS);
     703                 : 
     704                 :     /***** split the geometry at the dateline? *****/
     705                 :     
     706               0 :     const char *pszWrap = CPLGetConfigOption ( "LIBKML_WRAPDATELINE", "no" );
     707               0 :     if (CSLTestBoolean(pszWrap)) {
     708                 :         
     709               0 :         char **papszTransformOptions = NULL;
     710                 :         papszTransformOptions = CSLAddString( papszTransformOptions,
     711               0 :                                                 "WRAPDATELINE=YES");
     712                 : 
     713                 :         /***** transform *****/
     714                 :         
     715                 :         OGRGeometry *poOgrDstGeometry = 
     716                 :             OGRGeometryFactory::transformWithOptions(poOgrGeometry,
     717                 :                                                         NULL,
     718               0 :                                                         papszTransformOptions);
     719                 : 
     720                 :         /***** replace the original geom *****/
     721                 :         
     722               0 :         if (poOgrDstGeometry) {
     723               0 :             delete poOgrGeometry;
     724               0 :             poOgrGeometry = poOgrDstGeometry;
     725                 :         }
     726                 :         
     727               0 :         CSLDestroy(papszTransformOptions);
     728                 :     }
     729                 : 
     730               0 :     return poOgrGeometry;
     731                 : }

Generated by: LCOV version 1.7