/*! \brief Load geometry (point layers) \return number of invalid features */ int VFKDataBlockSQLite::LoadGeometryPoint() { int nInvalid, rowId, nGeometries; bool bSkipInvalid; /* long iFID; */ double x, y; CPLString osSQL; sqlite3_stmt *hStmt; VFKFeatureSQLite *poFeature; VFKReaderSQLite *poReader; nInvalid = nGeometries = 0; poReader = (VFKReaderSQLite*) m_poReader; if (LoadGeometryFromDB()) /* try to load geometry from DB */ return 0; bSkipInvalid = EQUAL(m_pszName, "OB") || EQUAL(m_pszName, "OP") || EQUAL(m_pszName, "OBBP"); osSQL.Printf("SELECT SOURADNICE_Y,SOURADNICE_X,%s,rowid FROM %s", FID_COLUMN, m_pszName); hStmt = poReader->PrepareStatement(osSQL.c_str()); if (poReader->IsSpatial()) poReader->ExecuteSQL("BEGIN"); while(poReader->ExecuteSQL(hStmt) == OGRERR_NONE) { /* read values */ x = -1.0 * sqlite3_column_double(hStmt, 0); /* S-JTSK coordinate system expected */ y = -1.0 * sqlite3_column_double(hStmt, 1); #ifdef DEBUG const long iFID = sqlite3_column_double(hStmt, 2); #endif rowId = sqlite3_column_int(hStmt, 3); poFeature = (VFKFeatureSQLite *) GetFeatureByIndex(rowId - 1); CPLAssert(NULL != poFeature && poFeature->GetFID() == iFID); /* create geometry */ OGRPoint pt(x, y); if (!poFeature->SetGeometry(&pt)) { nInvalid++; continue; } /* store also geometry in DB */ if (poReader->IsSpatial() && SaveGeometryToDB(&pt, rowId) != OGRERR_FAILURE) nGeometries++; } /* update number of geometries in VFK_DB_TABLE table */ UpdateVfkBlocks(nGeometries); if (poReader->IsSpatial()) poReader->ExecuteSQL("COMMIT"); return bSkipInvalid ? 0 : nInvalid; }
/*! \brief Load geometry (point layers) \return number of invalid features */ int VFKDataBlockDB::LoadGeometryPoint() { int nInvalid, rowId, nGeometries; bool bSkipInvalid; /* long iFID; */ double x, y; CPLString osSQL; VFKFeatureDB *poFeature; VFKReaderDB *poReader; nInvalid = nGeometries = 0; poReader = (VFKReaderDB*) m_poReader; if (LoadGeometryFromDB()) /* try to load geometry from DB */ return 0; bSkipInvalid = EQUAL(m_pszName, "OB") || EQUAL(m_pszName, "OP") || EQUAL(m_pszName, "OBBP"); osSQL.Printf("SELECT SOURADNICE_Y,SOURADNICE_X,%s,rowid FROM %s", FID_COLUMN, m_pszName); if (poReader->IsSpatial()) poReader->ExecuteSQL("BEGIN"); std::vector<VFKDbValue> record; record.push_back(VFKDbValue(DT_DOUBLE)); record.push_back(VFKDbValue(DT_DOUBLE)); record.push_back(VFKDbValue(DT_BIGINT)); record.push_back(VFKDbValue(DT_INT)); poReader->PrepareStatement(osSQL.c_str()); while(poReader->ExecuteSQL(record) == OGRERR_NONE && record.size() > 0) { /* read values */ x = -1.0 * (double) record[0]; /* S-JTSK coordinate system expected */ y = -1.0 * (double) record[1]; #ifdef DEBUG const GIntBig iFID = (GIntBig) record[2]; #endif rowId = (int) record[3]; poFeature = (VFKFeatureDB *) GetFeatureByIndex(rowId - 1); CPLAssert(NULL != poFeature && poFeature->GetFID() == iFID); /* create geometry */ OGRPoint pt(x, y); if (!poFeature->SetGeometry(&pt)) { nInvalid++; continue; } /* store also geometry in DB */ if (poReader->IsSpatial() && SaveGeometryToDB(&pt, rowId) != OGRERR_FAILURE) nGeometries++; } /* update number of geometries in VFK_DB_TABLE table */ UpdateVfkBlocks(nGeometries); if (poReader->IsSpatial()) poReader->ExecuteSQL("COMMIT"); return bSkipInvalid ? 0 : nInvalid; }
/*! \brief Load geometry (polygon BUD/PAR layers) \return number of invalid features */ int VFKDataBlockDB::LoadGeometryPolygon() { int nInvalidNoLines, nInvalidNoRings, nGeometries, nBridges; int rowId, nCount, nCountMax; size_t nLines; GIntBig iFID; bool bIsPar, bNewRing, bFound; CPLString osSQL; const char *vrColumn[2]; GUIntBig vrValue[2]; GUIntBig id, idOb; sqlite3_stmt *hStmt; VFKReaderDB *poReader; VFKDataBlockDB *poDataBlockLines1, *poDataBlockLines2; VFKFeatureDB *poFeature; VFKFeatureDBList poLineList; /* first is to be considered as exterior */ PointListArray poRingList; std::vector<OGRLinearRing *> poLinearRingList; OGRPolygon ogrPolygon; OGRLinearRing *poOgrRing; nInvalidNoLines = nInvalidNoRings = nGeometries = 0; poReader = (VFKReaderDB*) m_poReader; if (EQUAL (m_pszName, "PAR")) { poDataBlockLines1 = (VFKDataBlockDB *) m_poReader->GetDataBlock("HP"); poDataBlockLines2 = poDataBlockLines1; bIsPar = TRUE; } else { poDataBlockLines1 = (VFKDataBlockDB *) m_poReader->GetDataBlock("OB"); poDataBlockLines2 = (VFKDataBlockDB *) m_poReader->GetDataBlock("SBP"); bIsPar = FALSE; } if (NULL == poDataBlockLines1) { CPLError(CE_Warning, CPLE_FileIO, "Data block %s not found. Unable to build geometry for %s.", bIsPar ? "HP" : "OB", m_pszName); return -1; } if (NULL == poDataBlockLines2) { CPLError(CE_Warning, CPLE_FileIO, "Data block %s not found. Unable to build geometry for %s.", "SBP", m_pszName); return -1; } poDataBlockLines1->LoadGeometry(); poDataBlockLines2->LoadGeometry(); if (LoadGeometryFromDB()) /* try to load geometry from DB */ return 0; if (bIsPar) { vrColumn[0] = "PAR_ID_1"; vrColumn[1] = "PAR_ID_2"; } else { vrColumn[0] = "OB_ID"; vrColumn[1] = "PORADOVE_CISLO_BODU"; vrValue[1] = 1; } osSQL.Printf("SELECT ID,%s,rowid FROM %s", FID_COLUMN, m_pszName); if (poReader->IsSpatial()) poReader->ExecuteSQL("BEGIN"); std::vector<VFKDbValue> record; record.push_back(VFKDbValue(DT_BIGINT)); record.push_back(VFKDbValue(DT_BIGINT)); record.push_back(VFKDbValue(DT_INT)); poReader->PrepareStatement(osSQL.c_str()); while(poReader->ExecuteSQL(record) == OGRERR_NONE) { nBridges = 0; /* read values */ id = static_cast<GIntBig> (record[0]); iFID = static_cast<GIntBig> (record[1]); rowId = static_cast<int> (record[2]); poFeature = (VFKFeatureDB *) GetFeatureByIndex(rowId - 1); CPLAssert(NULL != poFeature && poFeature->GetFID() == iFID); if (bIsPar) { vrValue[0] = vrValue[1] = id; poLineList = poDataBlockLines1->GetFeatures(vrColumn, vrValue, 2); } else { VFKFeatureDB *poLineSbp; std::vector<VFKFeatureDB *> poLineListOb; sqlite3_stmt *hStmtOb; osSQL.Printf("SELECT ID FROM %s WHERE BUD_ID = " CPL_FRMT_GUIB, poDataBlockLines1->GetName(), id); if (poReader->IsSpatial()) { CPLString osColumn; osColumn.Printf(" AND %s IS NULL", GEOM_COLUMN); osSQL += osColumn; } std::vector<VFKDbValue> record1; record1.push_back(VFKDbValue(DT_BIGINT)); poReader->PrepareStatement(osSQL.c_str(), 1); while(poReader->ExecuteSQL(record, 1) == OGRERR_NONE) { idOb = static_cast<GIntBig> (record[0]); vrValue[0] = idOb; poLineSbp = poDataBlockLines2->GetFeature(vrColumn, vrValue, 2); if (poLineSbp) poLineList.push_back(poLineSbp); } } nLines = poLineList.size(); if (nLines < 1) { CPLDebug("OGR-VFK", "%s: unable to collect rings for polygon fid = %ld (no lines)", m_pszName, iFID); nInvalidNoLines++; continue; } /* clear */ ogrPolygon.empty(); poRingList.clear(); /* collect rings from lines */ bFound = FALSE; nCount = 0; nCountMax = static_cast<int>(nLines) * 2; while (poLineList.size() > 0 && nCount < nCountMax) { bNewRing = !bFound ? TRUE : FALSE; bFound = FALSE; int i = 1; for (VFKFeatureDBList::iterator iHp = poLineList.begin(), eHp = poLineList.end(); iHp != eHp; ++iHp, ++i) { const OGRLineString *pLine = (OGRLineString *) (*iHp)->GetGeometry(); if (pLine && AppendLineToRing(&poRingList, pLine, bNewRing)) { bFound = TRUE; poLineList.erase(iHp); break; } } nCount++; } CPLDebug("OGR-VFK", "%s: fid = %ld nlines = %d -> nrings = %d", m_pszName, iFID, (int)nLines, (int)poRingList.size()); if (poLineList.size() > 0) { CPLDebug("OGR-VFK", "%s: unable to collect rings for polygon fid = %ld", m_pszName, iFID); nInvalidNoRings++; continue; } /* build rings */ poLinearRingList.clear(); int i = 1; for (PointListArray::const_iterator iRing = poRingList.begin(), eRing = poRingList.end(); iRing != eRing; ++iRing) { OGRPoint *poPoint; PointList *poList = *iRing; poLinearRingList.push_back(new OGRLinearRing()); poOgrRing = poLinearRingList.back(); CPLAssert(NULL != poOgrRing); for (PointList::iterator iPoint = poList->begin(), ePoint = poList->end(); iPoint != ePoint; ++iPoint) { poPoint = &(*iPoint); poOgrRing->addPoint(poPoint); } i++; } /* find exterior ring */ if (poLinearRingList.size() > 1) { double dArea, dMaxArea; std::vector<OGRLinearRing *>::iterator exteriorRing; exteriorRing = poLinearRingList.begin(); dMaxArea = -1.; for (std::vector<OGRLinearRing *>::iterator iRing = poLinearRingList.begin(), eRing = poLinearRingList.end(); iRing != eRing; ++iRing) { poOgrRing = *iRing; if (!IsRingClosed(poOgrRing)) continue; /* skip unclosed rings */ dArea = poOgrRing->get_Area(); if (dArea > dMaxArea) { dMaxArea = dArea; exteriorRing = iRing; } } if (exteriorRing != poLinearRingList.begin()) { std::swap(*poLinearRingList.begin(), *exteriorRing); } } /* build polygon from rings */ for (std::vector<OGRLinearRing *>::iterator iRing = poLinearRingList.begin(), eRing = poLinearRingList.end(); iRing != eRing; ++iRing) { poOgrRing = *iRing; /* check if ring is closed */ if (IsRingClosed(poOgrRing)) { ogrPolygon.addRing(poOgrRing); } else { if (poOgrRing->getNumPoints() == 2) { CPLDebug("OGR-VFK", "%s: Polygon (fid = %ld) bridge removed", m_pszName, iFID); nBridges++; } else { CPLDebug("OGR-VFK", "%s: Polygon (fid = %ld) unclosed ring skipped", m_pszName, iFID); } } delete poOgrRing; *iRing = NULL; } /* set polygon */ ogrPolygon.setCoordinateDimension(2); /* force 2D */ if (ogrPolygon.getNumInteriorRings() + nBridges != (int) poLinearRingList.size() - 1 || !poFeature->SetGeometry(&ogrPolygon)) { nInvalidNoRings++; continue; } /* store also geometry in DB */ if (poReader->IsSpatial() && SaveGeometryToDB(&ogrPolygon, rowId) != OGRERR_FAILURE) nGeometries++; } /* free ring list */ for (PointListArray::iterator iRing = poRingList.begin(), eRing = poRingList.end(); iRing != eRing; ++iRing) { delete (*iRing); *iRing = NULL; } CPLDebug("OGR-VFK", "%s: nolines = %d norings = %d", m_pszName, nInvalidNoLines, nInvalidNoRings); /* update number of geometries in VFK_DB_TABLE table */ UpdateVfkBlocks(nGeometries); if (poReader->IsSpatial()) poReader->ExecuteSQL("COMMIT"); return nInvalidNoLines + nInvalidNoRings; }
/*! \brief Load geometry (linestring HP/DPM layer) \return number of invalid features */ int VFKDataBlockDB::LoadGeometryLineStringHP() { int nInvalid, nGeometries; int rowId; GIntBig iFID; CPLString osColumn, osSQL; const char *vrColumn[2]; GUIntBig vrValue[2]; sqlite3_stmt *hStmt; OGRGeometry *poOgrGeometry; VFKReaderDB *poReader; VFKDataBlockDB *poDataBlockLines; VFKFeatureDB *poFeature, *poLine; nInvalid = nGeometries = 0; poReader = (VFKReaderDB*) m_poReader; poDataBlockLines = (VFKDataBlockDB *) m_poReader->GetDataBlock("SBP"); if (NULL == poDataBlockLines) { CPLError(CE_Failure, CPLE_FileIO, "Data block %s not found.", m_pszName); return nInvalid; } poDataBlockLines->LoadGeometry(); if (LoadGeometryFromDB()) /* try to load geometry from DB */ return 0; osColumn.Printf("%s_ID", m_pszName); vrColumn[0] = osColumn.c_str(); vrColumn[1] = "PORADOVE_CISLO_BODU"; vrValue[1] = 1; /* reduce to first segment */ osSQL.Printf("SELECT ID,%s,rowid FROM %s", FID_COLUMN, m_pszName); /* TODO: handle points in DPM */ if (EQUAL(m_pszName, "DPM")) osSQL += " WHERE SOURADNICE_X IS NULL"; if (poReader->IsSpatial()) poReader->ExecuteSQL("BEGIN"); std::vector<VFKDbValue> record; record.push_back(VFKDbValue(DT_BIGINT)); record.push_back(VFKDbValue(DT_BIGINT)); record.push_back(VFKDbValue(DT_INT)); poReader->PrepareStatement(osSQL.c_str()); while(poReader->ExecuteSQL(record) == OGRERR_NONE) { /* read values */ vrValue[0] = static_cast<GIntBig> (record[0]); iFID = static_cast<GIntBig> (record[1]); rowId = static_cast<int> (record[2]); poFeature = (VFKFeatureDB *) GetFeatureByIndex(rowId - 1); CPLAssert(NULL != poFeature && poFeature->GetFID() == iFID); poLine = poDataBlockLines->GetFeature(vrColumn, vrValue, 2, TRUE); if (!poLine) { poOgrGeometry = NULL; } else { poOgrGeometry = poLine->GetGeometry(); } if (!poOgrGeometry || !poFeature->SetGeometry(poOgrGeometry)) { CPLDebug("OGR-VFK", "VFKDataBlockDB::LoadGeometryLineStringHP(): name=%s fid=%ld " "id=" CPL_FRMT_GUIB " -> %s geometry", m_pszName, iFID, vrValue[0], poOgrGeometry ? "invalid" : "empty"); nInvalid++; continue; } /* store also geometry in DB */ if (poReader->IsSpatial() && SaveGeometryToDB(poOgrGeometry, rowId) != OGRERR_FAILURE && poOgrGeometry) nGeometries++; } /* update number of geometries in VFK_DB_TABLE table */ UpdateVfkBlocks(nGeometries); if (poReader->IsSpatial()) poReader->ExecuteSQL("COMMIT"); return nInvalid; }
/*! \brief Load geometry (linestring SBP layer) \return number of invalid features */ int VFKDataBlockDB::LoadGeometryLineStringSBP() { int nInvalid, nGeometries, rowId, iIdx; CPLString szFType, szFTypeLine; GUIntBig id, ipcb; bool bValid; std::vector<int> rowIdFeat; CPLString osSQL; VFKReaderDB *poReader; VFKDataBlockDB *poDataBlockPoints; VFKFeatureDB *poFeature, *poPoint, *poLine; OGRLineString oOGRLine; nInvalid = nGeometries = 0; poReader = (VFKReaderDB*) m_poReader; poLine = NULL; poDataBlockPoints = (VFKDataBlockDB *) m_poReader->GetDataBlock("SOBR"); if (NULL == poDataBlockPoints) { CPLError(CE_Failure, CPLE_FileIO, "Data block %s not found.\n", m_pszName); return nInvalid; } poDataBlockPoints->LoadGeometry(); if (LoadGeometryFromDB()) /* try to load geometry from DB */ return 0; osSQL.Printf("UPDATE %s SET %s = -1", m_pszName, FID_COLUMN); poReader->ExecuteSQL(osSQL.c_str()); bValid = TRUE; iIdx = 0; for (int i = 0; i < 2; i++) { /* first collect linestrings related to HP, OB or DPM then collect rest of linestrings */ if (i == 0) osSQL.Printf("SELECT BP_ID,PORADOVE_CISLO_BODU,PARAMETRY_SPOJENI,_rowid_ FROM '%s' WHERE " "HP_ID IS NOT NULL OR OB_ID IS NOT NULL OR DPM_ID IS NOT NULL " "ORDER BY HP_ID,OB_ID,DPM_ID,PORADOVE_CISLO_BODU", m_pszName); else osSQL.Printf("SELECT BP_ID,PORADOVE_CISLO_BODU,PARAMETRY_SPOJENI,_rowid_ FROM '%s' WHERE " "OB_ID IS NULL AND HP_ID IS NULL AND DPM_ID IS NULL " "ORDER BY ID,PORADOVE_CISLO_BODU", m_pszName); if (poReader->IsSpatial()) poReader->ExecuteSQL("BEGIN"); std::vector<VFKDbValue> record; record.push_back(VFKDbValue(DT_BIGINT)); record.push_back(VFKDbValue(DT_BIGINT)); record.push_back(VFKDbValue(DT_TEXT)); record.push_back(VFKDbValue(DT_INT)); poReader->PrepareStatement(osSQL.c_str()); while(poReader->ExecuteSQL(record) == OGRERR_NONE) { // read values id = (GIntBig) record[0]; ipcb = (GIntBig) record[1]; szFType = (CPLString) record[2]; rowId = (int) record[3]; if (ipcb == 1) { poFeature = (VFKFeatureDB *) GetFeatureByIndex(iIdx); if( poFeature == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot retrieve feature %d", iIdx); break; } poFeature->SetRowId(rowId); /* set geometry & reset */ if (poLine && !SetGeometryLineString(poLine, &oOGRLine, bValid, szFTypeLine, rowIdFeat, nGeometries)) { nInvalid++; } bValid = TRUE; poLine = poFeature; szFTypeLine = szFType; iIdx++; } poPoint = (VFKFeatureDB *) poDataBlockPoints->GetFeature("ID", id); if (poPoint) { OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry(); if (pt) { oOGRLine.addPoint(pt); } else { CPLDebug("OGR-VFK", "Geometry (point ID = " CPL_FRMT_GUIB ") not valid", id); bValid = FALSE; } } else { CPLDebug("OGR-VFK", "Point ID = " CPL_FRMT_GUIB " not found (rowid = %d)", id, rowId); bValid = FALSE; } /* add vertex to the linestring */ rowIdFeat.push_back(rowId); } /* add last line */ if (poLine && !SetGeometryLineString(poLine, &oOGRLine, bValid, szFType.c_str(), rowIdFeat, nGeometries)) { nInvalid++; } poLine = NULL; if (poReader->IsSpatial()) poReader->ExecuteSQL("COMMIT"); } /* update number of geometries in VFK_DB_TABLE table */ UpdateVfkBlocks(nGeometries); return nInvalid; }
/*! \brief Load geometry (linestring HP/DPM layer) \return number of invalid features */ int VFKDataBlockSQLite::LoadGeometryLineStringHP() { int nInvalid = 0; VFKReaderSQLite *poReader = (VFKReaderSQLite*) m_poReader; VFKDataBlockSQLite *poDataBlockLines = (VFKDataBlockSQLite *) m_poReader->GetDataBlock("SBP"); if (NULL == poDataBlockLines) { CPLError(CE_Failure, CPLE_FileIO, "Data block %s not found.", m_pszName); return nInvalid; } poDataBlockLines->LoadGeometry(); if (LoadGeometryFromDB()) /* try to load geometry from DB */ return 0; CPLString osColumn; osColumn.Printf("%s_ID", m_pszName); const char *vrColumn[2] = { osColumn.c_str(), "PORADOVE_CISLO_BODU" }; GUIntBig vrValue[2] = { 0, 1 }; // Reduce to first segment. CPLString osSQL; osSQL.Printf("SELECT ID,%s,rowid FROM %s", FID_COLUMN, m_pszName); /* TODO: handle points in DPM */ if (EQUAL(m_pszName, "DPM")) osSQL += " WHERE SOURADNICE_X IS NULL"; sqlite3_stmt *hStmt = poReader->PrepareStatement(osSQL.c_str()); if (poReader->IsSpatial()) poReader->ExecuteSQL("BEGIN"); int nGeometries = 0; while( poReader->ExecuteSQL(hStmt) == OGRERR_NONE ) { /* read values */ vrValue[0] = sqlite3_column_int64(hStmt, 0); const long iFID = static_cast<long>(sqlite3_column_int64(hStmt, 1)); const int rowId = sqlite3_column_int(hStmt, 2); VFKFeatureSQLite *poFeature = (VFKFeatureSQLite *) GetFeatureByIndex(rowId - 1); CPLAssert(NULL != poFeature && poFeature->GetFID() == iFID); VFKFeatureSQLite *poLine = poDataBlockLines->GetFeature(vrColumn, vrValue, 2, TRUE); OGRGeometry *poOgrGeometry = NULL; if( !poLine ) { poOgrGeometry = NULL; } else { poOgrGeometry = poLine->GetGeometry(); } if (!poOgrGeometry || !poFeature->SetGeometry(poOgrGeometry)) { CPLDebug("OGR-VFK", "VFKDataBlockSQLite::LoadGeometryLineStringHP(): name=%s fid=%ld " "id=" CPL_FRMT_GUIB " -> %s geometry", m_pszName, iFID, vrValue[0], poOgrGeometry ? "invalid" : "empty"); nInvalid++; continue; } /* store also geometry in DB */ if (poReader->IsSpatial() && SaveGeometryToDB(poOgrGeometry, rowId) != OGRERR_FAILURE && poOgrGeometry) nGeometries++; } /* update number of geometries in VFK_DB_TABLE table */ UpdateVfkBlocks(nGeometries); if (poReader->IsSpatial()) poReader->ExecuteSQL("COMMIT"); return nInvalid; }