Exemplo n.º 1
0
static void ParseObject(const char* pszId,
                        json_object* poObj, OGRGeoJSONLayer* poLayer,
                        json_object* poArcsDB, ScalingParams* psParams)
{
    json_object* poType = OGRGeoJSONFindMemberByName(poObj, "type");
    if( poType == NULL || json_object_get_type(poType) != json_type_string )
        return;
    const char* pszType = json_object_get_string(poType);

    json_object* poArcsObj = OGRGeoJSONFindMemberByName(poObj, "arcs");
    json_object* poCoordinatesObj = OGRGeoJSONFindMemberByName(poObj, "coordinates");
    if( strcmp(pszType, "Point") == 0 || strcmp(pszType, "MultiPoint") == 0 )
    {
        if( poCoordinatesObj == NULL || json_type_array != json_object_get_type(poCoordinatesObj) )
            return;
    }
    else
    {
        if( poArcsObj == NULL || json_type_array != json_object_get_type(poArcsObj) )
            return;
    }

    if( pszId == NULL )
    {
        json_object* poId = OGRGeoJSONFindMemberByName(poObj, "id");
        if( poId != NULL &&
            (json_type_string == json_object_get_type(poId) ||
             json_type_int == json_object_get_type(poId)) )
        {
            pszId = json_object_get_string(poId);
        }
    }

    OGRFeature* poFeature = new OGRFeature(poLayer->GetLayerDefn());
    if( pszId != NULL )
        poFeature->SetField("id", pszId);

    json_object* poProperties = OGRGeoJSONFindMemberByName(poObj, "properties");
    if( poProperties != NULL && json_type_object == json_object_get_type(poProperties) )
    {
        json_object_iter it;
        it.key = NULL;
        it.val = NULL;
        it.entry = NULL;
        json_object_object_foreachC( poProperties, it )
        {
            const int nField
                = poFeature->GetFieldIndex(it.key);
            OGRGeoJSONReaderSetField(poLayer, poFeature, nField, it.key, it.val, false, 0);
        }
    }
Exemplo n.º 2
0
bool OGRESRIJSONReader::GenerateLayerDefn()
{
    CPLAssert( nullptr != poGJObject_ );
    CPLAssert( nullptr != poLayer_->GetLayerDefn() );
    CPLAssert( 0 == poLayer_->GetLayerDefn()->GetFieldCount() );

    bool bSuccess = true;

/* -------------------------------------------------------------------- */
/*      Scan all features and generate layer definition.                */
/* -------------------------------------------------------------------- */
    json_object* poFields =
        OGRGeoJSONFindMemberByName( poGJObject_, "fields" );
    if( nullptr != poFields &&
        json_type_array == json_object_get_type( poFields ) )
    {
        const int nFeatures = json_object_array_length( poFields );
        for( int i = 0; i < nFeatures; ++i )
        {
            json_object* poField =
                json_object_array_get_idx( poFields, i );
            if( !ParseField( poField ) )
            {
                CPLDebug( "GeoJSON", "Create feature schema failure." );
                bSuccess = false;
            }
        }
    }
    else
    {
        poFields = OGRGeoJSONFindMemberByName(
            poGJObject_, "fieldAliases" );
        if( nullptr != poFields &&
            json_object_get_type(poFields) == json_type_object )
        {
            OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn();
            json_object_iter it;
            it.key = nullptr;
            it.val = nullptr;
            it.entry = nullptr;
            json_object_object_foreachC( poFields, it )
            {
                OGRFieldDefn fldDefn( it.key, OFTString );
                poDefn->AddFieldDefn( &fldDefn );
            }
        }
Exemplo n.º 3
0
bool OGRGeoJSONReader::GenerateFeatureDefn( json_object* poObj )
{
    OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn();
    CPLAssert( NULL != poDefn );

    bool bSuccess = false;

/* -------------------------------------------------------------------- */
/*      Read collection of properties.									*/
/* -------------------------------------------------------------------- */
    json_object* poObjProps = NULL;
    poObjProps = OGRGeoJSONFindMemberByName( poObj, "properties" );
    if( NULL != poObjProps &&
        json_object_get_type(poObjProps) == json_type_object )
    {
        if (bIsGeocouchSpatiallistFormat)
        {
            poObjProps = json_object_object_get(poObjProps, "properties");
            if( NULL == poObjProps ||
                json_object_get_type(poObjProps) != json_type_object )
            {
                return true;
            }
        }

        json_object_iter it;
        it.key = NULL;
        it.val = NULL;
        it.entry = NULL;
        json_object_object_foreachC( poObjProps, it )
        {
            int nFldIndex = poDefn->GetFieldIndex( it.key );
            if( -1 == nFldIndex )
            {
                /* Detect the special kind of GeoJSON output by a spatiallist of GeoCouch */
                /* such as http://gd.iriscouch.com/cphosm/_design/geo/_rewrite/data?bbox=12.53%2C55.73%2C12.54%2C55.73 */
                if (strcmp(it.key, "_id") == 0)
                    bFoundId = true;
                else if (bFoundId && strcmp(it.key, "_rev") == 0)
                    bFoundRev = true;
                else if (bFoundRev && strcmp(it.key, "type") == 0 &&
                         it.val != NULL && json_object_get_type(it.val) == json_type_string &&
                         strcmp(json_object_get_string(it.val), "Feature") == 0)
                    bFoundTypeFeature = true;
                else if (bFoundTypeFeature && strcmp(it.key, "properties") == 0 &&
                         it.val != NULL && json_object_get_type(it.val) == json_type_object)
                {
                    if (bFlattenGeocouchSpatiallistFormat < 0)
                        bFlattenGeocouchSpatiallistFormat = CSLTestBoolean(
                            CPLGetConfigOption("GEOJSON_FLATTEN_GEOCOUCH", "TRUE"));
                    if (bFlattenGeocouchSpatiallistFormat)
                    {
                        poDefn->DeleteFieldDefn(poDefn->GetFieldIndex("type"));
                        bIsGeocouchSpatiallistFormat = true;
                        return GenerateFeatureDefn(poObj);
                    }
                }

                OGRFieldDefn fldDefn( it.key,
                    GeoJSONPropertyToFieldType( it.val ) );
                poDefn->AddFieldDefn( &fldDefn );
            }
            else
            {
                OGRFieldDefn* poFDefn = poDefn->GetFieldDefn(nFldIndex);
                OGRFieldType eType = poFDefn->GetType();
                if( eType == OFTInteger )
                {
                    OGRFieldType eNewType = GeoJSONPropertyToFieldType( it.val );
                    if( eNewType == OFTReal )
                        poFDefn->SetType(eNewType);
                }
            }
        }

        bSuccess = true; // SUCCESS
    }
Exemplo n.º 4
0
bool OGRGeoJSONReader::GenerateLayerDefn()
{
    CPLAssert( NULL != poGJObject_ );
    CPLAssert( NULL != poLayer_->GetLayerDefn() );
    CPLAssert( 0 == poLayer_->GetLayerDefn()->GetFieldCount() );

    bool bSuccess = true;

    if( bAttributesSkip_ )
        return true;

/* -------------------------------------------------------------------- */
/*      Scan all features and generate layer definition.				*/
/* -------------------------------------------------------------------- */
    GeoJSONObject::Type objType = OGRGeoJSONGetType( poGJObject_ );
    if( GeoJSONObject::eFeature == objType )
    {
        bSuccess = GenerateFeatureDefn( poGJObject_ );
    }
    else if( GeoJSONObject::eFeatureCollection == objType )
    {
        json_object* poObjFeatures = NULL;
        poObjFeatures = OGRGeoJSONFindMemberByName( poGJObject_, "features" );
        if( NULL != poObjFeatures
            && json_type_array == json_object_get_type( poObjFeatures ) )
        {
            json_object* poObjFeature = NULL;
            const int nFeatures = json_object_array_length( poObjFeatures );
            for( int i = 0; i < nFeatures; ++i )
            {
                poObjFeature = json_object_array_get_idx( poObjFeatures, i );
                if( !GenerateFeatureDefn( poObjFeature ) )
                {
                    CPLDebug( "GeoJSON", "Create feature schema failure." );
                    bSuccess = false;
                }
            }
        }
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Invalid FeatureCollection object. "
                      "Missing \'features\' member." );
            bSuccess = false;
        }
    }

/* -------------------------------------------------------------------- */
/*      Validate and add FID column if necessary.                       */
/* -------------------------------------------------------------------- */
	OGRFeatureDefn* poLayerDefn = poLayer_->GetLayerDefn();
	CPLAssert( NULL != poLayerDefn );

	bool bHasFID = false;

	for( int i = 0; i < poLayerDefn->GetFieldCount(); ++i )
	{
		OGRFieldDefn* poDefn = poLayerDefn->GetFieldDefn(i);
		if( EQUAL( poDefn->GetNameRef(), OGRGeoJSONLayer::DefaultFIDColumn )
			&& OFTInteger == poDefn->GetType() )
		{
			poLayer_->SetFIDColumn( poDefn->GetNameRef() );
            bHasFID = true;
            break;
		}
	}

    // TODO - mloskot: This is wrong! We want to add only FID field if
    // found in source layer (by default name or by FID_PROPERTY= specifier,
    // the latter has to be implemented).
    /*
    if( !bHasFID )
    {
        OGRFieldDefn fldDefn( OGRGeoJSONLayer::DefaultFIDColumn, OFTInteger );
        poLayerDefn->AddFieldDefn( &fldDefn );
        poLayer_->SetFIDColumn( fldDefn.GetNameRef() );
    }
    */

    return bSuccess;
}
Exemplo n.º 5
0
OGRSpatialReference* OGRGeoJSONReadSpatialReference( json_object* poObj) {
    
/* -------------------------------------------------------------------- */
/*      Read spatial reference definition.                              */
/* -------------------------------------------------------------------- */
    OGRSpatialReference* poSRS = NULL;

    json_object* poObjSrs = OGRGeoJSONFindMemberByName( poObj, "crs" );
    if( NULL != poObjSrs )
    {
        json_object* poObjSrsType = OGRGeoJSONFindMemberByName( poObjSrs, "type" );
        if (poObjSrsType == NULL)
            return NULL;

        const char* pszSrsType = json_object_get_string( poObjSrsType );

        // TODO: Add URL and URN types support
        if( EQUALN( pszSrsType, "NAME", 4 ) )
        {
            json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" );
            if (poObjSrsProps == NULL)
                return NULL;

            json_object* poNameURL = OGRGeoJSONFindMemberByName( poObjSrsProps, "name" );
            if (poNameURL == NULL)
                return NULL;

            const char* pszName = json_object_get_string( poNameURL );

            poSRS = new OGRSpatialReference();
            if( OGRERR_NONE != poSRS->SetFromUserInput( pszName ) )
            {
                delete poSRS;
                poSRS = NULL;
            }
        }

        if( EQUALN( pszSrsType, "EPSG", 4 ) )
        {
            json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" );
            if (poObjSrsProps == NULL)
                return NULL;

            json_object* poObjCode = OGRGeoJSONFindMemberByName( poObjSrsProps, "code" );
            if (poObjCode == NULL)
                return NULL;

            int nEPSG = json_object_get_int( poObjCode );

            poSRS = new OGRSpatialReference();
            if( OGRERR_NONE != poSRS->importFromEPSG( nEPSG ) )
            {
                delete poSRS;
                poSRS = NULL;
            }
        }

        if( EQUALN( pszSrsType, "URL", 3 ) || EQUALN( pszSrsType, "LINK", 4 )  )
        {
            json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" );
            if (poObjSrsProps == NULL)
                return NULL;

            json_object* poObjURL = OGRGeoJSONFindMemberByName( poObjSrsProps, "url" );
            
            if (NULL == poObjURL) {
                poObjURL = OGRGeoJSONFindMemberByName( poObjSrsProps, "href" );
            }
            if (poObjURL == NULL)
                return NULL;

            const char* pszURL = json_object_get_string( poObjURL );

            poSRS = new OGRSpatialReference();
            if( OGRERR_NONE != poSRS->importFromUrl( pszURL ) )
            {
                delete poSRS;
                poSRS = NULL;

            }
        }


        if( EQUAL( pszSrsType, "OGC" ) )
        {
            json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" );
            if (poObjSrsProps == NULL)
                return NULL;

            json_object* poObjURN = OGRGeoJSONFindMemberByName( poObjSrsProps, "urn" );
            if (poObjURN == NULL)
                return NULL;

            poSRS = new OGRSpatialReference();
            if( OGRERR_NONE != poSRS->importFromURN( json_object_get_string(poObjURN) ) )
            {
                delete poSRS;
                poSRS = NULL;
            }
        }
    }
    
    return poSRS;
}
void OGRTopoJSONReader::ReadLayers( OGRGeoJSONDataSource* poDS )
{
    if( NULL == poGJObject_ )
    {
        CPLDebug( "TopoJSON",
                  "Missing parset TopoJSON data. Forgot to call Parse()?" );
        return;
    }

    ScalingParams sParams;
    sParams.dfScale0 = 1.0;
    sParams.dfScale1 = 1.0;
    sParams.dfTranslate0 = 0.0;
    sParams.dfTranslate1 = 0.0;
    json_object* poObjTransform = OGRGeoJSONFindMemberByName( poGJObject_, "transform" );
    if( NULL != poObjTransform && json_type_object == json_object_get_type( poObjTransform ) )
    {
        json_object* poObjScale = OGRGeoJSONFindMemberByName( poObjTransform, "scale" );
        if( NULL != poObjScale && json_type_array == json_object_get_type( poObjScale ) &&
            json_object_array_length( poObjScale ) == 2 )
        {
            json_object* poScale0 = json_object_array_get_idx(poObjScale, 0);
            json_object* poScale1 = json_object_array_get_idx(poObjScale, 1);
            if( poScale0 != NULL &&
                (json_object_get_type(poScale0) == json_type_double ||
                 json_object_get_type(poScale0) == json_type_int) &&
                poScale1 != NULL &&
                (json_object_get_type(poScale1) == json_type_double ||
                 json_object_get_type(poScale1) == json_type_int) )
            {
                sParams.dfScale0 = json_object_get_double(poScale0);
                sParams.dfScale1 = json_object_get_double(poScale1);
            }
        }

        json_object* poObjTranslate = OGRGeoJSONFindMemberByName( poObjTransform, "translate" );
        if( NULL != poObjTranslate && json_type_array == json_object_get_type( poObjTranslate ) &&
            json_object_array_length( poObjTranslate ) == 2 )
        {
            json_object* poTranslate0 = json_object_array_get_idx(poObjTranslate, 0);
            json_object* poTranslate1 = json_object_array_get_idx(poObjTranslate, 1);
            if( poTranslate0 != NULL &&
                (json_object_get_type(poTranslate0) == json_type_double ||
                 json_object_get_type(poTranslate0) == json_type_int) &&
                poTranslate1 != NULL &&
                (json_object_get_type(poTranslate1) == json_type_double ||
                 json_object_get_type(poTranslate1) == json_type_int) )
            {
                sParams.dfTranslate0 = json_object_get_double(poTranslate0);
                sParams.dfTranslate1 = json_object_get_double(poTranslate1);
            }
        }
    }

    json_object* poArcs = OGRGeoJSONFindMemberByName( poGJObject_, "arcs" );
    if( poArcs == NULL || json_type_array != json_object_get_type( poArcs ) )
        return;

    OGRGeoJSONLayer* poMainLayer = NULL;

    json_object* poObjects = OGRGeoJSONFindMemberByName( poGJObject_, "objects" );
    if( poObjects == NULL )
        return;

    if( json_type_object == json_object_get_type( poObjects ) )
    {
        json_object_iter it;
        it.key = NULL;
        it.val = NULL;
        it.entry = NULL;
        json_object_object_foreachC( poObjects, it )
        {
            json_object* poObj = it.val;
            ParseObjectMain(it.key, poObj, poDS, &poMainLayer, poArcs, &sParams);
        }
static void ParseObjectMain(const char* pszId, json_object* poObj,
                            OGRGeoJSONDataSource* poDS,
                            OGRGeoJSONLayer **ppoMainLayer,
                            json_object* poArcs,
                            ScalingParams* psParams)
{
    if( poObj != NULL && json_type_object == json_object_get_type( poObj ) )
    {
        json_object* poType = OGRGeoJSONFindMemberByName(poObj, "type");
        if( poType != NULL && json_type_string == json_object_get_type( poType ) )
        {
            const char* pszType = json_object_get_string(poType);
            if( strcmp(pszType, "GeometryCollection") == 0 )
            {
                json_object* poGeometries = OGRGeoJSONFindMemberByName(poObj, "geometries");
                if( poGeometries != NULL &&
                    json_type_array == json_object_get_type( poGeometries ) )
                {
                    if( pszId == NULL )
                    {
                        json_object* poId = OGRGeoJSONFindMemberByName(poObj, "id");
                        if( poId != NULL &&
                            (json_type_string == json_object_get_type(poId) ||
                            json_type_int == json_object_get_type(poId)) )
                        {
                            pszId = json_object_get_string(poId);
                        }
                    }

                    OGRGeoJSONLayer* poLayer = new OGRGeoJSONLayer(
                            pszId ? pszId : "TopoJSON", NULL,
                            wkbUnknown, poDS );
                    {
                        OGRFieldDefn fldDefn( "id", OFTString );
                        poLayer->GetLayerDefn()->AddFieldDefn( &fldDefn );
                    }
                    {
                        OGRFieldDefn fldDefn( "name", OFTString );
                        poLayer->GetLayerDefn()->AddFieldDefn( &fldDefn );
                    }

                    int nGeometries = json_object_array_length(poGeometries);
                    for(int i=0; i<nGeometries; i++)
                    {
                        json_object* poGeom =
                            json_object_array_get_idx(poGeometries, i);
                        if( poGeom != NULL &&
                            json_type_object == json_object_get_type( poGeom ) )
                        {
                            ParseObject(NULL, poGeom, poLayer, poArcs, psParams);
                        }
                    }

                    poDS->AddLayer(poLayer);
                }
            }
            else if( strcmp(pszType, "Point") == 0 ||
                     strcmp(pszType, "MultiPoint") == 0 ||
                     strcmp(pszType, "LineString") == 0 ||
                     strcmp(pszType, "MultiLineString") == 0 ||
                     strcmp(pszType, "Polygon") == 0 ||
                     strcmp(pszType, "MultiPolygon") == 0 )
            {
                if( *ppoMainLayer == NULL )
                {
                    *ppoMainLayer = new OGRGeoJSONLayer(
                        "TopoJSON", NULL, wkbUnknown, poDS );
                    {
                        OGRFieldDefn fldDefn( "id", OFTString );
                        (*ppoMainLayer)->GetLayerDefn()->AddFieldDefn( &fldDefn );
                    }
                    {
                        OGRFieldDefn fldDefn( "name", OFTString );
                        (*ppoMainLayer)->GetLayerDefn()->AddFieldDefn( &fldDefn );
                    }
                }
                ParseObject(pszId, poObj, *ppoMainLayer, poArcs, psParams);
            }
        }
    }
}
static void ParseObject(const char* pszId,
                        json_object* poObj, OGRGeoJSONLayer* poLayer,
                        json_object* poArcsDB, ScalingParams* psParams)
{
    json_object* poType = OGRGeoJSONFindMemberByName(poObj, "type");
    if( poType == NULL || json_object_get_type(poType) != json_type_string )
        return;
    const char* pszType = json_object_get_string(poType);

    json_object* poArcsObj = OGRGeoJSONFindMemberByName(poObj, "arcs");
    json_object* poCoordinatesObj = OGRGeoJSONFindMemberByName(poObj, "coordinates");
    if( strcmp(pszType, "Point") == 0 || strcmp(pszType, "MultiPoint") == 0 )
    {
        if( poCoordinatesObj == NULL || json_type_array != json_object_get_type(poCoordinatesObj) )
            return;
    }
    else
    {
        if( poArcsObj == NULL || json_type_array != json_object_get_type(poArcsObj) )
            return;
    }

    if( pszId == NULL )
    {
        json_object* poId = OGRGeoJSONFindMemberByName(poObj, "id");
        if( poId != NULL &&
            (json_type_string == json_object_get_type(poId) ||
             json_type_int == json_object_get_type(poId)) )
        {
            pszId = json_object_get_string(poId);
        }
    }

    OGRFeature* poFeature = new OGRFeature(poLayer->GetLayerDefn());
    if( pszId != NULL )
        poFeature->SetField("id", pszId);

    json_object* poProperties = OGRGeoJSONFindMemberByName(poObj, "properties");
    if( poProperties != NULL && json_type_object == json_object_get_type(poProperties) )
    {
        json_object* poName = OGRGeoJSONFindMemberByName(poProperties, "name");
        if( poName != NULL && json_type_string == json_object_get_type(poName) )
        {
            const char* pszName = json_object_get_string(poName);
            poFeature->SetField("name", pszName);
        }
    }

    OGRGeometry* poGeom = NULL;
    if( strcmp(pszType, "Point") == 0 )
    {
        double dfX = 0.0, dfY = 0.0;
        if( ParsePoint( poCoordinatesObj, &dfX, &dfY ) )
        {
            dfX = dfX * psParams->dfScale0 + psParams->dfTranslate0;
            dfY = dfY * psParams->dfScale1 + psParams->dfTranslate1;
            poGeom = new OGRPoint(dfX, dfY);
        }
        else
            poGeom = new OGRPoint();
    }
    else if( strcmp(pszType, "MultiPoint") == 0 )
    {
        OGRMultiPoint* poMP = new OGRMultiPoint();
        poGeom = poMP;
        int nTuples = json_object_array_length(poCoordinatesObj);
        for(int i=0; i<nTuples; i++)
        {
            json_object* poPair = json_object_array_get_idx(poCoordinatesObj, i);
            double dfX = 0.0, dfY = 0.0;
            if( ParsePoint( poPair, &dfX, &dfY ) )
            {
                dfX = dfX * psParams->dfScale0 + psParams->dfTranslate0;
                dfY = dfY * psParams->dfScale1 + psParams->dfTranslate1;
                poMP->addGeometryDirectly(new OGRPoint(dfX, dfY));
            }
        }
    }
    else if( strcmp(pszType, "LineString") == 0 )
    {
        OGRLineString* poLS = new OGRLineString();
        poGeom = poLS;
        ParseLineString(poLS, poArcsObj, poArcsDB, psParams);
    }
    else if( strcmp(pszType, "MultiLineString") == 0 )
    {
        OGRMultiLineString* poMLS = new OGRMultiLineString();
        poGeom = poMLS;
        ParseMultiLineString(poMLS, poArcsObj, poArcsDB, psParams);
    }
    else if( strcmp(pszType, "Polygon") == 0 )
    {
        OGRPolygon* poPoly = new OGRPolygon();
        poGeom = poPoly;
        ParsePolygon(poPoly, poArcsObj, poArcsDB, psParams);
    }
    else if( strcmp(pszType, "MultiPolygon") == 0 )
    {
        OGRMultiPolygon* poMultiPoly = new OGRMultiPolygon();
        poGeom = poMultiPoly;
        ParseMultiPolygon(poMultiPoly, poArcsObj, poArcsDB, psParams);
    }
    
    if( poGeom != NULL )
        poFeature->SetGeometryDirectly(poGeom);
    poLayer->AddFeature(poFeature);
    delete poFeature;
}