OGRPLScenesLayer::OGRPLScenesLayer(OGRPLScenesDataset* poDS,
                                   const char* pszName,
                                   const char* pszBaseURL,
                                   json_object* poObjCount10)
{
    this->poDS = poDS;
    osBaseURL = pszBaseURL;
    SetDescription(pszName);
    poFeatureDefn = new OGRFeatureDefn(pszName);
    poFeatureDefn->SetGeomType(wkbMultiPolygon);
    for(int i = 0; i < (int)sizeof(apsAttrs) / (int)sizeof(apsAttrs[0]); i++)
    {
        OGRFieldDefn oField(apsAttrs[i].pszName, apsAttrs[i].eType);
        poFeatureDefn->AddFieldDefn(&oField);
    }
    poFeatureDefn->Reference();
    poSRS = new OGRSpatialReference(SRS_WKT_WGS84);
    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
    bEOF = FALSE;
    nFeatureCount = -1;
    nNextFID = 1;
    poGeoJSONDS = NULL;
    poGeoJSONLayer = NULL;
    poMainFilter = NULL;
    nPageSize = atoi(CPLGetConfigOption("PLSCENES_PAGE_SIZE", "1000"));
    bStillInFirstPage = FALSE;
    bAcquiredAscending = -1;
    bFilterMustBeClientSideEvaluated = FALSE;
    ResetReading();
    
    if( poObjCount10 != NULL )
    {
        json_object* poCount = json_object_object_get(poObjCount10, "count");
        if( poCount != NULL )
            nFeatureCount = MAX(0, json_object_get_int64(poCount));

        OGRGeoJSONDataSource* poTmpDS = new OGRGeoJSONDataSource();
        OGRGeoJSONReader oReader;
        oReader.SetFlattenNestedAttributes(true, '.');
        oReader.ReadLayer( poTmpDS, "layer", poObjCount10 );
        OGRLayer* poTmpLayer = poTmpDS->GetLayer(0);
        if( poTmpLayer )
        {
            OGRFeatureDefn* poTmpFDefn = poTmpLayer->GetLayerDefn();
            std::vector<CPLString> aosNewFields;
            for(int i=0;i<poTmpFDefn->GetFieldCount();i++)
            {
                if( poFeatureDefn->GetFieldIndex(poTmpFDefn->GetFieldDefn(i)->GetNameRef()) < 0 )
                    aosNewFields.push_back(poTmpFDefn->GetFieldDefn(i)->GetNameRef());
            }
            std::sort(aosNewFields.begin(), aosNewFields.end(), OGRPLScenesLayerFieldNameComparator);
            for(int i=0;i<(int)aosNewFields.size();i++)
            {
                OGRFieldDefn oField(poTmpFDefn->GetFieldDefn(poTmpFDefn->GetFieldIndex(aosNewFields[i])));
                poFeatureDefn->AddFieldDefn(&oField);
            }
        }
        delete poTmpDS;
    }
}
GIntBig OGRPLScenesLayer::GetFeatureCount(int bForce)
{
    if( nFeatureCount < 0 )
    {
        CPLString osURL(BuildURL(1));
        if( bFilterMustBeClientSideEvaluated )
        {
            nFeatureCount = OGRLayer::GetFeatureCount(bForce);
        }
        else if( osURL.find('?') == std::string::npos )
        {
            /* Case of a "id = XXXXX" filter: we get directly a Feature, */
            /* not a FeatureCollection */
            GetNextPage();
        }
        else
        {
            nFeatureCount = 0;
            json_object* poObj = poDS->RunRequest(osURL);
            if( poObj != NULL )
            {
                json_object* poCount = json_object_object_get(poObj, "count");
                if( poCount != NULL )
                    nFeatureCount = MAX(0, json_object_get_int64(poCount));

                // Small optimization, if the feature count is actually 1
                // then we can fetch it as the full layer
                if( nFeatureCount == 1 )
                {
                    delete poGeoJSONDS;
                    // Parse the Feature/FeatureCollection with the GeoJSON reader
                    poGeoJSONDS = new OGRGeoJSONDataSource();
                    OGRGeoJSONReader oReader;
                    oReader.SetFlattenNestedAttributes(true, '.');
                    oReader.ReadLayer( poGeoJSONDS, "layer", poObj);
                    poGeoJSONLayer = poGeoJSONDS->GetLayer(0);
                    osNextURL = "";
                }
                json_object_put(poObj);
            }
        }
    }

    return nFeatureCount;
}
int OGRPLScenesLayer::GetNextPage()
{
    delete poGeoJSONDS;
    poGeoJSONLayer = NULL;
    poGeoJSONDS = NULL;

    if( osRequestURL.size() == 0 )
    {
        bEOF = TRUE;
        if( !bFilterMustBeClientSideEvaluated && nFeatureCount < 0 )
            nFeatureCount = 0;
        return FALSE;
    }
    // In the case of a "id = 'foo'" filter, a non existing resource 
    // will cause a 404 error, which we want to be silent
    int bQuiet404Error = ( osRequestURL.find('?') == std::string::npos );
    json_object* poObj = poDS->RunRequest(osRequestURL, bQuiet404Error);
    if( poObj == NULL )
    {
        bEOF = TRUE;
        if( !bFilterMustBeClientSideEvaluated && nFeatureCount < 0 )
            nFeatureCount = 0;
        return FALSE;
    }

    if( !bFilterMustBeClientSideEvaluated && nFeatureCount < 0 )
    {
        json_object* poType = json_object_object_get(poObj, "type");
        if( poType && json_object_get_type(poType) == json_type_string &&
            strcmp(json_object_get_string(poType), "Feature") == 0 )
        {
            nFeatureCount = 1;
        }
        else
        {
            json_object* poCount = json_object_object_get(poObj, "count");
            if( poCount == NULL )
            {
                json_object_put(poObj);
                bEOF = TRUE;
                nFeatureCount = 0;
                return FALSE;
            }
            nFeatureCount = MAX(0, json_object_get_int64(poCount));
        }
    }

    // Parse the Feature/FeatureCollection with the GeoJSON reader
    poGeoJSONDS = new OGRGeoJSONDataSource();
    OGRGeoJSONReader oReader;
    oReader.SetFlattenNestedAttributes(true, '.');
    oReader.ReadLayer( poGeoJSONDS, "layer", poObj);
    poGeoJSONLayer = poGeoJSONDS->GetLayer(0);
    
    // Get URL of next page
    osNextURL = "";
    if( poGeoJSONLayer )
    {
        json_object* poLinks = json_object_object_get(poObj, "links");
        if( poLinks && json_object_get_type(poLinks) == json_type_object )
        {
            json_object* poNext = json_object_object_get(poLinks, "next");
            if( poNext && json_object_get_type(poNext) == json_type_string )
            {
                osNextURL = json_object_get_string(poNext);
            }
        }
    }

    json_object_put(poObj);
    return poGeoJSONLayer != NULL;
}
Beispiel #4
0
void OGRGeoJSONDataSource::LoadLayers(char** papszOpenOptions)
{
    if( NULL == pszGeoData_ )
    {
        CPLError( CE_Failure, CPLE_ObjectNull,
                  "GeoJSON data buffer empty" );
        return;
    }
    
    const char* const apszPrefix[] = { "loadGeoJSON(", "jsonp(" };
    for(size_t iP = 0; iP < sizeof(apszPrefix) / sizeof(apszPrefix[0]); iP++ )
    {
        if( strncmp(pszGeoData_, apszPrefix[iP], strlen(apszPrefix[iP])) == 0 )
        {
            size_t nDataLen = strlen(pszGeoData_);
            memmove( pszGeoData_, pszGeoData_ + strlen(apszPrefix[iP]),
                    nDataLen - strlen(apszPrefix[iP]) );
            size_t i = nDataLen - strlen(apszPrefix[iP]);
            pszGeoData_[i] = '\0';
            while( i > 0 && pszGeoData_[i] != ')' )
            {
                i --;
            }
            pszGeoData_[i] = '\0';
        }
    }


    if ( !GeoJSONIsObject( pszGeoData_) )
    {
        CPLDebug( "GeoJSON", "No valid GeoJSON data found in source '%s'", pszName_ );
        return;
    }

    OGRErr err = OGRERR_NONE;

/* -------------------------------------------------------------------- */
/*      Is it ESRI Feature Service data ?                               */
/* -------------------------------------------------------------------- */
    if ( strstr(pszGeoData_, "esriGeometry") ||
         strstr(pszGeoData_, "esriFieldType") )
    {
        OGRESRIJSONReader reader;
        err = reader.Parse( pszGeoData_ );
        if( OGRERR_NONE == err )
        {
            json_object* poObj = reader.GetJSonObject();
            if( poObj && json_object_get_type(poObj) == json_type_object )
            {
                json_object* poExceededTransferLimit =
                    json_object_object_get(poObj, "exceededTransferLimit");
                if( poExceededTransferLimit && json_object_get_type(poExceededTransferLimit) == json_type_boolean )
                    bOtherPages_ = json_object_get_boolean(poExceededTransferLimit);
            }
            reader.ReadLayers( this );
        }
        return;
    }

/* -------------------------------------------------------------------- */
/*      Is it TopoJSON data ?                                           */
/* -------------------------------------------------------------------- */
    if ( strstr(pszGeoData_, "\"type\"") &&
         strstr(pszGeoData_, "\"Topology\"")  )
    {
        OGRTopoJSONReader reader;
        err = reader.Parse( pszGeoData_ );
        if( OGRERR_NONE == err )
        {
            reader.ReadLayers( this );
        }
        return;
    }

/* -------------------------------------------------------------------- */
/*      Configure GeoJSON format translator.                            */
/* -------------------------------------------------------------------- */
    OGRGeoJSONReader reader;

    if( eGeometryAsCollection == flTransGeom_ )
    {
        reader.SetPreserveGeometryType( false );
        CPLDebug( "GeoJSON", "Geometry as OGRGeometryCollection type." );
    }
    
    if( eAtributesSkip == flTransAttrs_ )
    {
        reader.SetSkipAttributes( true );
        CPLDebug( "GeoJSON", "Skip all attributes." );
    }
    
    reader.SetFlattenNestedAttributes(
        (bool)CSLFetchBoolean(papszOpenOptions, "FLATTEN_NESTED_ATTRIBUTES", FALSE),
        CSLFetchNameValueDef(papszOpenOptions, "NESTED_ATTRIBUTE_SEPARATOR", "_")[0]);

/* -------------------------------------------------------------------- */
/*      Parse GeoJSON and build valid OGRLayer instance.                */
/* -------------------------------------------------------------------- */
    err = reader.Parse( pszGeoData_ );
    if( OGRERR_NONE == err )
    {
        json_object* poObj = reader.GetJSonObject();
        if( poObj && json_object_get_type(poObj) == json_type_object )
        {
            json_object* poProperties = json_object_object_get(poObj, "properties");
            if( poProperties && json_object_get_type(poProperties) == json_type_object )
            {
                json_object* poExceededTransferLimit =
                    json_object_object_get(poProperties, "exceededTransferLimit");
                if( poExceededTransferLimit && json_object_get_type(poExceededTransferLimit) == json_type_boolean )
                    bOtherPages_ = json_object_get_boolean(poExceededTransferLimit);
            }
        }

        reader.ReadLayers( this );
    }

    return;
}
void OGRGeoJSONDataSource::LoadLayers()
{
    if( NULL == pszGeoData_ )
    {
        CPLError( CE_Failure, CPLE_ObjectNull,
                  "GeoJSON data buffer empty" );
        return;
    }
    
    const char* const apszPrefix[] = { "loadGeoJSON(", "jsonp(" };
    for(size_t iP = 0; iP < sizeof(apszPrefix) / sizeof(apszPrefix[0]); iP++ )
    {
        if( strncmp(pszGeoData_, apszPrefix[iP], strlen(apszPrefix[iP])) == 0 )
        {
            size_t nDataLen = strlen(pszGeoData_);
            memmove( pszGeoData_, pszGeoData_ + strlen(apszPrefix[iP]),
                    nDataLen - strlen(apszPrefix[iP]) );
            size_t i = nDataLen - strlen(apszPrefix[iP]);
            pszGeoData_[i] = '\0';
            while( i > 0 && pszGeoData_[i] != ')' )
            {
                i --;
            }
            pszGeoData_[i] = '\0';
        }
    }


    if ( !GeoJSONIsObject( pszGeoData_) )
    {
        CPLDebug( "GeoJSON", "No valid GeoJSON data found in source '%s'", pszName_ );
        return;
    }

    OGRErr err = OGRERR_NONE;

/* -------------------------------------------------------------------- */
/*      Is it ESRI Feature Service data ?                               */
/* -------------------------------------------------------------------- */
    if ( strstr(pszGeoData_, "esriGeometry") ||
         strstr(pszGeoData_, "esriFieldType") )
    {
        OGRESRIJSONReader reader;
        err = reader.Parse( pszGeoData_ );
        if( OGRERR_NONE == err )
        {
            reader.ReadLayers( this );
        }
        return;
    }

/* -------------------------------------------------------------------- */
/*      Is it TopoJSON data ?                                           */
/* -------------------------------------------------------------------- */
    if ( strstr(pszGeoData_, "\"type\"") &&
         strstr(pszGeoData_, "\"Topology\"")  )
    {
        OGRTopoJSONReader reader;
        err = reader.Parse( pszGeoData_ );
        if( OGRERR_NONE == err )
        {
            reader.ReadLayers( this );
        }
        return;
    }

/* -------------------------------------------------------------------- */
/*      Configure GeoJSON format translator.                            */
/* -------------------------------------------------------------------- */
    OGRGeoJSONReader reader;

    if( eGeometryAsCollection == flTransGeom_ )
    {
        reader.SetPreserveGeometryType( false );
        CPLDebug( "GeoJSON", "Geometry as OGRGeometryCollection type." );
    }
    
    if( eAtributesSkip == flTransAttrs_ )
    {
        reader.SetSkipAttributes( true );
        CPLDebug( "GeoJSON", "Skip all attributes." );
    }
    
/* -------------------------------------------------------------------- */
/*      Parse GeoJSON and build valid OGRLayer instance.                */
/* -------------------------------------------------------------------- */
    err = reader.Parse( pszGeoData_ );
    if( OGRERR_NONE == err )
    {
        reader.ReadLayers( this );
    }

    return;
}
Beispiel #6
0
OGRGeoJSONLayer* OGRGeoJSONDataSource::LoadLayer()
{
    if( NULL == pszGeoData_ )
    {
        CPLError( CE_Failure, CPLE_ObjectNull,
                  "GeoJSON data buffer empty" );
        return NULL;
    }

    if ( !GeoJSONIsObject( pszGeoData_) )
    {
        CPLDebug( "GeoJSON", "No valid GeoJSON data found in source '%s'", pszName_ );
        return NULL;
    }

    OGRErr err = OGRERR_NONE;
    OGRGeoJSONLayer* poLayer = NULL;

/* -------------------------------------------------------------------- */
/*      Is it ESRI Feature Service data ?                               */
/* -------------------------------------------------------------------- */
    if ( strstr(pszGeoData_, "esriGeometry") ||
         strstr(pszGeoData_, "esriFieldTypeOID") )
    {
        OGRESRIJSONReader reader;
        err = reader.Parse( pszGeoData_ );
        if( OGRERR_NONE == err )
        {
            // TODO: Think about better name selection
            poLayer = reader.ReadLayer( OGRGeoJSONLayer::DefaultName, this );
        }

        return poLayer;
    }
    
/* -------------------------------------------------------------------- */
/*      Configure GeoJSON format translator.                            */
/* -------------------------------------------------------------------- */
    OGRGeoJSONReader reader;

    if( eGeometryAsCollection == flTransGeom_ )
    {
        reader.SetPreserveGeometryType( false );
        CPLDebug( "GeoJSON", "Geometry as OGRGeometryCollection type." );
    }
    
    if( eAtributesSkip == flTransAttrs_ )
    {
        reader.SetSkipAttributes( true );
        CPLDebug( "GeoJSON", "Skip all attributes." );
    }
    
/* -------------------------------------------------------------------- */
/*      Parse GeoJSON and build valid OGRLayer instance.                */
/* -------------------------------------------------------------------- */
    err = reader.Parse( pszGeoData_ );
    if( OGRERR_NONE == err )
    {
        // TODO: Think about better name selection
        poLayer = reader.ReadLayer( OGRGeoJSONLayer::DefaultName, this );
    }

    return poLayer;
}