LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/geojson - ogresrijsonreader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 404 272 67.3 %
Date: 2012-04-28 Functions: 18 16 88.9 %

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

Generated by: LCOV version 1.7