OGRFeature *OGRHTFPolygonLayer::GetNextRawFeature() { OGRFeature* poFeature = new OGRFeature(poFeatureDefn); const char* pszLine; OGRLinearRing oLR; int bHastFirstCoord = FALSE; double dfFirstEasting = 0, dfFirstNorthing = 0; double dfIslandEasting = 0, dfIslandNorthing = 0; int bInIsland = FALSE; OGRPolygon* poPoly = new OGRPolygon(); while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL) { if (pszLine[0] == ';') { /* comment */ ; } else if (pszLine[0] == 0) { /* end of polygon is marked by a blank line */ break; } else if (strncmp(pszLine, "POLYGON DESCRIPTION: ", strlen("POLYGON DESCRIPTION: ")) == 0) { poFeature->SetField(0, pszLine + strlen("POLYGON DESCRIPTION: ")); } else if (strncmp(pszLine, "POLYGON IDENTIFIER: ", strlen("POLYGON IDENTIFIER: ")) == 0) { poFeature->SetField(1, pszLine + strlen("POLYGON IDENTIFIER: ")); } else if (strncmp(pszLine, "SEAFLOOR COVERAGE: ", strlen("SEAFLOOR COVERAGE:")) == 0) { const char* pszVal = pszLine + strlen("SEAFLOOR COVERAGE: "); if (*pszVal != '*') poFeature->SetField(2, pszVal); } else if (strncmp(pszLine, "POSITION ACCURACY: ", strlen("POSITION ACCURACY:")) == 0) { const char* pszVal = pszLine + strlen("POSITION ACCURACY: "); if (*pszVal != '*') poFeature->SetField(3, pszVal); } else if (strncmp(pszLine, "DEPTH ACCURACY: ", strlen("DEPTH ACCURACY:")) == 0) { const char* pszVal = pszLine + strlen("DEPTH ACCURACY: "); if (*pszVal != '*') poFeature->SetField(4, pszVal); } else if (strcmp(pszLine, "END OF POLYGON DATA") == 0) { bEOF = TRUE; break; } else { char** papszTokens = CSLTokenizeString(pszLine); if (CSLCount(papszTokens) == 4) { double dfEasting = atof(papszTokens[2]); double dfNorthing = atof(papszTokens[3]); if (!bHastFirstCoord) { bHastFirstCoord = TRUE; dfFirstEasting = dfEasting; dfFirstNorthing = dfNorthing; oLR.addPoint(dfEasting, dfNorthing); } else if (dfFirstEasting == dfEasting && dfFirstNorthing == dfNorthing) { if (!bInIsland) { oLR.addPoint(dfEasting, dfNorthing); poPoly->addRing(&oLR); oLR.empty(); bInIsland = TRUE; } } else if (bInIsland && oLR.getNumPoints() == 0) { dfIslandEasting = dfEasting; dfIslandNorthing = dfNorthing; oLR.addPoint(dfEasting, dfNorthing); } else if (bInIsland && dfIslandEasting == dfEasting && dfIslandNorthing == dfNorthing) { oLR.addPoint(dfEasting, dfNorthing); poPoly->addRing(&oLR); oLR.empty(); } else { oLR.addPoint(dfEasting, dfNorthing); } } CSLDestroy(papszTokens); } } if (pszLine == NULL) bEOF = TRUE; if (oLR.getNumPoints() >= 3) { oLR.closeRings(); poPoly->addRing(&oLR); } poPoly->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
/*! \brief Load geometry (polygon BUD/PAR layers) \return number of invalid features */ int VFKDataBlock::LoadGeometryPolygon() { long nInvalid; bool bIsPar, bNewRing, bFound; GUIntBig id, idOb; int nCount, nCountMax; int idxId, idxPar1, idxPar2, idxBud, idxOb, idxIdOb; VFKFeature *poFeature; VFKDataBlock *poDataBlockLines1, *poDataBlockLines2; VFKFeatureList poLineList; PointListArray poRingList; /* first is to be considered as exterior */ OGRLinearRing ogrRing; OGRPolygon ogrPolygon; idxPar1 = idxPar2 = idxBud = idxOb = idxIdOb = 0; nInvalid = 0; if (EQUAL (m_pszName, "PAR")) { poDataBlockLines1 = (VFKDataBlock *) m_poReader->GetDataBlock("HP"); poDataBlockLines2 = poDataBlockLines1; bIsPar = TRUE; } else { poDataBlockLines1 = (VFKDataBlock *) m_poReader->GetDataBlock("OB"); poDataBlockLines2 = (VFKDataBlock *) m_poReader->GetDataBlock("SBP"); bIsPar = FALSE; } if (NULL == poDataBlockLines1 || NULL == poDataBlockLines2) { CPLError(CE_Failure, CPLE_NotSupported, "Data block %s not found.\n", m_pszName); return nInvalid; } poDataBlockLines1->LoadGeometry(); poDataBlockLines2->LoadGeometry(); idxId = GetPropertyIndex("ID"); if (idxId < 0) { CPLError(CE_Failure, CPLE_NotSupported, "Corrupted data (%s).\n", m_pszName); return nInvalid; } if (bIsPar) { idxPar1 = poDataBlockLines1->GetPropertyIndex("PAR_ID_1"); idxPar2 = poDataBlockLines1->GetPropertyIndex("PAR_ID_2"); if (idxPar1 < 0 || idxPar2 < 0) { CPLError(CE_Failure, CPLE_NotSupported, "Corrupted data (%s).\n", m_pszName); return nInvalid; } } else { /* BUD */ idxIdOb = poDataBlockLines1->GetPropertyIndex("ID"); idxBud = poDataBlockLines1->GetPropertyIndex("BUD_ID"); idxOb = poDataBlockLines2->GetPropertyIndex("OB_ID"); if (idxIdOb < 0 || idxBud < 0 || idxOb < 0) { CPLError(CE_Failure, CPLE_NotSupported, "Corrupted data (%s).\n", m_pszName); return nInvalid; } } for (int i = 0; i < ((IVFKDataBlock *) this)->GetFeatureCount(); i++) { poFeature = (VFKFeature *) GetFeatureByIndex(i); id = strtoul(poFeature->GetProperty(idxId)->GetValueS(), NULL, 0); if (bIsPar) { poLineList = poDataBlockLines1->GetFeatures(idxPar1, idxPar2, id); } else { VFKFeature *poLineOb, *poLineSbp; std::vector<VFKFeature *> poLineListOb; poLineListOb = poDataBlockLines1->GetFeatures(idxBud, id); for (std::vector<VFKFeature *>::const_iterator iOb = poLineListOb.begin(), eOb = poLineListOb.end(); iOb != eOb; ++iOb) { poLineOb = (*iOb); idOb = strtoul(poLineOb->GetProperty(idxIdOb)->GetValueS(), NULL, 0); poLineSbp = poDataBlockLines2->GetFeature(idxOb, idOb); if (poLineSbp) poLineList.push_back(poLineSbp); } } if (poLineList.size() < 1) continue; /* clear */ ogrPolygon.empty(); poRingList.clear(); /* collect rings (points) */ bFound = FALSE; nCount = 0; nCountMax = poLineList.size() * 2; while (poLineList.size() > 0 && nCount < nCountMax) { bNewRing = !bFound ? TRUE : FALSE; bFound = FALSE; for (VFKFeatureList::iterator iHp = poLineList.begin(), eHp = poLineList.end(); iHp != eHp; ++iHp) { const OGRLineString *pLine = (OGRLineString *) (*iHp)->GetGeometry(); if (pLine && AppendLineToRing(&poRingList, pLine, bNewRing)) { bFound = TRUE; poLineList.erase(iHp); break; } } nCount++; } /* create rings */ for (PointListArray::const_iterator iRing = poRingList.begin(), eRing = poRingList.end(); iRing != eRing; ++iRing) { PointList *poList = *iRing; ogrRing.empty(); for (PointList::iterator iPoint = poList->begin(), ePoint = poList->end(); iPoint != ePoint; ++iPoint) { ogrRing.addPoint(&(*iPoint)); } ogrPolygon.addRing(&ogrRing); } /* set polygon */ ogrPolygon.setCoordinateDimension(2); /* force 2D */ if (!poFeature->SetGeometry(&ogrPolygon)) nInvalid++; } /* free ring list */ for (PointListArray::iterator iRing = poRingList.begin(), eRing = poRingList.end(); iRing != eRing; ++iRing) { delete (*iRing); *iRing = NULL; } poDataBlockLines1->ResetReading(); poDataBlockLines2->ResetReading(); return nInvalid; }