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); } } }
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); } } }
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; }