Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Implementation of OGC Features and Geometries JSON (JSON-FG) 5 : * Author: Even Rouault <even.rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2023, Even Rouault <even.rouault at spatialys.com> 9 : * 10 : * Permission is hereby granted, free of charge, to any person obtaining a 11 : * copy of this software and associated documentation files (the "Software"), 12 : * to deal in the Software without restriction, including without limitation 13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 : * and/or sell copies of the Software, and to permit persons to whom the 15 : * Software is furnished to do so, subject to the following conditions: 16 : * 17 : * The above copyright notice and this permission notice shall be included 18 : * in all copies or substantial portions of the Software. 19 : * 20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 : * DEALINGS IN THE SOFTWARE. 27 : ****************************************************************************/ 28 : 29 : #include "ogr_jsonfg.h" 30 : 31 : /************************************************************************/ 32 : /* OGRJSONFGStreamingParserGetMaxObjectSize() */ 33 : /************************************************************************/ 34 : 35 283 : static size_t OGRJSONFGStreamingParserGetMaxObjectSize() 36 : { 37 : const double dfTmp = 38 283 : CPLAtof(CPLGetConfigOption("OGR_JSONFG_MAX_OBJ_SIZE", "200")); 39 283 : return dfTmp > 0 ? static_cast<size_t>(dfTmp * 1024 * 1024) : 0; 40 : } 41 : 42 : /************************************************************************/ 43 : /* OGRJSONFGStreamingParser() */ 44 : /************************************************************************/ 45 : 46 283 : OGRJSONFGStreamingParser::OGRJSONFGStreamingParser(OGRJSONFGReader &oReader, 47 283 : bool bFirstPass) 48 : : OGRJSONCollectionStreamingParser( 49 : bFirstPass, /*bStoreNativeData=*/false, 50 : OGRJSONFGStreamingParserGetMaxObjectSize()), 51 283 : m_oReader(oReader) 52 : { 53 283 : } 54 : 55 : /************************************************************************/ 56 : /* ~OGRJSONFGStreamingParser() */ 57 : /************************************************************************/ 58 : 59 : OGRJSONFGStreamingParser::~OGRJSONFGStreamingParser() = default; 60 : 61 : /************************************************************************/ 62 : /* OGRJSONFGStreamingParser::Clone() */ 63 : /************************************************************************/ 64 : 65 103 : std::unique_ptr<OGRJSONFGStreamingParser> OGRJSONFGStreamingParser::Clone() 66 : { 67 : auto poRet = 68 103 : std::make_unique<OGRJSONFGStreamingParser>(m_oReader, IsFirstPass()); 69 103 : poRet->m_osRequestedLayer = m_osRequestedLayer; 70 103 : return poRet; 71 : } 72 : 73 : /************************************************************************/ 74 : /* GetNextFeature() */ 75 : /************************************************************************/ 76 : 77 : std::pair<std::unique_ptr<OGRFeature>, OGRLayer *> 78 541 : OGRJSONFGStreamingParser::GetNextFeature() 79 : { 80 541 : if (m_nCurFeatureIdx < m_apoFeatures.size()) 81 : { 82 774 : auto poRet = std::move(m_apoFeatures[m_nCurFeatureIdx]); 83 387 : m_apoFeatures[m_nCurFeatureIdx].first = nullptr; 84 387 : m_apoFeatures[m_nCurFeatureIdx].second = nullptr; 85 387 : m_nCurFeatureIdx++; 86 387 : return poRet; 87 : } 88 154 : m_nCurFeatureIdx = 0; 89 154 : m_apoFeatures.clear(); 90 154 : return std::pair(nullptr, nullptr); 91 : } 92 : 93 : /************************************************************************/ 94 : /* AnalyzeFeature() */ 95 : /************************************************************************/ 96 : 97 703 : void OGRJSONFGStreamingParser::GotFeature(json_object *poObj, bool bFirstPass, 98 : const std::string & /*osJson*/) 99 : { 100 703 : if (bFirstPass) 101 : { 102 163 : m_oReader.GenerateLayerDefnFromFeature(poObj); 103 : } 104 : else 105 : { 106 540 : OGRJSONFGStreamedLayer *poStreamedLayer = nullptr; 107 540 : auto poFeat = m_oReader.ReadFeature(poObj, m_osRequestedLayer.c_str(), 108 1080 : nullptr, &poStreamedLayer); 109 540 : if (poFeat) 110 : { 111 537 : CPLAssert(poStreamedLayer); 112 : m_apoFeatures.emplace_back( 113 537 : std::pair(std::move(poFeat), poStreamedLayer)); 114 : } 115 : } 116 703 : } 117 : 118 : /************************************************************************/ 119 : /* TooComplex() */ 120 : /************************************************************************/ 121 : 122 0 : void OGRJSONFGStreamingParser::TooComplex() 123 : { 124 0 : if (!ExceptionOccurred()) 125 0 : EmitException("JSON object too complex/large. You may define the " 126 : "OGR_JSONFG_MAX_OBJ_SIZE configuration option to " 127 : "a value in megabytes to allow " 128 : "for larger features, or 0 to remove any size limit."); 129 0 : }