LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/geojson - ogresrijsonreader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 403 271 67.2 %
Date: 2011-12-18 Functions: 18 16 88.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogresrijsonreader.cpp 22281 2011-05-01 17:57:55Z 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 :                                     NULL, 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                 :         {
     182               0 :             OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn();
     183                 :             json_object_iter it;
     184               0 :             it.key = NULL;
     185               0 :             it.val = NULL;
     186               0 :             it.entry = NULL;
     187               0 :             json_object_object_foreachC( poObjFeatures, it )
     188                 :             {
     189               0 :                 OGRFieldDefn fldDefn( it.key, OFTString );
     190               0 :                 poDefn->AddFieldDefn( &fldDefn );
     191                 :             }
     192                 :         }
     193                 :         else
     194                 :         {
     195                 :             CPLError( CE_Failure, CPLE_AppDefined,
     196                 :                         "Invalid FeatureCollection object. "
     197               0 :                         "Missing \'fields\' member." );
     198               0 :             bSuccess = false;
     199                 :         }
     200                 :     }
     201                 : 
     202               8 :     return bSuccess;
     203                 : }
     204                 : 
     205                 : /************************************************************************/
     206                 : /*                        GenerateFeatureDefn()                         */
     207                 : /************************************************************************/
     208                 : 
     209              16 : bool OGRESRIJSONReader::GenerateFeatureDefn( json_object* poObj )
     210                 : {
     211              16 :     OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn();
     212              16 :     CPLAssert( NULL != poDefn );
     213                 : 
     214              16 :     bool bSuccess = false;
     215                 : 
     216                 : /* -------------------------------------------------------------------- */
     217                 : /*      Read collection of properties.                  */
     218                 : /* -------------------------------------------------------------------- */
     219              16 :     json_object* poObjName = OGRGeoJSONFindMemberByName( poObj, "name" );
     220              16 :     json_object* poObjType = OGRGeoJSONFindMemberByName( poObj, "type" );
     221              16 :     if( NULL != poObjName && NULL != poObjType )
     222                 :     {
     223              16 :         OGRFieldType eFieldType = OFTString;
     224              16 :         if (EQUAL(json_object_get_string(poObjType), "esriFieldTypeOID"))
     225                 :         {
     226               4 :             eFieldType = OFTInteger;
     227               4 :             poLayer_->SetFIDColumn(json_object_get_string(poObjName));
     228                 :         }
     229              12 :         else if (EQUAL(json_object_get_string(poObjType), "esriFieldTypeDouble"))
     230                 :         {
     231               4 :             eFieldType = OFTReal;
     232                 :         }
     233               8 :         else if (EQUAL(json_object_get_string(poObjType), "esriFieldTypeSmallInteger") ||
     234                 :                  EQUAL(json_object_get_string(poObjType), "esriFieldTypeInteger") )
     235                 :         {
     236               4 :             eFieldType = OFTInteger;
     237                 :         }
     238                 :         OGRFieldDefn fldDefn( json_object_get_string(poObjName),
     239              16 :                               eFieldType);
     240                 : 
     241              16 :         json_object* poObjLength = OGRGeoJSONFindMemberByName( poObj, "length" );
     242              16 :         if (poObjLength != NULL && json_object_get_type(poObjLength) == json_type_int )
     243                 :         {
     244               8 :             fldDefn.SetWidth(json_object_get_int(poObjLength));
     245                 :         }
     246                 : 
     247              16 :         poDefn->AddFieldDefn( &fldDefn );
     248                 : 
     249              16 :         bSuccess = true; // SUCCESS
     250                 :     }
     251              16 :     return bSuccess;
     252                 : }
     253                 : 
     254                 : /************************************************************************/
     255                 : /*                           AddFeature                                 */
     256                 : /************************************************************************/
     257                 : 
     258               8 : bool OGRESRIJSONReader::AddFeature( OGRFeature* poFeature )
     259                 : {
     260               8 :     bool bAdded = false;
     261                 :   
     262               8 :     if( NULL != poFeature )
     263                 :     {
     264               8 :         poLayer_->AddFeature( poFeature );
     265               8 :         bAdded = true;
     266               8 :         delete poFeature;
     267                 :     }
     268                 : 
     269               8 :     return bAdded;
     270                 : }
     271                 : 
     272                 : /************************************************************************/
     273                 : /*                           ReadGeometry()                             */
     274                 : /************************************************************************/
     275                 : 
     276               8 : OGRGeometry* OGRESRIJSONReader::ReadGeometry( json_object* poObj )
     277                 : {
     278               8 :     OGRGeometry* poGeometry = NULL;
     279                 : 
     280               8 :     OGRwkbGeometryType eType = poLayer_->GetGeomType();
     281               8 :     if (eType == wkbPoint)
     282               2 :         poGeometry = OGRESRIJSONReadPoint( poObj );
     283               6 :     else if (eType == wkbLineString)
     284               2 :         poGeometry = OGRESRIJSONReadLineString( poObj );
     285               4 :     else if (eType == wkbPolygon)
     286               2 :         poGeometry = OGRESRIJSONReadPolygon( poObj );
     287               2 :     else if (eType == wkbMultiPoint)
     288               2 :         poGeometry = OGRESRIJSONReadMultiPoint( poObj );
     289                 : 
     290               8 :     return poGeometry;
     291                 : }
     292                 : 
     293                 : /************************************************************************/
     294                 : /*                           ReadFeature()                              */
     295                 : /************************************************************************/
     296                 : 
     297               8 : OGRFeature* OGRESRIJSONReader::ReadFeature( json_object* poObj )
     298                 : {
     299               8 :     CPLAssert( NULL != poObj );
     300               8 :     CPLAssert( NULL != poLayer_ );
     301                 : 
     302               8 :     OGRFeature* poFeature = NULL;
     303               8 :     poFeature = new OGRFeature( poLayer_->GetLayerDefn() );
     304                 : 
     305                 : /* -------------------------------------------------------------------- */
     306                 : /*      Translate ESRIJSON "attributes" object to feature attributes.   */
     307                 : /* -------------------------------------------------------------------- */
     308               8 :     CPLAssert( NULL != poFeature );
     309                 : 
     310               8 :     json_object* poObjProps = NULL;
     311               8 :     poObjProps = OGRGeoJSONFindMemberByName( poObj, "attributes" );
     312               8 :     if( NULL != poObjProps )
     313                 :     {
     314               8 :         int nField = -1;
     315               8 :         OGRFieldDefn* poFieldDefn = NULL;
     316                 :         json_object_iter it;
     317               8 :         it.key = NULL;
     318               8 :         it.val = NULL;
     319               8 :         it.entry = NULL;
     320              24 :         json_object_object_foreachC( poObjProps, it )
     321                 :         {
     322              16 :             nField = poFeature->GetFieldIndex(it.key);
     323              16 :             poFieldDefn = poFeature->GetFieldDefnRef(nField);
     324              16 :             if (poFieldDefn && it.val != NULL )
     325                 :             {
     326              16 :                 if ( EQUAL( it.key,  poLayer_->GetFIDColumn() ) )
     327               4 :                     poFeature->SetFID( json_object_get_int( it.val ) );
     328              16 :                 poFeature->SetField( nField, json_object_get_string(it.val) );
     329                 :             }
     330                 :         }
     331                 :     }
     332                 : 
     333               8 :     OGRwkbGeometryType eType = poLayer_->GetGeomType();
     334               8 :     if (eType == wkbNone)
     335               0 :         return poFeature;
     336                 : 
     337                 : /* -------------------------------------------------------------------- */
     338                 : /*      Translate geometry sub-object of ESRIJSON Feature.               */
     339                 : /* -------------------------------------------------------------------- */
     340               8 :     json_object* poObjGeom = NULL;
     341                 : 
     342               8 :     json_object* poTmp = poObj;
     343                 : 
     344                 :     json_object_iter it;
     345               8 :     it.key = NULL;
     346               8 :     it.val = NULL;
     347               8 :     it.entry = NULL;
     348              24 :     json_object_object_foreachC(poTmp, it)
     349                 :     {
     350              16 :         if( EQUAL( it.key, "geometry" ) ) {
     351               8 :             if (it.val != NULL)
     352               8 :                 poObjGeom = it.val;
     353                 :             // we're done.  They had 'geometry':null
     354                 :             else
     355               0 :                 return poFeature;
     356                 :         }
     357                 :     }
     358                 :     
     359               8 :     if( NULL != poObjGeom )
     360                 :     {
     361               8 :         OGRGeometry* poGeometry = ReadGeometry( poObjGeom );
     362               8 :         if( NULL != poGeometry )
     363                 :         {
     364               8 :             poFeature->SetGeometryDirectly( poGeometry );
     365                 :         }
     366                 :     }
     367                 :     else
     368                 :     {
     369                 :         CPLError( CE_Failure, CPLE_AppDefined,
     370                 :                   "Invalid Feature object. "
     371               0 :                   "Missing \'geometry\' member." );
     372               0 :         delete poFeature;
     373               0 :         return NULL;
     374                 :     }
     375                 : 
     376               8 :     return poFeature;
     377                 : }
     378                 : 
     379                 : /************************************************************************/
     380                 : /*                           ReadFeatureCollection()                    */
     381                 : /************************************************************************/
     382                 : 
     383                 : OGRGeoJSONLayer*
     384               8 : OGRESRIJSONReader::ReadFeatureCollection( json_object* poObj )
     385                 : {
     386               8 :     CPLAssert( NULL != poLayer_ );
     387                 : 
     388               8 :     json_object* poObjFeatures = NULL;
     389               8 :     poObjFeatures = OGRGeoJSONFindMemberByName( poObj, "features" );
     390               8 :     if( NULL == poObjFeatures )
     391                 :     {
     392                 :         CPLError( CE_Failure, CPLE_AppDefined,
     393                 :                   "Invalid FeatureCollection object. "
     394               0 :                   "Missing \'features\' member." );
     395               0 :         return NULL;
     396                 :     }
     397                 : 
     398               8 :     if( json_type_array == json_object_get_type( poObjFeatures ) )
     399                 :     {
     400               8 :         bool bAdded = false;
     401               8 :         OGRFeature* poFeature = NULL;
     402               8 :         json_object* poObjFeature = NULL;
     403                 : 
     404               8 :         const int nFeatures = json_object_array_length( poObjFeatures );
     405              16 :         for( int i = 0; i < nFeatures; ++i )
     406                 :         {
     407               8 :             poObjFeature = json_object_array_get_idx( poObjFeatures, i );
     408               8 :             poFeature = OGRESRIJSONReader::ReadFeature( poObjFeature );
     409               8 :             bAdded = AddFeature( poFeature );
     410                 :             //CPLAssert( bAdded );
     411                 :         }
     412                 :         //CPLAssert( nFeatures == poLayer_->GetFeatureCount() );
     413                 :     }
     414                 : 
     415                 :     // We're returning class member to follow the same pattern of
     416                 :     // Read* functions call convention.
     417               8 :     CPLAssert( NULL != poLayer_ );
     418               8 :     return poLayer_;
     419                 : }
     420                 : 
     421                 : /************************************************************************/
     422                 : /*                        OGRESRIJSONGetType()                          */
     423                 : /************************************************************************/
     424                 : 
     425               8 : OGRwkbGeometryType OGRESRIJSONGetGeometryType( json_object* poObj )
     426                 : {
     427               8 :     if( NULL == poObj )
     428               0 :         return wkbUnknown;
     429                 : 
     430               8 :     json_object* poObjType = NULL;
     431               8 :     poObjType = OGRGeoJSONFindMemberByName( poObj, "geometryType" );
     432               8 :     if( NULL == poObjType )
     433                 :     {
     434               0 :         return wkbNone;
     435                 :     }
     436                 : 
     437               8 :     const char* name = json_object_get_string( poObjType );
     438               8 :     if( EQUAL( name, "esriGeometryPoint" ) )
     439               2 :         return wkbPoint;
     440               6 :     else if( EQUAL( name, "esriGeometryPolyline" ) )
     441               2 :         return wkbLineString;
     442               4 :     else if( EQUAL( name, "esriGeometryPolygon" ) )
     443               2 :         return wkbPolygon;
     444               2 :     else if( EQUAL( name, "esriGeometryMultiPoint" ) )
     445               2 :         return wkbMultiPoint;
     446                 :     else
     447               0 :         return wkbUnknown;
     448                 : }
     449                 : 
     450                 : /************************************************************************/
     451                 : /*                          OGRESRIJSONReadPoint()                      */
     452                 : /************************************************************************/
     453                 : 
     454               2 : OGRPoint* OGRESRIJSONReadPoint( json_object* poObj)
     455                 : {
     456               2 :     CPLAssert( NULL != poObj );
     457                 : 
     458               2 :     json_object* poObjX = OGRGeoJSONFindMemberByName( poObj, "x" );
     459               2 :     if( NULL == poObjX )
     460                 :     {
     461                 :         CPLError( CE_Failure, CPLE_AppDefined,
     462                 :             "Invalid Point object. "
     463               0 :             "Missing \'x\' member." );
     464               0 :         return NULL;
     465                 :     }
     466                 : 
     467               2 :     int iTypeX = json_object_get_type(poObjX);
     468               2 :     if ( (json_type_double != iTypeX) && (json_type_int != iTypeX) )
     469                 :     {
     470                 :         CPLError( CE_Failure, CPLE_AppDefined,
     471                 :                 "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     472               0 :                 json_object_to_json_string(poObjX) );
     473               0 :         return NULL;
     474                 :     }
     475                 : 
     476               2 :     json_object* poObjY = OGRGeoJSONFindMemberByName( poObj, "y" );
     477               2 :     if( NULL == poObjY )
     478                 :     {
     479                 :         CPLError( CE_Failure, CPLE_AppDefined,
     480                 :             "Invalid Point object. "
     481               0 :             "Missing \'y\' member." );
     482               0 :         return NULL;
     483                 :     }
     484                 : 
     485               2 :     int iTypeY = json_object_get_type(poObjY);
     486               2 :     if ( (json_type_double != iTypeY) && (json_type_int != iTypeY) )
     487                 :     {
     488                 :         CPLError( CE_Failure, CPLE_AppDefined,
     489                 :                 "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     490               0 :                 json_object_to_json_string(poObjY) );
     491               0 :         return NULL;
     492                 :     }
     493                 : 
     494                 :     double dfX, dfY;
     495               2 :     if (iTypeX == json_type_double)
     496               0 :         dfX = json_object_get_double( poObjX );
     497                 :     else
     498               2 :         dfX = json_object_get_int( poObjX );
     499               2 :     if (iTypeY == json_type_double)
     500               0 :         dfY = json_object_get_double( poObjY );
     501                 :     else
     502               2 :         dfY = json_object_get_int( poObjY );
     503                 : 
     504               2 :     return new OGRPoint(dfX, dfY);
     505                 : }
     506                 : 
     507                 : /************************************************************************/
     508                 : /*                        OGRESRIJSONReadLineString()                   */
     509                 : /************************************************************************/
     510                 : 
     511               2 : OGRLineString* OGRESRIJSONReadLineString( json_object* poObj)
     512                 : {
     513               2 :     CPLAssert( NULL != poObj );
     514                 : 
     515               2 :     OGRLineString* poLine = NULL;
     516                 :     
     517               2 :     json_object* poObjPaths = OGRGeoJSONFindMemberByName( poObj, "paths" );
     518               2 :     if( NULL == poObjPaths )
     519                 :     {
     520                 :         CPLError( CE_Failure, CPLE_AppDefined,
     521                 :             "Invalid LineString object. "
     522               0 :             "Missing \'paths\' member." );
     523               0 :         return NULL;
     524                 :     }
     525                 : 
     526               2 :     if( json_type_array != json_object_get_type( poObjPaths ) )
     527                 :     {
     528                 :         CPLError( CE_Failure, CPLE_AppDefined,
     529                 :             "Invalid LineString object. "
     530               0 :             "Invalid \'paths\' member." );
     531               0 :         return NULL;
     532                 :     }
     533                 :     
     534               2 :     poLine = new OGRLineString();
     535               2 :     const int nPaths = json_object_array_length( poObjPaths );
     536               4 :     for(int iPath = 0; iPath < nPaths; iPath ++)
     537                 :     {
     538               2 :         json_object* poObjPath = json_object_array_get_idx( poObjPaths, iPath );
     539               2 :         if ( poObjPath == NULL ||
     540                 :                 json_type_array != json_object_get_type( poObjPath ) )
     541                 :         {
     542               0 :             delete poLine;
     543                 :             CPLDebug( "ESRIJSON",
     544               0 :                     "LineString: got non-array object." );
     545               0 :             return NULL;
     546                 :         }
     547                 : 
     548               2 :         const int nPoints = json_object_array_length( poObjPath );
     549               6 :         for(int i = 0; i < nPoints; i++)
     550                 :         {
     551               4 :             json_object* poObjCoords = NULL;
     552                 : 
     553               4 :             poObjCoords = json_object_array_get_idx( poObjPath, i );
     554               4 :             if (poObjCoords == NULL)
     555                 :             {
     556               0 :                 delete poLine;
     557                 :                 CPLDebug( "ESRIJSON",
     558               0 :                         "LineString: got null object." );
     559               0 :                 return NULL;
     560                 :             }
     561               4 :             if( json_type_array != json_object_get_type( poObjCoords ) ||
     562                 :                 json_object_array_length( poObjCoords ) != 2 )
     563                 :             {
     564               0 :                 delete poLine;
     565                 :                 CPLDebug( "ESRIJSON",
     566               0 :                         "LineString: got non-array object." );
     567               0 :                 return NULL;
     568                 :             }
     569                 : 
     570                 :             json_object* poObjCoord;
     571                 :             int iType;
     572                 :             double dfX, dfY;
     573                 : 
     574                 :             // Read X coordinate
     575               4 :             poObjCoord = json_object_array_get_idx( poObjCoords, 0 );
     576               4 :             if (poObjCoord == NULL)
     577                 :             {
     578               0 :                 CPLDebug( "ESRIJSON", "LineString: got null object." );
     579               0 :                 delete poLine;
     580               0 :                 return NULL;
     581                 :             }
     582                 : 
     583               4 :             iType = json_object_get_type(poObjCoord);
     584               4 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     585                 :             {
     586                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     587                 :                         "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     588               0 :                         json_object_to_json_string(poObjCoord) );
     589               0 :                 delete poLine;
     590               0 :                 return NULL;
     591                 :             }
     592                 : 
     593               4 :             if (iType == json_type_double)
     594               0 :                 dfX = json_object_get_double( poObjCoord );
     595                 :             else
     596               4 :                 dfX = json_object_get_int( poObjCoord );
     597                 : 
     598                 :             // Read Y coordinate
     599               4 :             poObjCoord = json_object_array_get_idx( poObjCoords, 1 );
     600               4 :             if (poObjCoord == NULL)
     601                 :             {
     602               0 :                 CPLDebug( "ESRIJSON", "LineString: got null object." );
     603               0 :                 delete poLine;
     604               0 :                 return NULL;
     605                 :             }
     606                 : 
     607               4 :             iType = json_object_get_type(poObjCoord);
     608               4 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     609                 :             {
     610                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     611                 :                         "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     612               0 :                         json_object_to_json_string(poObjCoord) );
     613               0 :                 delete poLine;
     614               0 :                 return NULL;
     615                 :             }
     616                 : 
     617               4 :             if (iType == json_type_double)
     618               0 :                 dfY = json_object_get_double( poObjCoord );
     619                 :             else
     620               4 :                 dfY = json_object_get_int( poObjCoord );
     621                 : 
     622               4 :             poLine->addPoint( dfX, dfY );
     623                 :         }
     624                 :     }
     625                 : 
     626               2 :     return poLine;
     627                 : }
     628                 : 
     629                 : /************************************************************************/
     630                 : /*                          OGRESRIJSONReadPolygon()                    */
     631                 : /************************************************************************/
     632                 : 
     633               2 : OGRPolygon* OGRESRIJSONReadPolygon( json_object* poObj)
     634                 : {
     635               2 :     CPLAssert( NULL != poObj );
     636                 : 
     637               2 :     OGRPolygon* poPoly = NULL;
     638                 : 
     639               2 :     json_object* poObjRings = OGRGeoJSONFindMemberByName( poObj, "rings" );
     640               2 :     if( NULL == poObjRings )
     641                 :     {
     642                 :         CPLError( CE_Failure, CPLE_AppDefined,
     643                 :             "Invalid Polygon object. "
     644               0 :             "Missing \'rings\' member." );
     645               0 :         return NULL;
     646                 :     }
     647                 : 
     648               2 :     if( json_type_array != json_object_get_type( poObjRings ) )
     649                 :     {
     650                 :         CPLError( CE_Failure, CPLE_AppDefined,
     651                 :             "Invalid Polygon object. "
     652               0 :             "Invalid \'rings\' member." );
     653               0 :         return NULL;
     654                 :     }
     655                 : 
     656               2 :     poPoly = new OGRPolygon();
     657                 : 
     658               2 :     const int nRings = json_object_array_length( poObjRings );
     659               4 :     for(int iRing = 0; iRing < nRings; iRing ++)
     660                 :     {
     661               2 :         json_object* poObjRing = json_object_array_get_idx( poObjRings, iRing );
     662               2 :         if ( poObjRing == NULL ||
     663                 :                 json_type_array != json_object_get_type( poObjRing ) )
     664                 :         {
     665               0 :             delete poPoly;
     666                 :             CPLDebug( "ESRIJSON",
     667               0 :                     "Polygon: got non-array object." );
     668               0 :             return NULL;
     669                 :         }
     670                 : 
     671               2 :         OGRLinearRing* poLine = new OGRLinearRing();
     672               2 :         poPoly->addRingDirectly(poLine);
     673                 : 
     674               2 :         const int nPoints = json_object_array_length( poObjRing );
     675              12 :         for(int i = 0; i < nPoints; i++)
     676                 :         {
     677              10 :             json_object* poObjCoords = NULL;
     678                 : 
     679              10 :             poObjCoords = json_object_array_get_idx( poObjRing, i );
     680              10 :             if (poObjCoords == NULL)
     681                 :             {
     682               0 :                 delete poPoly;
     683                 :                 CPLDebug( "ESRIJSON",
     684               0 :                         "Polygon: got null object." );
     685               0 :                 return NULL;
     686                 :             }
     687              10 :             if( json_type_array != json_object_get_type( poObjCoords ) ||
     688                 :                 json_object_array_length( poObjCoords ) != 2 )
     689                 :             {
     690               0 :                 delete poPoly;
     691                 :                 CPLDebug( "ESRIJSON",
     692               0 :                         "Polygon: got non-array object." );
     693               0 :                 return NULL;
     694                 :             }
     695                 : 
     696                 :             json_object* poObjCoord;
     697                 :             int iType;
     698                 :             double dfX, dfY;
     699                 : 
     700                 :             // Read X coordinate
     701              10 :             poObjCoord = json_object_array_get_idx( poObjCoords, 0 );
     702              10 :             if (poObjCoord == NULL)
     703                 :             {
     704               0 :                 CPLDebug( "ESRIJSON", "Polygon: got null object." );
     705               0 :                 delete poPoly;
     706               0 :                 return NULL;
     707                 :             }
     708                 : 
     709              10 :             iType = json_object_get_type(poObjCoord);
     710              10 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     711                 :             {
     712                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     713                 :                         "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     714               0 :                         json_object_to_json_string(poObjCoord) );
     715               0 :                 delete poPoly;
     716               0 :                 return NULL;
     717                 :             }
     718                 : 
     719              10 :             if (iType == json_type_double)
     720               0 :                 dfX = json_object_get_double( poObjCoord );
     721                 :             else
     722              10 :                 dfX = json_object_get_int( poObjCoord );
     723                 : 
     724                 :             // Read Y coordinate
     725              10 :             poObjCoord = json_object_array_get_idx( poObjCoords, 1 );
     726              10 :             if (poObjCoord == NULL)
     727                 :             {
     728               0 :                 CPLDebug( "ESRIJSON", "Polygon: got null object." );
     729               0 :                 delete poPoly;
     730               0 :                 return NULL;
     731                 :             }
     732                 : 
     733              10 :             iType = json_object_get_type(poObjCoord);
     734              10 :             if ( (json_type_double != iType) && (json_type_int != iType) )
     735                 :             {
     736                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     737                 :                         "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     738               0 :                         json_object_to_json_string(poObjCoord) );
     739               0 :                 delete poPoly;
     740               0 :                 return NULL;
     741                 :             }
     742                 : 
     743              10 :             if (iType == json_type_double)
     744               0 :                 dfY = json_object_get_double( poObjCoord );
     745                 :             else
     746              10 :                 dfY = json_object_get_int( poObjCoord );
     747                 : 
     748              10 :             poLine->addPoint( dfX, dfY );
     749                 :         }
     750                 :     }
     751                 : 
     752               2 :     return poPoly;
     753                 : }
     754                 : 
     755                 : /************************************************************************/
     756                 : /*                        OGRESRIJSONReadMultiPoint()                   */
     757                 : /************************************************************************/
     758                 : 
     759               2 : OGRMultiPoint* OGRESRIJSONReadMultiPoint( json_object* poObj)
     760                 : {
     761               2 :     CPLAssert( NULL != poObj );
     762                 : 
     763               2 :     OGRMultiPoint* poMulti = NULL;
     764                 : 
     765               2 :     json_object* poObjPoints = OGRGeoJSONFindMemberByName( poObj, "points" );
     766               2 :     if( NULL == poObjPoints )
     767                 :     {
     768                 :         CPLError( CE_Failure, CPLE_AppDefined,
     769                 :             "Invalid LineString object. "
     770               0 :             "Missing \'points\' member." );
     771               0 :         return NULL;
     772                 :     }
     773                 : 
     774               2 :     if( json_type_array != json_object_get_type( poObjPoints ) )
     775                 :     {
     776                 :         CPLError( CE_Failure, CPLE_AppDefined,
     777                 :             "Invalid LineString object. "
     778               0 :             "Invalid \'points\' member." );
     779               0 :         return NULL;
     780                 :     }
     781                 : 
     782               2 :     poMulti = new OGRMultiPoint();
     783                 : 
     784               2 :     const int nPoints = json_object_array_length( poObjPoints );
     785              12 :     for(int i = 0; i < nPoints; i++)
     786                 :     {
     787               4 :         json_object* poObjCoords = NULL;
     788                 : 
     789               4 :         poObjCoords = json_object_array_get_idx( poObjPoints, i );
     790               4 :         if (poObjCoords == NULL)
     791                 :         {
     792               0 :             delete poMulti;
     793                 :             CPLDebug( "ESRIJSON",
     794               0 :                     "MultiPoint: got null object." );
     795               0 :             return NULL;
     796                 :         }
     797               4 :         if( json_type_array != json_object_get_type( poObjCoords ) ||
     798                 :             json_object_array_length( poObjCoords ) != 2 )
     799                 :         {
     800               0 :             delete poMulti;
     801                 :             CPLDebug( "ESRIJSON",
     802               0 :                     "MultiPoint: got non-array object." );
     803               0 :             return NULL;
     804                 :         }
     805                 : 
     806                 :         json_object* poObjCoord;
     807                 :         int iType;
     808                 :         double dfX, dfY;
     809                 : 
     810                 :         // Read X coordinate
     811               4 :         poObjCoord = json_object_array_get_idx( poObjCoords, 0 );
     812               4 :         if (poObjCoord == NULL)
     813                 :         {
     814               0 :             CPLDebug( "ESRIJSON", "MultiPoint: got null object." );
     815               0 :             delete poMulti;
     816               0 :             return NULL;
     817                 :         }
     818                 : 
     819               4 :         iType = json_object_get_type(poObjCoord);
     820               4 :         if ( (json_type_double != iType) && (json_type_int != iType) )
     821                 :         {
     822                 :             CPLError( CE_Failure, CPLE_AppDefined,
     823                 :                     "Invalid X coordinate. Type is not double or integer for \'%s\'.",
     824               0 :                     json_object_to_json_string(poObjCoord) );
     825               0 :             delete poMulti;
     826               0 :             return NULL;
     827                 :         }
     828                 : 
     829               4 :         if (iType == json_type_double)
     830               0 :             dfX = json_object_get_double( poObjCoord );
     831                 :         else
     832               4 :             dfX = json_object_get_int( poObjCoord );
     833                 : 
     834                 :         // Read Y coordinate
     835               4 :         poObjCoord = json_object_array_get_idx( poObjCoords, 1 );
     836               4 :         if (poObjCoord == NULL)
     837                 :         {
     838               0 :             CPLDebug( "ESRIJSON", "MultiPoint: got null object." );
     839               0 :             delete poMulti;
     840               0 :             return NULL;
     841                 :         }
     842                 : 
     843               4 :         iType = json_object_get_type(poObjCoord);
     844               4 :         if ( (json_type_double != iType) && (json_type_int != iType) )
     845                 :         {
     846                 :             CPLError( CE_Failure, CPLE_AppDefined,
     847                 :                     "Invalid Y coordinate. Type is not double or integer for \'%s\'.",
     848               0 :                     json_object_to_json_string(poObjCoord) );
     849               0 :             delete poMulti;
     850               0 :             return NULL;
     851                 :         }
     852                 : 
     853               4 :         if (iType == json_type_double)
     854               0 :             dfY = json_object_get_double( poObjCoord );
     855                 :         else
     856               4 :             dfY = json_object_get_int( poObjCoord );
     857                 : 
     858               4 :         poMulti->addGeometryDirectly( new OGRPoint(dfX, dfY) );
     859                 :     }
     860                 : 
     861               2 :     return poMulti;
     862                 : }
     863                 : 
     864                 : /************************************************************************/
     865                 : /*                    OGRESRIJSONReadSpatialReference()                 */
     866                 : /************************************************************************/
     867                 : 
     868               8 : OGRSpatialReference* OGRESRIJSONReadSpatialReference( json_object* poObj )
     869                 : {
     870                 : /* -------------------------------------------------------------------- */
     871                 : /*      Read spatial reference definition.                              */
     872                 : /* -------------------------------------------------------------------- */
     873               8 :     OGRSpatialReference* poSRS = NULL;
     874                 : 
     875               8 :     json_object* poObjSrs = OGRGeoJSONFindMemberByName( poObj, "spatialReference" );
     876               8 :     if( NULL != poObjSrs )
     877                 :     {
     878               4 :         json_object* poObjWkid = OGRGeoJSONFindMemberByName( poObjSrs, "wkid" );
     879               4 :         if (poObjWkid == NULL)
     880                 :         {
     881               0 :             json_object* poObjWkt = OGRGeoJSONFindMemberByName( poObjSrs, "wkt" );
     882               0 :             if (poObjWkt == NULL)
     883               0 :                 return NULL;
     884                 : 
     885               0 :             char* pszWKT = (char*) json_object_get_string( poObjWkt );
     886               0 :             poSRS = new OGRSpatialReference();
     887               0 :             if( OGRERR_NONE != poSRS->importFromWkt( &pszWKT ) ||
     888                 :                 poSRS->morphFromESRI() != OGRERR_NONE )
     889                 :             {
     890               0 :                 delete poSRS;
     891               0 :                 poSRS = NULL;
     892                 :             }
     893                 : 
     894               0 :             return poSRS;
     895                 :         }
     896                 : 
     897               4 :         int nEPSG = json_object_get_int( poObjWkid );
     898                 : 
     899               4 :         poSRS = new OGRSpatialReference();
     900               4 :         if( OGRERR_NONE != poSRS->importFromEPSG( nEPSG ) )
     901                 :         {
     902               0 :             delete poSRS;
     903               0 :             poSRS = NULL;
     904                 :         }
     905                 :     }
     906                 : 
     907               8 :     return poSRS;
     908                 : }

Generated by: LCOV version 1.7