LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/geojson - ogresrijsonreader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 406 274 67.5 %
Date: 2012-12-26 Functions: 18 16 88.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogresrijsonreader.cpp 24923 2012-09-16 09:46:59Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implementation of OGRESRIJSONReader class (OGR ESRIJSON Driver)
       6                 :  *           to read ESRI Feature Service REST data
       7                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2010, Even Rouault
      11                 :  * Copyright (c) 2007, Mateusz Loskot
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "ogrgeojsonreader.h"
      33                 : #include "ogrgeojsonutils.h"
      34                 : #include "ogr_geojson.h"
      35                 : #include <jsonc/json.h> // JSON-C
      36                 : #include <jsonc/json_object_private.h> // json_object_iter, complete type required
      37                 : #include <ogr_api.h>
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                          OGRESRIJSONReader()                         */
      41                 : /************************************************************************/
      42                 : 
      43               8 : OGRESRIJSONReader::OGRESRIJSONReader()
      44               8 :     : poGJObject_( NULL ), poLayer_( NULL )
      45                 : {
      46                 :     // Take a deep breath and get to work.
      47               8 : }
      48                 : 
      49                 : /************************************************************************/
      50                 : /*                         ~OGRESRIJSONReader()                         */
      51                 : /************************************************************************/
      52                 : 
      53               8 : OGRESRIJSONReader::~OGRESRIJSONReader()
      54                 : {
      55               8 :     if( NULL != poGJObject_ )
      56                 :     {
      57               8 :         json_object_put(poGJObject_);
      58                 :     }
      59                 : 
      60               8 :     poGJObject_ = NULL;
      61               8 :     poLayer_ = NULL;
      62               8 : }
      63                 : 
      64                 : /************************************************************************/
      65                 : /*                           Parse()                                    */
      66                 : /************************************************************************/
      67                 : 
      68               8 : OGRErr OGRESRIJSONReader::Parse( const char* pszText )
      69                 : {
      70               8 :     if( NULL != pszText )
      71                 :     {
      72               8 :         json_tokener* jstok = NULL;
      73               8 :         json_object* jsobj = NULL;
      74                 : 
      75               8 :         jstok = json_tokener_new();
      76               8 :         jsobj = json_tokener_parse_ex(jstok, pszText, -1);
      77               8 :         if( jstok->err != json_tokener_success)
      78                 :         {
      79                 :             CPLError( CE_Failure, CPLE_AppDefined,
      80                 :                       "ESRIJSON parsing error: %s (at offset %d)",
      81               0 :                     json_tokener_errors[jstok->err], jstok->char_offset);
      82                 :             
      83               0 :             json_tokener_free(jstok);
      84               0 :             return OGRERR_CORRUPT_DATA;
      85                 :         }
      86               8 :         json_tokener_free(jstok);
      87                 : 
      88                 :         /* JSON tree is shared for while lifetime of the reader object
      89                 :          * and will be released in the destructor.
      90                 :          */
      91               8 :         poGJObject_ = jsobj;
      92                 :     }
      93                 : 
      94               8 :     return OGRERR_NONE;
      95                 : }
      96                 : 
      97                 : /************************************************************************/
      98                 : /*                           ReadLayer()                                */
      99                 : /************************************************************************/
     100                 : 
     101               8 : OGRGeoJSONLayer* OGRESRIJSONReader::ReadLayer( const char* pszName,
     102                 :                                                 OGRGeoJSONDataSource* poDS )
     103                 : {
     104               8 :     CPLAssert( NULL == poLayer_ );
     105                 : 
     106               8 :     if( NULL == poGJObject_ )
     107                 :     {
     108                 :         CPLDebug( "ESRIJSON",
     109               0 :                   "Missing parset ESRIJSON data. Forgot to call Parse()?" );
     110               0 :         return NULL;
     111                 :     }
     112                 :         
     113                 :     poLayer_ = new OGRGeoJSONLayer( pszName, NULL,
     114                 :                                     OGRESRIJSONGetGeometryType(poGJObject_),
     115               8 :                                     poDS );
     116                 : 
     117               8 :     if( !GenerateLayerDefn() )
     118                 :     {
     119                 :         CPLError( CE_Failure, CPLE_AppDefined,
     120               0 :             "Layer schema generation failed." );
     121                 : 
     122               0 :         delete poLayer_;
     123               0 :         return NULL;
     124                 :     }
     125                 : 
     126               8 :     OGRGeoJSONLayer* poThisLayer = NULL;
     127               8 :     poThisLayer = ReadFeatureCollection( poGJObject_ );
     128               8 :     if (poThisLayer == NULL)
     129                 :     {
     130               0 :         delete poLayer_;
     131               0 :         return NULL;
     132                 :     }
     133                 : 
     134               8 :     OGRSpatialReference* poSRS = NULL;
     135               8 :     poSRS = OGRESRIJSONReadSpatialReference( poGJObject_ );
     136               8 :     if (poSRS != NULL )
     137                 :     {
     138               4 :         poLayer_->SetSpatialRef( poSRS );
     139               4 :         delete poSRS;
     140                 :     }
     141                 : 
     142               8 :     return poLayer_;
     143                 : }
     144                 : 
     145                 : /************************************************************************/
     146                 : /*                        GenerateFeatureDefn()                         */
     147                 : /************************************************************************/
     148                 : 
     149               8 : bool OGRESRIJSONReader::GenerateLayerDefn()
     150                 : {
     151               8 :     CPLAssert( NULL != poGJObject_ );
     152               8 :     CPLAssert( NULL != poLayer_->GetLayerDefn() );
     153               8 :     CPLAssert( 0 == poLayer_->GetLayerDefn()->GetFieldCount() );
     154                 : 
     155               8 :     bool bSuccess = true;
     156                 : 
     157                 : /* -------------------------------------------------------------------- */
     158                 : /*      Scan all features and generate layer definition.        */
     159                 : /* -------------------------------------------------------------------- */
     160               8 :     json_object* poObjFeatures = NULL;
     161                 : 
     162               8 :     poObjFeatures = OGRGeoJSONFindMemberByName( poGJObject_, "fields" );
     163               8 :     if( NULL != poObjFeatures && json_type_array == json_object_get_type( poObjFeatures ) )
     164                 :     {
     165               8 :         json_object* poObjFeature = NULL;
     166               8 :         const int nFeatures = json_object_array_length( poObjFeatures );
     167              24 :         for( int i = 0; i < nFeatures; ++i )
     168                 :         {
     169              16 :             poObjFeature = json_object_array_get_idx( poObjFeatures, i );
     170              16 :             if( !GenerateFeatureDefn( poObjFeature ) )
     171                 :             {
     172               0 :                 CPLDebug( "GeoJSON", "Create feature schema failure." );
     173               0 :                 bSuccess = false;
     174                 :             }
     175                 :         }
     176                 :     }
     177                 :     else
     178                 :     {
     179               0 :         poObjFeatures = OGRGeoJSONFindMemberByName( poGJObject_, "fieldAliases" );
     180               0 :         if( NULL != poObjFeatures &&
     181                 :             json_object_get_type(poObjFeatures) == json_type_object )
     182                 :         {
     183               0 :             OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn();
     184                 :             json_object_iter it;
     185               0 :             it.key = NULL;
     186               0 :             it.val = NULL;
     187               0 :             it.entry = NULL;
     188               0 :             json_object_object_foreachC( poObjFeatures, it )
     189                 :             {
     190               0 :                 OGRFieldDefn fldDefn( it.key, OFTString );
     191               0 :                 poDefn->AddFieldDefn( &fldDefn );
     192                 :             }
     193                 :         }
     194                 :         else
     195                 :         {
     196                 :             CPLError( CE_Failure, CPLE_AppDefined,
     197                 :                         "Invalid FeatureCollection object. "
     198               0 :                         "Missing \'fields\' member." );
     199               0 :             bSuccess = false;
     200                 :         }
     201                 :     }
     202                 : 
     203               8 :     return bSuccess;
     204                 : }
     205                 : 
     206                 : /************************************************************************/
     207                 : /*                        GenerateFeatureDefn()                         */
     208                 : /************************************************************************/
     209                 : 
     210              16 : bool OGRESRIJSONReader::GenerateFeatureDefn( json_object* poObj )
     211                 : {
     212              16 :     OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn();
     213              16 :     CPLAssert( NULL != poDefn );
     214                 : 
     215              16 :     bool bSuccess = false;
     216                 : 
     217                 : /* -------------------------------------------------------------------- */
     218                 : /*      Read collection of properties.                  */
     219                 : /* -------------------------------------------------------------------- */
     220              16 :     json_object* poObjName = OGRGeoJSONFindMemberByName( poObj, "name" );
     221              16 :     json_object* poObjType = OGRGeoJSONFindMemberByName( poObj, "type" );
     222              16 :     if( NULL != poObjName && NULL != poObjType )
     223                 :     {
     224              16 :         OGRFieldType eFieldType = OFTString;
     225              16 :         if (EQUAL(json_object_get_string(poObjType), "esriFieldTypeOID"))
     226                 :         {
     227               4 :             eFieldType = OFTInteger;
     228               4 :             poLayer_->SetFIDColumn(json_object_get_string(poObjName));
     229                 :         }
     230              12 :         else if (EQUAL(json_object_get_string(poObjType), "esriFieldTypeDouble"))
     231                 :         {
     232               4 :             eFieldType = OFTReal;
     233                 :         }
     234               8 :         else if (EQUAL(json_object_get_string(poObjType), "esriFieldTypeSmallInteger") ||
     235                 :                  EQUAL(json_object_get_string(poObjType), "esriFieldTypeInteger") )
     236                 :         {
     237               4 :             eFieldType = OFTInteger;
     238                 :         }
     239                 :         OGRFieldDefn fldDefn( json_object_get_string(poObjName),
     240              16 :                               eFieldType);
     241                 : 
     242              16 :         json_object* poObjLength = OGRGeoJSONFindMemberByName( poObj, "length" );
     243              16 :         if (poObjLength != NULL && json_object_get_type(poObjLength) == json_type_int )
     244                 :         {
     245               8 :             fldDefn.SetWidth(json_object_get_int(poObjLength));
     246                 :         }
     247                 : 
     248              16 :         poDefn->AddFieldDefn( &fldDefn );
     249                 : 
     250              16 :         bSuccess = true; // SUCCESS
     251                 :     }
     252              16 :     return bSuccess;
     253                 : }
     254                 : 
     255                 : /************************************************************************/
     256                 : /*                           AddFeature                                 */
     257                 : /************************************************************************/
     258                 : 
     259               8 : bool OGRESRIJSONReader::AddFeature( OGRFeature* poFeature )
     260                 : {
     261               8 :     bool bAdded = false;
     262                 :   
     263               8 :     if( NULL != poFeature )
     264                 :     {
     265               8 :         poLayer_->AddFeature( poFeature );
     266               8 :         bAdded = true;
     267               8 :         delete poFeature;
     268                 :     }
     269                 : 
     270               8 :     return bAdded;
     271                 : }
     272                 : 
     273                 : /************************************************************************/
     274                 : /*                           ReadGeometry()                             */
     275                 : /************************************************************************/
     276                 : 
     277               8 : OGRGeometry* OGRESRIJSONReader::ReadGeometry( json_object* poObj )
     278                 : {
     279               8 :     OGRGeometry* poGeometry = NULL;
     280                 : 
     281               8 :     OGRwkbGeometryType eType = poLayer_->GetGeomType();
     282               8 :     if (eType == wkbPoint)
     283               2 :         poGeometry = OGRESRIJSONReadPoint( poObj );
     284               6 :     else if (eType == wkbLineString)
     285               2 :         poGeometry = OGRESRIJSONReadLineString( poObj );
     286               4 :     else if (eType == wkbPolygon)
     287               2 :         poGeometry = OGRESRIJSONReadPolygon( poObj );
     288               2 :     else if (eType == wkbMultiPoint)
     289               2 :         poGeometry = OGRESRIJSONReadMultiPoint( poObj );
     290                 : 
     291               8 :     return poGeometry;
     292                 : }
     293                 : 
     294                 : /************************************************************************/
     295                 : /*                           ReadFeature()                              */
     296                 : /************************************************************************/
     297                 : 
     298               8 : OGRFeature* OGRESRIJSONReader::ReadFeature( json_object* poObj )
     299                 : {
     300               8 :     CPLAssert( NULL != poObj );
     301               8 :     CPLAssert( NULL != poLayer_ );
     302                 : 
     303               8 :     OGRFeature* poFeature = NULL;
     304               8 :     poFeature = new OGRFeature( poLayer_->GetLayerDefn() );
     305                 : 
     306                 : /* -------------------------------------------------------------------- */
     307                 : /*      Translate ESRIJSON "attributes" object to feature attributes.   */
     308                 : /* -------------------------------------------------------------------- */
     309               8 :     CPLAssert( NULL != poFeature );
     310                 : 
     311               8 :     json_object* poObjProps = NULL;
     312               8 :     poObjProps = OGRGeoJSONFindMemberByName( poObj, "attributes" );
     313               8 :     if( NULL != poObjProps &&
     314                 :         json_object_get_type(poObjProps) == json_type_object )
     315                 :     {
     316               8 :         int nField = -1;
     317               8 :         OGRFieldDefn* poFieldDefn = NULL;
     318                 :         json_object_iter it;
     319               8 :         it.key = NULL;
     320               8 :         it.val = NULL;
     321               8 :         it.entry = NULL;
     322              24 :         json_object_object_foreachC( poObjProps, it )
     323                 :         {
     324              16 :             nField = poFeature->GetFieldIndex(it.key);
     325              16 :             poFieldDefn = poFeature->GetFieldDefnRef(nField);
     326              16 :             if (poFieldDefn && it.val != NULL )
     327                 :             {
     328              16 :                 if ( EQUAL( it.key,  poLayer_->GetFIDColumn() ) )
     329               4 :                     poFeature->SetFID( json_object_get_int( it.val ) );
     330              16 :                 if ( poLayer_->GetLayerDefn()->GetFieldDefn(nField)->GetType() == OFTReal )
     331               4 :                     poFeature->SetField( nField, CPLAtofM(json_object_get_string(it.val)) );
     332                 :                 else
     333              12 :                     poFeature->SetField( nField, json_object_get_string(it.val) );
     334                 :             }
     335                 :         }
     336                 :     }
     337                 : 
     338               8 :     OGRwkbGeometryType eType = poLayer_->GetGeomType();
     339               8 :     if (eType == wkbNone)
     340               0 :         return poFeature;
     341                 : 
     342                 : /* -------------------------------------------------------------------- */
     343                 : /*      Translate geometry sub-object of ESRIJSON Feature.               */
     344                 : /* -------------------------------------------------------------------- */
     345               8 :     json_object* poObjGeom = NULL;
     346                 : 
     347               8 :     json_object* poTmp = poObj;
     348                 : 
     349                 :     json_object_iter it;
     350               8 :     it.key = NULL;
     351               8 :     it.val = NULL;
     352               8 :     it.entry = NULL;
     353              24 :     json_object_object_foreachC(poTmp, it)
     354                 :     {
     355              16 :         if( EQUAL( it.key, "geometry" ) ) {
     356               8 :             if (it.val != NULL)
     357               8 :                 poObjGeom = it.val;
     358                 :             // we're done.  They had 'geometry':null
     359                 :             else
     360               0 :                 return poFeature;
     361                 :         }
     362                 :     }
     363                 :     
     364               8 :     if( NULL != poObjGeom )
     365                 :     {
     366               8 :         OGRGeometry* poGeometry = ReadGeometry( poObjGeom );
     367               8 :         if( NULL != poGeometry )
     368                 :         {
     369               8 :             poFeature->SetGeometryDirectly( poGeometry );
     370                 :         }
     371                 :     }
     372                 :     else
     373                 :     {
     374                 :         CPLError( CE_Failure, CPLE_AppDefined,
     375                 :                   "Invalid Feature object. "
     376               0 :                   "Missing \'geometry\' member." );
     377               0 :         delete poFeature;
     378               0 :         return NULL;
     379                 :     }
     380                 : 
     381               8 :     return poFeature;
     382                 : }
     383                 : 
     384                 : /************************************************************************/
     385                 : /*                           ReadFeatureCollection()                    */
     386                 : /************************************************************************/
     387                 : 
     388                 : OGRGeoJSONLayer*
     389               8 : OGRESRIJSONReader::ReadFeatureCollection( json_object* poObj )
     390                 : {
     391               8 :     CPLAssert( NULL != poLayer_ );
     392                 : 
     393               8 :     json_object* poObjFeatures = NULL;
     394               8 :     poObjFeatures = OGRGeoJSONFindMemberByName( poObj, "features" );
     395               8 :     if( NULL == poObjFeatures )
     396                 :     {
     397                 :         CPLError( CE_Failure, CPLE_AppDefined,
     398                 :                   "Invalid FeatureCollection object. "
     399               0 :                   "Missing \'features\' member." );
     400               0 :         return NULL;
     401                 :     }
     402                 : 
     403               8 :     if( json_type_array == json_object_get_type( poObjFeatures ) )
     404                 :     {
     405               8 :         bool bAdded = false;
     406               8 :         OGRFeature* poFeature = NULL;
     407               8 :         json_object* poObjFeature = NULL;
     408                 : 
     409               8 :         const int nFeatures = json_object_array_length( poObjFeatures );
     410              16 :         for( int i = 0; i < nFeatures; ++i )
     411                 :         {
     412               8 :             poObjFeature = json_object_array_get_idx( poObjFeatures, i );
     413               8 :             if (poObjFeature != NULL &&
     414                 :                 json_object_get_type(poObjFeature) == json_type_object)
     415                 :             {
     416               8 :                 poFeature = OGRESRIJSONReader::ReadFeature( poObjFeature );
     417               8 :                 bAdded = AddFeature( poFeature );
     418                 :             }
     419                 :             //CPLAssert( bAdded );
     420                 :         }
     421                 :         //CPLAssert( nFeatures == poLayer_->GetFeatureCount() );
     422                 :     }
     423                 : 
     424                 :     // We're returning class member to follow the same pattern of
     425                 :     // Read* functions call convention.
     426               8 :     CPLAssert( NULL != poLayer_ );
     427               8 :     return poLayer_;
     428                 : }
     429                 : 
     430                 : /************************************************************************/
     431                 : /*                        OGRESRIJSONGetType()                          */
     432                 : /************************************************************************/
     433                 : 
     434               8 : OGRwkbGeometryType OGRESRIJSONGetGeometryType( json_object* poObj )
     435                 : {
     436               8 :     if( NULL == poObj )
     437               0 :         return wkbUnknown;
     438                 : 
     439               8 :     json_object* poObjType = NULL;
     440               8 :     poObjType = OGRGeoJSONFindMemberByName( poObj, "geometryType" );
     441               8 :     if( NULL == poObjType )
     442                 :     {
     443               0 :         return wkbNone;
     444                 :     }
     445                 : 
     446               8 :     const char* name = json_object_get_string( poObjType );
     447               8 :     if( EQUAL( name, "esriGeometryPoint" ) )
     448               2 :         return wkbPoint;
     449               6 :     else if( EQUAL( name, "esriGeometryPolyline" ) )
     450               2 :         return wkbLineString;
     451               4 :     else if( EQUAL( name, "esriGeometryPolygon" ) )
     452               2 :         return wkbPolygon;
     453               2 :     else if( EQUAL( name, "esriGeometryMultiPoint" ) )
     454               2 :         return wkbMultiPoint;
     455                 :     else
     456               0 :         return wkbUnknown;
     457                 : }
     458                 : 
     459                 : /************************************************************************/
     460                 : /*                          OGRESRIJSONReadPoint()                      */
     461                 : /************************************************************************/
     462                 : 
     463               2 : OGRPoint* OGRESRIJSONReadPoint( json_object* poObj)
     464                 : {
     465               2 :     CPLAssert( NULL != poObj );
     466                 : 
     467               2 :     json_object* poObjX = OGRGeoJSONFindMemberByName( poObj, "x" );
     468               2 :     if( NULL == poObjX )
     469                 :     {
     470                 :         CPLError( CE_Failure, CPLE_AppDefined,
     471                 :             "Invalid Point object. "
     472               0 :             "Missing \'x\' member." );
     473               0 :         return NULL;
     474                 :     }
     475                 : 
     476               2 :     int iTypeX = json_object_get_type(poObjX);
     477               2 :     if ( (json_type_double != iTypeX) && (json_type_int != iTypeX) )
     478                 :     {
     479                 :         CPLError( CE_Failure, CPLE_AppDefined,
     480                 :                 "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     481               0 :                 json_object_to_json_string(poObjX) );
     482               0 :         return NULL;
     483                 :     }
     484                 : 
     485               2 :     json_object* poObjY = OGRGeoJSONFindMemberByName( poObj, "y" );
     486               2 :     if( NULL == poObjY )
     487                 :     {
     488                 :         CPLError( CE_Failure, CPLE_AppDefined,
     489                 :             "Invalid Point object. "
     490               0 :             "Missing \'y\' member." );
     491               0 :         return NULL;
     492                 :     }
     493                 : 
     494               2 :     int iTypeY = json_object_get_type(poObjY);
     495               2 :     if ( (json_type_double != iTypeY) && (json_type_int != iTypeY) )
     496                 :     {
     497                 :         CPLError( CE_Failure, CPLE_AppDefined,
     498                 :                 "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     499               0 :                 json_object_to_json_string(poObjY) );
     500               0 :         return NULL;
     501                 :     }
     502                 : 
     503                 :     double dfX, dfY;
     504               2 :     if (iTypeX == json_type_double)
     505               0 :         dfX = json_object_get_double( poObjX );
     506                 :     else
     507               2 :         dfX = json_object_get_int( poObjX );
     508               2 :     if (iTypeY == json_type_double)
     509               0 :         dfY = json_object_get_double( poObjY );
     510                 :     else
     511               2 :         dfY = json_object_get_int( poObjY );
     512                 : 
     513               2 :     return new OGRPoint(dfX, dfY);
     514                 : }
     515                 : 
     516                 : /************************************************************************/
     517                 : /*                        OGRESRIJSONReadLineString()                   */
     518                 : /************************************************************************/
     519                 : 
     520               2 : OGRLineString* OGRESRIJSONReadLineString( json_object* poObj)
     521                 : {
     522               2 :     CPLAssert( NULL != poObj );
     523                 : 
     524               2 :     OGRLineString* poLine = NULL;
     525                 :     
     526               2 :     json_object* poObjPaths = OGRGeoJSONFindMemberByName( poObj, "paths" );
     527               2 :     if( NULL == poObjPaths )
     528                 :     {
     529                 :         CPLError( CE_Failure, CPLE_AppDefined,
     530                 :             "Invalid LineString object. "
     531               0 :             "Missing \'paths\' member." );
     532               0 :         return NULL;
     533                 :     }
     534                 : 
     535               2 :     if( json_type_array != json_object_get_type( poObjPaths ) )
     536                 :     {
     537                 :         CPLError( CE_Failure, CPLE_AppDefined,
     538                 :             "Invalid LineString object. "
     539               0 :             "Invalid \'paths\' member." );
     540               0 :         return NULL;
     541                 :     }
     542                 :     
     543               2 :     poLine = new OGRLineString();
     544               2 :     const int nPaths = json_object_array_length( poObjPaths );
     545               4 :     for(int iPath = 0; iPath < nPaths; iPath ++)
     546                 :     {
     547               2 :         json_object* poObjPath = json_object_array_get_idx( poObjPaths, iPath );
     548               2 :         if ( poObjPath == NULL ||
     549                 :                 json_type_array != json_object_get_type( poObjPath ) )
     550                 :         {
     551               0 :             delete poLine;
     552                 :             CPLDebug( "ESRIJSON",
     553               0 :                     "LineString: got non-array object." );
     554               0 :             return NULL;
     555                 :         }
     556                 : 
     557               2 :         const int nPoints = json_object_array_length( poObjPath );
     558               6 :         for(int i = 0; i < nPoints; i++)
     559                 :         {
     560               4 :             json_object* poObjCoords = NULL;
     561                 : 
     562               4 :             poObjCoords = json_object_array_get_idx( poObjPath, i );
     563               4 :             if (poObjCoords == NULL)
     564                 :             {
     565               0 :                 delete poLine;
     566                 :                 CPLDebug( "ESRIJSON",
     567               0 :                         "LineString: got null object." );
     568               0 :                 return NULL;
     569                 :             }
     570               4 :             if( json_type_array != json_object_get_type( poObjCoords ) ||
     571                 :                 json_object_array_length( poObjCoords ) != 2 )
     572                 :             {
     573               0 :                 delete poLine;
     574                 :                 CPLDebug( "ESRIJSON",
     575               0 :                         "LineString: got non-array object." );
     576               0 :                 return NULL;
     577                 :             }
     578                 : 
     579                 :             json_object* poObjCoord;
     580                 :             int iType;
     581                 :             double dfX, dfY;
     582                 : 
     583                 :             // Read X coordinate
     584               4 :             poObjCoord = json_object_array_get_idx( poObjCoords, 0 );
     585               4 :             if (poObjCoord == NULL)
     586                 :             {
     587               0 :                 CPLDebug( "ESRIJSON", "LineString: got null object." );
     588               0 :                 delete poLine;
     589               0 :                 return NULL;
     590                 :             }
     591                 : 
     592               4 :             iType = json_object_get_type(poObjCoord);
     593               4 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     594                 :             {
     595                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     596                 :                         "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     597               0 :                         json_object_to_json_string(poObjCoord) );
     598               0 :                 delete poLine;
     599               0 :                 return NULL;
     600                 :             }
     601                 : 
     602               4 :             if (iType == json_type_double)
     603               0 :                 dfX = json_object_get_double( poObjCoord );
     604                 :             else
     605               4 :                 dfX = json_object_get_int( poObjCoord );
     606                 : 
     607                 :             // Read Y coordinate
     608               4 :             poObjCoord = json_object_array_get_idx( poObjCoords, 1 );
     609               4 :             if (poObjCoord == NULL)
     610                 :             {
     611               0 :                 CPLDebug( "ESRIJSON", "LineString: got null object." );
     612               0 :                 delete poLine;
     613               0 :                 return NULL;
     614                 :             }
     615                 : 
     616               4 :             iType = json_object_get_type(poObjCoord);
     617               4 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     618                 :             {
     619                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     620                 :                         "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     621               0 :                         json_object_to_json_string(poObjCoord) );
     622               0 :                 delete poLine;
     623               0 :                 return NULL;
     624                 :             }
     625                 : 
     626               4 :             if (iType == json_type_double)
     627               0 :                 dfY = json_object_get_double( poObjCoord );
     628                 :             else
     629               4 :                 dfY = json_object_get_int( poObjCoord );
     630                 : 
     631               4 :             poLine->addPoint( dfX, dfY );
     632                 :         }
     633                 :     }
     634                 : 
     635               2 :     return poLine;
     636                 : }
     637                 : 
     638                 : /************************************************************************/
     639                 : /*                          OGRESRIJSONReadPolygon()                    */
     640                 : /************************************************************************/
     641                 : 
     642               2 : OGRPolygon* OGRESRIJSONReadPolygon( json_object* poObj)
     643                 : {
     644               2 :     CPLAssert( NULL != poObj );
     645                 : 
     646               2 :     OGRPolygon* poPoly = NULL;
     647                 : 
     648               2 :     json_object* poObjRings = OGRGeoJSONFindMemberByName( poObj, "rings" );
     649               2 :     if( NULL == poObjRings )
     650                 :     {
     651                 :         CPLError( CE_Failure, CPLE_AppDefined,
     652                 :             "Invalid Polygon object. "
     653               0 :             "Missing \'rings\' member." );
     654               0 :         return NULL;
     655                 :     }
     656                 : 
     657               2 :     if( json_type_array != json_object_get_type( poObjRings ) )
     658                 :     {
     659                 :         CPLError( CE_Failure, CPLE_AppDefined,
     660                 :             "Invalid Polygon object. "
     661               0 :             "Invalid \'rings\' member." );
     662               0 :         return NULL;
     663                 :     }
     664                 : 
     665               2 :     poPoly = new OGRPolygon();
     666                 : 
     667               2 :     const int nRings = json_object_array_length( poObjRings );
     668               4 :     for(int iRing = 0; iRing < nRings; iRing ++)
     669                 :     {
     670               2 :         json_object* poObjRing = json_object_array_get_idx( poObjRings, iRing );
     671               2 :         if ( poObjRing == NULL ||
     672                 :                 json_type_array != json_object_get_type( poObjRing ) )
     673                 :         {
     674               0 :             delete poPoly;
     675                 :             CPLDebug( "ESRIJSON",
     676               0 :                     "Polygon: got non-array object." );
     677               0 :             return NULL;
     678                 :         }
     679                 : 
     680               2 :         OGRLinearRing* poLine = new OGRLinearRing();
     681               2 :         poPoly->addRingDirectly(poLine);
     682                 : 
     683               2 :         const int nPoints = json_object_array_length( poObjRing );
     684              12 :         for(int i = 0; i < nPoints; i++)
     685                 :         {
     686              10 :             json_object* poObjCoords = NULL;
     687                 : 
     688              10 :             poObjCoords = json_object_array_get_idx( poObjRing, i );
     689              10 :             if (poObjCoords == NULL)
     690                 :             {
     691               0 :                 delete poPoly;
     692                 :                 CPLDebug( "ESRIJSON",
     693               0 :                         "Polygon: got null object." );
     694               0 :                 return NULL;
     695                 :             }
     696              10 :             if( json_type_array != json_object_get_type( poObjCoords ) ||
     697                 :                 json_object_array_length( poObjCoords ) != 2 )
     698                 :             {
     699               0 :                 delete poPoly;
     700                 :                 CPLDebug( "ESRIJSON",
     701               0 :                         "Polygon: got non-array object." );
     702               0 :                 return NULL;
     703                 :             }
     704                 : 
     705                 :             json_object* poObjCoord;
     706                 :             int iType;
     707                 :             double dfX, dfY;
     708                 : 
     709                 :             // Read X coordinate
     710              10 :             poObjCoord = json_object_array_get_idx( poObjCoords, 0 );
     711              10 :             if (poObjCoord == NULL)
     712                 :             {
     713               0 :                 CPLDebug( "ESRIJSON", "Polygon: got null object." );
     714               0 :                 delete poPoly;
     715               0 :                 return NULL;
     716                 :             }
     717                 : 
     718              10 :             iType = json_object_get_type(poObjCoord);
     719              10 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     720                 :             {
     721                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     722                 :                         "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     723               0 :                         json_object_to_json_string(poObjCoord) );
     724               0 :                 delete poPoly;
     725               0 :                 return NULL;
     726                 :             }
     727                 : 
     728              10 :             if (iType == json_type_double)
     729               0 :                 dfX = json_object_get_double( poObjCoord );
     730                 :             else
     731              10 :                 dfX = json_object_get_int( poObjCoord );
     732                 : 
     733                 :             // Read Y coordinate
     734              10 :             poObjCoord = json_object_array_get_idx( poObjCoords, 1 );
     735              10 :             if (poObjCoord == NULL)
     736                 :             {
     737               0 :                 CPLDebug( "ESRIJSON", "Polygon: got null object." );
     738               0 :                 delete poPoly;
     739               0 :                 return NULL;
     740                 :             }
     741                 : 
     742              10 :             iType = json_object_get_type(poObjCoord);
     743              10 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     744                 :             {
     745                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     746                 :                         "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     747               0 :                         json_object_to_json_string(poObjCoord) );
     748               0 :                 delete poPoly;
     749               0 :                 return NULL;
     750                 :             }
     751                 : 
     752              10 :             if (iType == json_type_double)
     753               0 :                 dfY = json_object_get_double( poObjCoord );
     754                 :             else
     755              10 :                 dfY = json_object_get_int( poObjCoord );
     756                 : 
     757              10 :             poLine->addPoint( dfX, dfY );
     758                 :         }
     759                 :     }
     760                 : 
     761               2 :     return poPoly;
     762                 : }
     763                 : 
     764                 : /************************************************************************/
     765                 : /*                        OGRESRIJSONReadMultiPoint()                   */
     766                 : /************************************************************************/
     767                 : 
     768               2 : OGRMultiPoint* OGRESRIJSONReadMultiPoint( json_object* poObj)
     769                 : {
     770               2 :     CPLAssert( NULL != poObj );
     771                 : 
     772               2 :     OGRMultiPoint* poMulti = NULL;
     773                 : 
     774               2 :     json_object* poObjPoints = OGRGeoJSONFindMemberByName( poObj, "points" );
     775               2 :     if( NULL == poObjPoints )
     776                 :     {
     777                 :         CPLError( CE_Failure, CPLE_AppDefined,
     778                 :             "Invalid LineString object. "
     779               0 :             "Missing \'points\' member." );
     780               0 :         return NULL;
     781                 :     }
     782                 : 
     783               2 :     if( json_type_array != json_object_get_type( poObjPoints ) )
     784                 :     {
     785                 :         CPLError( CE_Failure, CPLE_AppDefined,
     786                 :             "Invalid LineString object. "
     787               0 :             "Invalid \'points\' member." );
     788               0 :         return NULL;
     789                 :     }
     790                 : 
     791               2 :     poMulti = new OGRMultiPoint();
     792                 : 
     793               2 :     const int nPoints = json_object_array_length( poObjPoints );
     794              12 :     for(int i = 0; i < nPoints; i++)
     795                 :     {
     796               4 :         json_object* poObjCoords = NULL;
     797                 : 
     798               4 :         poObjCoords = json_object_array_get_idx( poObjPoints, i );
     799               4 :         if (poObjCoords == NULL)
     800                 :         {
     801               0 :             delete poMulti;
     802                 :             CPLDebug( "ESRIJSON",
     803               0 :                     "MultiPoint: got null object." );
     804               0 :             return NULL;
     805                 :         }
     806               4 :         if( json_type_array != json_object_get_type( poObjCoords ) ||
     807                 :             json_object_array_length( poObjCoords ) != 2 )
     808                 :         {
     809               0 :             delete poMulti;
     810                 :             CPLDebug( "ESRIJSON",
     811               0 :                     "MultiPoint: got non-array object." );
     812               0 :             return NULL;
     813                 :         }
     814                 : 
     815                 :         json_object* poObjCoord;
     816                 :         int iType;
     817                 :         double dfX, dfY;
     818                 : 
     819                 :         // Read X coordinate
     820               4 :         poObjCoord = json_object_array_get_idx( poObjCoords, 0 );
     821               4 :         if (poObjCoord == NULL)
     822                 :         {
     823               0 :             CPLDebug( "ESRIJSON", "MultiPoint: got null object." );
     824               0 :             delete poMulti;
     825               0 :             return NULL;
     826                 :         }
     827                 : 
     828               4 :         iType = json_object_get_type(poObjCoord);
     829               4 :         if ( (json_type_double != iType) && (json_type_int != iType) )
     830                 :         {
     831                 :             CPLError( CE_Failure, CPLE_AppDefined,
     832                 :                     "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     833               0 :                     json_object_to_json_string(poObjCoord) );
     834               0 :             delete poMulti;
     835               0 :             return NULL;
     836                 :         }
     837                 : 
     838               4 :         if (iType == json_type_double)
     839               0 :             dfX = json_object_get_double( poObjCoord );
     840                 :         else
     841               4 :             dfX = json_object_get_int( poObjCoord );
     842                 : 
     843                 :         // Read Y coordinate
     844               4 :         poObjCoord = json_object_array_get_idx( poObjCoords, 1 );
     845               4 :         if (poObjCoord == NULL)
     846                 :         {
     847               0 :             CPLDebug( "ESRIJSON", "MultiPoint: got null object." );
     848               0 :             delete poMulti;
     849               0 :             return NULL;
     850                 :         }
     851                 : 
     852               4 :         iType = json_object_get_type(poObjCoord);
     853               4 :         if ( (json_type_double != iType) && (json_type_int != iType) )
     854                 :         {
     855                 :             CPLError( CE_Failure, CPLE_AppDefined,
     856                 :                     "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     857               0 :                     json_object_to_json_string(poObjCoord) );
     858               0 :             delete poMulti;
     859               0 :             return NULL;
     860                 :         }
     861                 : 
     862               4 :         if (iType == json_type_double)
     863               0 :             dfY = json_object_get_double( poObjCoord );
     864                 :         else
     865               4 :             dfY = json_object_get_int( poObjCoord );
     866                 : 
     867               4 :         poMulti->addGeometryDirectly( new OGRPoint(dfX, dfY) );
     868                 :     }
     869                 : 
     870               2 :     return poMulti;
     871                 : }
     872                 : 
     873                 : /************************************************************************/
     874                 : /*                    OGRESRIJSONReadSpatialReference()                 */
     875                 : /************************************************************************/
     876                 : 
     877               8 : OGRSpatialReference* OGRESRIJSONReadSpatialReference( json_object* poObj )
     878                 : {
     879                 : /* -------------------------------------------------------------------- */
     880                 : /*      Read spatial reference definition.                              */
     881                 : /* -------------------------------------------------------------------- */
     882               8 :     OGRSpatialReference* poSRS = NULL;
     883                 : 
     884               8 :     json_object* poObjSrs = OGRGeoJSONFindMemberByName( poObj, "spatialReference" );
     885               8 :     if( NULL != poObjSrs )
     886                 :     {
     887               4 :         json_object* poObjWkid = OGRGeoJSONFindMemberByName( poObjSrs, "wkid" );
     888               4 :         if (poObjWkid == NULL)
     889                 :         {
     890               0 :             json_object* poObjWkt = OGRGeoJSONFindMemberByName( poObjSrs, "wkt" );
     891               0 :             if (poObjWkt == NULL)
     892               0 :                 return NULL;
     893                 : 
     894               0 :             char* pszWKT = (char*) json_object_get_string( poObjWkt );
     895               0 :             poSRS = new OGRSpatialReference();
     896               0 :             if( OGRERR_NONE != poSRS->importFromWkt( &pszWKT ) ||
     897                 :                 poSRS->morphFromESRI() != OGRERR_NONE )
     898                 :             {
     899               0 :                 delete poSRS;
     900               0 :                 poSRS = NULL;
     901                 :             }
     902                 : 
     903               0 :             return poSRS;
     904                 :         }
     905                 : 
     906               4 :         int nEPSG = json_object_get_int( poObjWkid );
     907                 : 
     908               4 :         poSRS = new OGRSpatialReference();
     909               4 :         if( OGRERR_NONE != poSRS->importFromEPSG( nEPSG ) )
     910                 :         {
     911               0 :             delete poSRS;
     912               0 :             poSRS = NULL;
     913                 :         }
     914                 :     }
     915                 : 
     916               8 :     return poSRS;
     917                 : }

Generated by: LCOV version 1.7