EVOLUTION-MANAGER
Edit File: ogrgeojsonwritelayer.cpp
/****************************************************************************** * $Id: ogrgeojsonwritelayer.cpp 27044 2014-03-16 23:41:27Z rouault $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implementation of OGRGeoJSONWriteLayer class (OGR GeoJSON Driver). * Author: Mateusz Loskot, mateusz@loskot.net * ****************************************************************************** * Copyright (c) 2011, Even Rouault <even dot rouault at mines-paris dot org> * Copyright (c) 2007, Mateusz Loskot * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include "ogr_geojson.h" #include "ogrgeojsonwriter.h" /* Remove annoying warnings Microsoft Visual C++ */ #if defined(_MSC_VER) # pragma warning(disable:4512) #endif /************************************************************************/ /* OGRGeoJSONWriteLayer() */ /************************************************************************/ OGRGeoJSONWriteLayer::OGRGeoJSONWriteLayer( const char* pszName, OGRwkbGeometryType eGType, char** papszOptions, OGRGeoJSONDataSource* poDS ) : poDS_( poDS ), poFeatureDefn_(new OGRFeatureDefn( pszName ) ), nOutCounter_( 0 ) { bWriteBBOX = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WRITE_BBOX", "FALSE")); bBBOX3D = FALSE; poFeatureDefn_->Reference(); poFeatureDefn_->SetGeomType( eGType ); nCoordPrecision = atoi(CSLFetchNameValueDef(papszOptions, "COORDINATE_PRECISION", "-1")); } /************************************************************************/ /* ~OGRGeoJSONWriteLayer() */ /************************************************************************/ OGRGeoJSONWriteLayer::~OGRGeoJSONWriteLayer() { VSILFILE* fp = poDS_->GetOutputFile(); VSIFPrintfL( fp, "\n]" ); if( bWriteBBOX && sEnvelopeLayer.IsInit() ) { json_object* poObjBBOX = json_object_new_array(); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelopeLayer.MinX, nCoordPrecision)); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelopeLayer.MinY, nCoordPrecision)); if( bBBOX3D ) json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelopeLayer.MinZ, nCoordPrecision)); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelopeLayer.MaxX, nCoordPrecision)); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelopeLayer.MaxY, nCoordPrecision)); if( bBBOX3D ) json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelopeLayer.MaxZ, nCoordPrecision)); const char* pszBBOX = json_object_to_json_string( poObjBBOX ); if( poDS_->GetFpOutputIsSeekable() ) { VSIFSeekL(fp, poDS_->GetBBOXInsertLocation(), SEEK_SET); if (strlen(pszBBOX) + 9 < SPACE_FOR_BBOX) VSIFPrintfL( fp, "\"bbox\": %s,", pszBBOX ); VSIFSeekL(fp, 0, SEEK_END); } else { VSIFPrintfL( fp, ",\n\"bbox\": %s", pszBBOX ); } json_object_put( poObjBBOX ); } VSIFPrintfL( fp, "\n}\n" ); if( NULL != poFeatureDefn_ ) { poFeatureDefn_->Release(); } } /************************************************************************/ /* CreateFeature() */ /************************************************************************/ OGRErr OGRGeoJSONWriteLayer::CreateFeature( OGRFeature* poFeature ) { VSILFILE* fp = poDS_->GetOutputFile(); if( NULL == poFeature ) { CPLDebug( "GeoJSON", "Feature is null" ); return OGRERR_INVALID_HANDLE; } json_object* poObj = OGRGeoJSONWriteFeature( poFeature, bWriteBBOX, nCoordPrecision ); CPLAssert( NULL != poObj ); if( nOutCounter_ > 0 ) { /* Separate "Feature" entries in "FeatureCollection" object. */ VSIFPrintfL( fp, ",\n" ); } VSIFPrintfL( fp, "%s", json_object_to_json_string( poObj ) ); json_object_put( poObj ); ++nOutCounter_; OGRGeometry* poGeometry = poFeature->GetGeometryRef(); if ( bWriteBBOX && !poGeometry->IsEmpty() ) { OGREnvelope3D sEnvelope; poGeometry->getEnvelope(&sEnvelope); if( poGeometry->getCoordinateDimension() == 3 ) bBBOX3D = TRUE; sEnvelopeLayer.Merge(sEnvelope); } return OGRERR_NONE; } /************************************************************************/ /* CreateField() */ /************************************************************************/ OGRErr OGRGeoJSONWriteLayer::CreateField(OGRFieldDefn* poField, int bApproxOK) { UNREFERENCED_PARAM(bApproxOK); for( int i = 0; i < poFeatureDefn_->GetFieldCount(); ++i ) { OGRFieldDefn* poDefn = poFeatureDefn_->GetFieldDefn(i); CPLAssert( NULL != poDefn ); if( EQUAL( poDefn->GetNameRef(), poField->GetNameRef() ) ) { CPLDebug( "GeoJSON", "Field '%s' already present in schema", poField->GetNameRef() ); // TODO - mloskot: Is this return code correct? return OGRERR_NONE; } } poFeatureDefn_->AddFieldDefn( poField ); return OGRERR_NONE; } /************************************************************************/ /* TestCapability() */ /************************************************************************/ int OGRGeoJSONWriteLayer::TestCapability( const char* pszCap ) { if (EQUAL(pszCap, OLCCreateField)) return TRUE; else if (EQUAL(pszCap, OLCSequentialWrite)) return TRUE; return FALSE; }