Changeset 13005

Show
Ignore:
Timestamp:
11/24/07 21:11:26 (9 months ago)
Author:
mloskot
Message:

Added support of sequential write to OGR GeoJSON driver.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/ogr/ogrsf_frmts/geojson/GNUmakefile

    r12634 r13005  
    1212        ogrgeojsonlayer.o \ 
    1313        ogrgeojsonutils.o \ 
    14         ogrgeojsonreader.o 
     14        ogrgeojsonreader.o \ 
     15        ogrgeojsonwriter.o 
    1516 
    1617CPPFLAGS        := -Ijsonc -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS) 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/makefile.vc

    r12634 r13005  
    1010        ogrgeojsonlayer.obj \ 
    1111        ogrgeojsonutils.obj \ 
    12         ogrgeojsonreader.obj 
    13          
     12        ogrgeojsonreader.obj \ 
     13        ogrgeojsonwriter.obj 
    1414 
    1515EXTRAFLAGS = -Ijsonc -I.. -I..\.. 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/ogr_geojson.h

    r12876 r13005  
    3434#include <vector> // used by OGRGeoJSONLayer 
    3535 
     36class OGRGeoJSONDataSource; 
     37 
    3638/************************************************************************/ 
    3739/*                           OGRGeoJSONLayer                            */ 
     
    4951                     OGRSpatialReference* poSRS, 
    5052                     OGRwkbGeometryType eGType, 
    51                      char** papszOptions); 
     53                     char** papszOptions, 
     54                     OGRGeoJSONDataSource* poDS ); 
    5255    ~OGRGeoJSONLayer(); 
    5356 
     
    6366    OGRFeature* GetFeature( long nFID ); 
    6467    OGRErr CreateFeature( OGRFeature* poFeature ); 
     68    OGRErr CreateField(OGRFieldDefn* poField, int bApproxOK); 
    6569    int TestCapability( const char* pszCap ); 
    6670    const char* GetFIDColumn(); 
     
    8084    FeaturesSeq seqFeatures_; 
    8185    FeaturesSeq::iterator iterCurrent_; 
     86 
     87    OGRGeoJSONDataSource* poDS_; 
    8288    OGRFeatureDefn* poFeatureDefn_; 
    8389    OGRSpatialReference* poSRS_; 
    8490    CPLString sFIDColumn_; 
     91    int nOutCounter_; 
    8592}; 
    8693 
     
    113120    // 
    114121    int Create( const char* pszName, char** papszOptions ); 
     122    FILE* GetOutputFile() const { return fpOut_; } 
    115123 
    116124    enum GeometryTranslation 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsondatasource.cpp

    r12876 r13005  
    5454{ 
    5555    Clear(); 
     56     
     57    if( NULL != fpOut_ ) 
     58    { 
     59        if ( fpOut_ != stdout ) 
     60            VSIFClose( fpOut_ ); 
     61    } 
    5662} 
    5763 
     
    179185{ 
    180186    OGRGeoJSONLayer* poLayer = NULL; 
    181     poLayer = new OGRGeoJSONLayer( pszName_, poSRS, eGType, papszOptions ); 
     187    poLayer = new OGRGeoJSONLayer( pszName_, poSRS, eGType, papszOptions, this ); 
    182188 
    183189/* -------------------------------------------------------------------- */ 
     
    192198     
    193199    papoLayers_[nLayers_++] = poLayer; 
     200 
     201    if( NULL != fpOut_ ) 
     202    { 
     203        VSIFPrintf( fpOut_, "{\n\"type\": \"FeatureCollection\",\n\"features\": [\n" ); 
     204    } 
    194205 
    195206    return poLayer; 
     
    218229/* -------------------------------------------------------------------- */ 
    219230    VSIStatBufL sStatBuf; 
    220     if( VSIStatL( pszName, &sStatBuf ) == 0
     231    if( 0 == VSIStatL( pszName, &sStatBuf )
    221232    { 
    222233        CPLError( CE_Failure, CPLE_NotSupported, 
     
    454465    { 
    455466        // TODO: Think about better name selection 
    456         poLayer = reader.ReadLayer( OGRGeoJSONLayer::DefaultName ); 
     467        poLayer = reader.ReadLayer( OGRGeoJSONLayer::DefaultName, this ); 
    457468    } 
    458469 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonlayer.cpp

    r12876 r13005  
    2828 ****************************************************************************/ 
    2929#include "ogr_geojson.h" 
     30#include "ogrgeojsonwriter.h" 
     31#include <json.h> // JSON-C 
    3032#include <algorithm> // for_each, find_if 
    3133 
     
    4547                                  OGRSpatialReference* poSRSIn, 
    4648                                  OGRwkbGeometryType eGType, 
    47                                   char** papszOptions ) 
    48     : poFeatureDefn_(new OGRFeatureDefn( pszName ) ), 
    49       poSRS_( NULL ) 
    50 
     49                                  char** papszOptions, 
     50                                  OGRGeoJSONDataSource* poDS ) 
     51    : poDS_( poDS ), poFeatureDefn_(new OGRFeatureDefn( pszName ) ), poSRS_( NULL ), nOutCounter_( 0 ) 
     52
     53    CPLAssert( NULL != poDS_ ); 
    5154    CPLAssert( NULL != poFeatureDefn_ ); 
    52  
     55     
    5356    poFeatureDefn_->Reference(); 
    5457    poFeatureDefn_->SetGeomType( eGType ); 
     
    6669OGRGeoJSONLayer::~OGRGeoJSONLayer() 
    6770{ 
     71    FILE* fp = poDS_->GetOutputFile(); 
     72    if( NULL != fp ) 
     73    { 
     74        VSIFPrintf( fp, "\n]\n}\n" ); 
     75    } 
     76 
    6877    std::for_each(seqFeatures_.begin(), seqFeatures_.end(), 
    6978                  OGRFeature::DestroyFeature); 
     
    234243OGRErr OGRGeoJSONLayer::CreateFeature( OGRFeature* poFeature ) 
    235244{ 
     245    FILE* fp = poDS_->GetOutputFile(); 
     246    if( NULL == poFeature ) 
     247    { 
     248        CPLDebug( "GeoJSON", "Target datasource file is invalid." ); 
     249        return CE_Failure; 
     250    } 
     251 
    236252    if( NULL == poFeature ) 
    237253    { 
     
    240256    } 
    241257 
    242     OGRFeature* poNewFeature = NULL; 
    243     poNewFeature = poFeature->Clone(); 
    244     seqFeatures_.push_back( poNewFeature ); 
     258    json_object* poObj = OGRGeoJSONWriteFeature( poFeature ); 
     259    CPLAssert( NULL != poObj ); 
     260 
     261    if( nOutCounter_ > 0 ) 
     262    { 
     263        /* Separate "Feature" entries in "FeatureCollection" object. */ 
     264        VSIFPrintf( fp, ",\n" ); 
     265    } 
     266    VSIFPrintf( fp, "%s\n", json_object_to_json_string( poObj ) ); 
     267 
     268    json_object_put( poObj ); 
     269 
     270    ++nOutCounter_; 
     271 
     272    return OGRERR_NONE; 
     273
     274 
     275OGRErr OGRGeoJSONLayer::CreateField(OGRFieldDefn* poField, int bApproxOK) 
     276
     277    for( int i = 0; i < poFeatureDefn_->GetFieldCount(); ++i ) 
     278    { 
     279        OGRFieldDefn* poDefn = poFeatureDefn_->GetFieldDefn(i); 
     280        CPLAssert( NULL != poDefn ); 
     281 
     282        if( EQUAL( poDefn->GetNameRef(), poField->GetNameRef() ) ) 
     283        { 
     284            CPLDebug( "GeoJSON", "Field '%s' already present in schema", 
     285                      poField->GetNameRef() ); 
     286             
     287            // TODO - mloskot: Is this return code correct? 
     288            return OGRERR_NONE; 
     289        } 
     290    } 
     291 
     292    poFeatureDefn_->AddFieldDefn( poField ); 
    245293 
    246294    return OGRERR_NONE; 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp

    r12948 r13005  
    9595/************************************************************************/ 
    9696 
    97 OGRGeoJSONLayer* OGRGeoJSONReader::ReadLayer( const char* pszName ) 
     97OGRGeoJSONLayer* OGRGeoJSONReader::ReadLayer( const char* pszName, 
     98                                              OGRGeoJSONDataSource* poDS ) 
    9899{ 
    99100    CPLAssert( NULL == poLayer_ ); 
     
    109110    poLayer_ = new OGRGeoJSONLayer( pszName, NULL, 
    110111                                   OGRGeoJSONLayer::DefaultGeometryType, 
    111                                    NULL ); 
     112                                   NULL, poDS ); 
    112113 
    113114    if( !GenerateLayerDefn() ) 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h

    r12948 r13005  
    8181/************************************************************************/ 
    8282 
     83class OGRGeoJSONDataSource; 
     84 
    8385class OGRGeoJSONReader 
    8486{ 
     
    9294 
    9395    OGRErr Parse( const char* pszText ); 
    94     OGRGeoJSONLayer* ReadLayer( const char* pszName ); 
     96    OGRGeoJSONLayer* ReadLayer( const char* pszName, OGRGeoJSONDataSource* poDS ); 
    9597 
    9698private: 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonutils.cpp

    r12663 r13005  
    3030#include <cpl_port.h> 
    3131#include <cpl_conv.h> 
     32#include <ogr_geometry.h> 
    3233#include <json.h> // JSON-C 
    3334 
     
    123124        return OFTString; /* null, object */ 
    124125} 
     126 
     127/************************************************************************/ 
     128/*                           OGRGeoJSONGetGeometryName()                */ 
     129/************************************************************************/ 
     130 
     131const char* OGRGeoJSONGetGeometryName( OGRGeometry const* poGeometry ) 
     132{ 
     133    CPLAssert( NULL != poGeometry ); 
     134     
     135    OGRwkbGeometryType eType = poGeometry->getGeometryType(); 
     136 
     137    if( wkbPoint == eType ) 
     138        return "Point"; 
     139    else if( wkbLineString == eType ) 
     140        return "LineString"; 
     141    else if( wkbPolygon == eType ) 
     142        return "Polygon"; 
     143    else if( wkbMultiPoint == eType ) 
     144        return "MultiPoint"; 
     145    else if( wkbMultiLineString == eType ) 
     146        return "MultiLineString"; 
     147    else if( wkbMultiPolygon == eType ) 
     148        return "MultiPolygon"; 
     149    else if( wkbGeometryCollection == eType ) 
     150        return "GeometryCollection"; 
     151    else 
     152        return "Unknown"; 
     153} 
  • trunk/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonutils.h

    r12634 r13005  
    3232#include <ogr_core.h> 
    3333#include <json.h> // JSON-C 
     34 
     35class OGRGeometry; 
    3436 
    3537/************************************************************************/ 
     
    8789OGRFieldType GeoJSONPropertyToFieldType( json_object* poObject ); 
    8890 
     91/************************************************************************/ 
     92/*                           OGRGeoJSONGetGeometryName                  */ 
     93/************************************************************************/ 
     94 
     95const char* OGRGeoJSONGetGeometryName( OGRGeometry const* poGeometry ); 
     96 
    8997#endif /* OGR_GEOJSONUTILS_H_INCLUDED */