Ejemplo n.º 1
0
static void ParseMultiLineString(OGRMultiLineString* poMLS, json_object* poArcsObj,
                                 json_object* poArcsDB, ScalingParams* psParams)
{
    int nRings = json_object_array_length(poArcsObj);
    for(int i=0; i<nRings; i++)
    {
        OGRLineString* poLS = new OGRLineString();
        poMLS->addGeometryDirectly(poLS);

        json_object* poRing = json_object_array_get_idx(poArcsObj, i);
        if( poRing != NULL && json_type_array == json_object_get_type(poRing) )
        {
            ParseLineString(poLS, poRing, poArcsDB, psParams);
        }
    }
}
Ejemplo n.º 2
0
static void ParsePolygon(OGRPolygon* poPoly, json_object* poArcsObj,
                         json_object* poArcsDB, ScalingParams* psParams)
{
    int nRings = json_object_array_length(poArcsObj);
    for(int i=0; i<nRings; i++)
    {
        OGRLinearRing* poLR = new OGRLinearRing();
        poPoly->addRingDirectly(poLR);

        json_object* poRing = json_object_array_get_idx(poArcsObj, i);
        if( poRing != NULL && json_type_array == json_object_get_type(poRing) )
        {
            ParseLineString(poLR, poRing, poArcsDB, psParams);
        }
    }
}
Ejemplo n.º 3
0
static OGRGeometry* ParseKMLGeometry(/* const */ CPLXMLNode* psXML)
{
    OGRGeometry* poGeom = nullptr;
    const char* pszGeomType = psXML->pszValue;
    if (strcmp(pszGeomType, "Point") == 0)
    {
        const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr);
        if (pszCoordinates)
        {
            char** papszTokens = CSLTokenizeString2(pszCoordinates, ",", 0);
            if (CSLCount(papszTokens) == 2)
                poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]));
            else if (CSLCount(papszTokens) == 3)
                poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]),
                                      CPLAtof(papszTokens[2]));
            CSLDestroy(papszTokens);
        }
    }
    else if (strcmp(pszGeomType, "LineString") == 0)
    {
        const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr);
        if (pszCoordinates)
        {
            OGRLineString* poLS = new OGRLineString();
            ParseLineString(poLS, pszCoordinates);
            poGeom = poLS;
        }
    }
    else if (strcmp(pszGeomType, "Polygon") == 0)
    {
        OGRPolygon* poPoly = nullptr;
        CPLXMLNode* psOuterBoundary = CPLGetXMLNode(psXML, "outerBoundaryIs");
        if (psOuterBoundary)
        {
            CPLXMLNode* psLinearRing = CPLGetXMLNode(psOuterBoundary, "LinearRing");
            const char* pszCoordinates = CPLGetXMLValue(
                psLinearRing ? psLinearRing : psOuterBoundary, "coordinates", nullptr);
            if (pszCoordinates)
            {
                OGRLinearRing* poLS = new OGRLinearRing();
                ParseLineString(poLS, pszCoordinates);
                poPoly = new OGRPolygon();
                poPoly->addRingDirectly(poLS);
                poGeom = poPoly;
            }

            if (poPoly)
            {
                CPLXMLNode* psIter = psXML->psChild;
                while(psIter)
                {
                    if (psIter->eType == CXT_Element &&
                        strcmp(psIter->pszValue, "innerBoundaryIs") == 0)
                    {
                        psLinearRing = CPLGetXMLNode(psIter, "LinearRing");
                        pszCoordinates = CPLGetXMLValue(
                            psLinearRing ? psLinearRing : psIter, "coordinates", nullptr);
                        if (pszCoordinates)
                        {
                            OGRLinearRing* poLS = new OGRLinearRing();
                            ParseLineString(poLS, pszCoordinates);
                            poPoly->addRingDirectly(poLS);
                        }
                    }
                    psIter = psIter->psNext;
                }
            }
        }
    }
    else if (strcmp(pszGeomType, "MultiGeometry") == 0)
    {
        CPLXMLNode* psIter = nullptr;
        OGRwkbGeometryType eType = wkbUnknown;
        for(psIter = psXML->psChild; psIter; psIter = psIter->psNext)
        {
            if (psIter->eType == CXT_Element)
            {
                OGRwkbGeometryType eNewType = wkbUnknown;
                if (strcmp(psIter->pszValue, "Point") == 0)
                {
                    eNewType = wkbPoint;
                }
                else if (strcmp(psIter->pszValue, "LineString") == 0)
                {
                    eNewType = wkbLineString;
                }
                else if (strcmp(psIter->pszValue, "Polygon") == 0)
                {
                    eNewType = wkbPolygon;
                }
                else
                    break;
                if (eType == wkbUnknown)
                    eType = eNewType;
                else if (eType != eNewType)
                    break;
            }
        }
        OGRGeometryCollection* poColl = nullptr;
        if (psIter != nullptr)
            poColl = new OGRGeometryCollection();
        else if (eType == wkbPoint)
            poColl = new OGRMultiPoint();
        else if (eType == wkbLineString)
            poColl = new OGRMultiLineString();
        else if (eType == wkbPolygon)
            poColl = new OGRMultiPolygon();
        else {
            CPLAssert(false);
        }

        for(psIter = psXML->psChild; psIter; psIter = psIter->psNext)
        {
            if (psIter->eType == CXT_Element)
            {
                OGRGeometry* poSubGeom = ParseKMLGeometry(psIter);
                if (poSubGeom)
                    poColl->addGeometryDirectly(poSubGeom);
            }
        }

        poGeom = poColl;
    }

    return poGeom;
}
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;
}