OGRGeometry *OGRGeometryFactory::forceToPolygon( OGRGeometry *poGeom ) { if( poGeom == NULL ) return NULL; if( wkbFlatten(poGeom->getGeometryType()) != wkbGeometryCollection || wkbFlatten(poGeom->getGeometryType()) != wkbMultiPolygon ) return poGeom; // build an aggregated polygon from all the polygon rings in the container. OGRPolygon *poPolygon = new OGRPolygon(); OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom; int iGeom; for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ ) { if( wkbFlatten(poGC->getGeometryRef(iGeom)->getGeometryType()) != wkbPolygon ) continue; OGRPolygon *poOldPoly = (OGRPolygon *) poGC->getGeometryRef(iGeom); int iRing; poPolygon->addRing( poOldPoly->getExteriorRing() ); for( iRing = 0; iRing < poOldPoly->getNumInteriorRings(); iRing++ ) poPolygon->addRing( poOldPoly->getInteriorRing( iRing ) ); } delete poGC; return poPolygon; }
OGRGeometry *OGRPolygon::clone() { OGRPolygon *poNewPolygon; poNewPolygon = new OGRPolygon; poNewPolygon->assignSpatialReference( getSpatialReference() ); for( int i = 0; i < nRingCount; i++ ) { poNewPolygon->addRing( papoRings[i] ); } return poNewPolygon; }
void OGRLayer::SetSpatialFilterRect( double dfMinX, double dfMinY, double dfMaxX, double dfMaxY ) { OGRLinearRing oRing; OGRPolygon oPoly; oRing.addPoint( dfMinX, dfMinY ); oRing.addPoint( dfMinX, dfMaxY ); oRing.addPoint( dfMaxX, dfMaxY ); oRing.addPoint( dfMaxX, dfMinY ); oRing.addPoint( dfMinX, dfMinY ); oPoly.addRing( &oRing ); SetSpatialFilter( &oPoly ); }
//-------------------------------------------------------------- OGRPolygon GeoData::MakeRect(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY) { OGRLinearRing oRing; OGRPolygon oPoly; oRing.addPoint(dfMinX, dfMinY); oRing.addPoint(dfMinX, dfMaxY); oRing.addPoint(dfMaxX, dfMaxY); oRing.addPoint(dfMaxX, dfMinY); oRing.addPoint(dfMinX, dfMinY); oPoly.addRing(&oRing); return oPoly; }
std::unique_ptr<OGRPoint> centroid(const osmium::Way& way) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRPolygon polygon; polygon.addRing(static_cast<OGRLinearRing*>(ogr_linestring.get())); std::unique_ptr<OGRPoint> centroid(new OGRPoint); int ret = polygon.Centroid(centroid.get()); if (ret != OGRERR_NONE) { std::cerr << "Couldn't calculate centroid of way = " << way.id() << ".\n"; osmium::geometry_error e(std::string("Couldn't calculate centroid of way = ") + std::to_string(way.id()) + std::string(".\n")); throw e; return nullptr; } else { return centroid; } return nullptr; }
void feed_way(const osmium::Way& way) { try { const char* building = way.tags().get_value_by_key("building"); if (building && way.is_closed()) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRFeature* feature = OGRFeature::CreateFeature(m_layer->GetLayerDefn()); OGRPolygon polygon; polygon.addRing(static_cast<OGRLinearRing*>(ogr_linestring.get())); feature->SetGeometry(static_cast<OGRGeometry*>(&polygon)); feature->SetField("way_id", static_cast<double>(way.id())); //TODO: node.id() is of type int64_t. is this ok? feature->SetField("lastchange", way.timestamp().to_iso().c_str()); create_feature(feature); } } catch (osmium::geom::geometry_error& e) { catch_geometry_error(e, way); } }
void MapExtruder::extrusion() { _sides = new OGRMultiPolygon(); int n = _map2d->getNumGeometries(); for(int i=0;i<n;i++) { OGRLinearRing* ring = ((OGRPolygon*)_map2d->getGeometryRef(i))->getExteriorRing(); ring->closeRings(); int nPoints = ring->getNumPoints(); for(int j=0;j<nPoints-1;j++) { OGRPolygon side; OGRLinearRing* ring_side = new OGRLinearRing(); OGRPoint p1,p4; ring->getPoint(j,&p1); ring->getPoint(j+1,&p4); OGRPoint p2(p1.getX(),p1.getY(),_height); OGRPoint p3(p4.getX(),p4.getY(),_height); ring_side->addPoint(&p1); ring_side->addPoint(&p2); ring_side->addPoint(&p3); ring_side->addPoint(&p4); ring_side->addPoint(&p1); side.addRing(ring_side); _sides->addGeometry(&side); } } }
void feed_way(const osmium::Way& way) { try { const char* building = way.tags().get_value_by_key("building"); if (building && way.is_closed()) { const char* street = way.tags().get_value_by_key("addr:street"); const char* houseno = way.tags().get_value_by_key("addr:housenumber"); if (street || houseno) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRFeature* feature = OGRFeature::CreateFeature(m_layer->GetLayerDefn()); OGRPolygon polygon; polygon.addRing(static_cast<OGRLinearRing*>(ogr_linestring.get())); feature->SetGeometry(static_cast<OGRGeometry*>(&polygon)); feature->SetField("way_id", static_cast<double>(way.id())); //TODO: node.id() is of type int64_t. is this ok? feature->SetField("lastchange", way.timestamp().to_iso().c_str()); const char* postcode = way.tags().get_value_by_key("addr:postcode"); const char* city = way.tags().get_value_by_key("addr:city"); const char* country = way.tags().get_value_by_key("addr:country"); const char* fulladdr = way.tags().get_value_by_key("addr:full"); const char* place = way.tags().get_value_by_key("addr:place"); if (street) { feature->SetField("street" , street); } if (houseno) { feature->SetField("houseno" , houseno); } if (postcode) { feature->SetField("postcode", postcode); } if (city) { feature->SetField("city", city); } if (country) { feature->SetField("country", country); } if (fulladdr) { feature->SetField("fulladdr", fulladdr); } if (place) { feature->SetField("place", place); } create_feature(feature); } } } catch (osmium::geometry_error& e) { catch_geometry_error(e, way); } }
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; }
//--------------------------------------------------------- bool COGR_DataSource::_Write_Geometry(CSG_Shape *pShape, OGRFeature *pFeature) { if( pShape && pFeature ) { int iPoint, iPart; TSG_Point sgPoint; OGRPoint Point; OGRMultiPoint Points; OGRLineString Line; OGRMultiLineString Lines; OGRLinearRing Ring; OGRPolygon Polygon; switch( pShape->Get_Type() ) { //------------------------------------------------- case SHAPE_TYPE_Point: sgPoint = pShape->Get_Point(0); Point.setX(sgPoint.x); Point.setY(sgPoint.y); return( pFeature->SetGeometry(&Point) == OGRERR_NONE ); //------------------------------------------------- case SHAPE_TYPE_Points: for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { for(iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { sgPoint = pShape->Get_Point(iPoint, iPart); Point.setX(sgPoint.x); Point.setY(sgPoint.y); Points.addGeometry(&Point); } } return( pFeature->SetGeometry(&Points) == OGRERR_NONE ); //------------------------------------------------- case SHAPE_TYPE_Line: if( pShape->Get_Part_Count() == 1 ) { _Write_Line(pShape, &Line, 0); return( pFeature->SetGeometry(&Line) == OGRERR_NONE ); } else { for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { if( _Write_Line(pShape, &Line, iPart) ) { Lines.addGeometry(&Line); } } return( pFeature->SetGeometry(&Lines) == OGRERR_NONE ); } //------------------------------------------------- case SHAPE_TYPE_Polygon: for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { if( _Write_Line(pShape, &Ring, iPart) ) { Polygon.addRing(&Ring); } } return( pFeature->SetGeometry(&Polygon) == OGRERR_NONE ); //------------------------------------------------- default: break; } } return( false ); }
bool Shape::save(const std::string& filename) { if (shapeType == -1) { std::cout << "Shape type is not set." << std::endl; return false; } if (shapeObjects.size() == 0) { std::cout << "No shape exists." << std::endl; return false; } const char *pszDriverName = "ESRI Shapefile"; GDALDriver *poDriver; GDALAllRegister(); poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName); if (poDriver == NULL) { printf("%s driver not available.\n", pszDriverName); return false; } GDALDataset *poDS; poDS = poDriver->Create(filename.c_str(), 0, 0, 0, GDT_Unknown, NULL); if (poDS == NULL) { printf("Creation of output file failed.\n"); return false; } OGRLayer *poLayer; if (shapeType == wkbPoint) { poLayer = poDS->CreateLayer("point_out", NULL, wkbPoint, NULL); } else if (shapeType == wkbLineString) { poLayer = poDS->CreateLayer("point_out", NULL, wkbLineString, NULL); } else if (shapeType == wkbPolygon) { poLayer = poDS->CreateLayer("point_out", NULL, wkbPolygon, NULL); } if (poLayer == NULL) { printf("Layer creation failed.\n"); return false; } for (auto it = shapeObjects[0].attributes.begin(); it != shapeObjects[0].attributes.end(); ++it) { OGRFieldDefn oField(it->first.c_str(), static_cast<OGRFieldType>(it->second.type)); if (it->second.type == OFTString) { oField.SetWidth(it->second.stringValue().size()); } if (poLayer->CreateField(&oField) != OGRERR_NONE) { printf("Creating Name field failed.\n"); return false; } } for (int i = 0; i < shapeObjects.size(); ++i) { if (shapeObjects[i].parts.size() == 0) continue; OGRFeature *poFeature; poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn()); // 属性をセット for (auto it = shapeObjects[i].attributes.begin(); it != shapeObjects[i].attributes.end(); ++it) { poFeature->SetField(it->first.c_str(), it->second.stringValue().c_str()); } // ã‚¸ã‚ªãƒ¡ãƒˆãƒªæƒ…å ±ã‚’ã‚»ãƒƒãƒˆ if (shapeType == wkbPoint) { OGRPoint point; point.setX(shapeObjects[i].parts[0].points[0].x); point.setY(shapeObjects[i].parts[0].points[0].y); point.setZ(shapeObjects[i].parts[0].points[0].z); poFeature->SetGeometry(&point); } else if (shapeType == wkbLineString) { OGRLineString lineString; for (int k = 0; k < shapeObjects[i].parts[0].points.size(); ++k) { lineString.addPoint(shapeObjects[i].parts[0].points[k].x, shapeObjects[i].parts[0].points[k].y, shapeObjects[i].parts[0].points[k].z); } poFeature->SetGeometry(&lineString); } else if (shapeType == wkbPolygon) { OGRPolygon polygon; for (int j = 0; j < shapeObjects[i].parts.size(); ++j) { OGRLinearRing linearRing; for (int k = 0; k < shapeObjects[i].parts[j].points.size(); ++k) { linearRing.addPoint(shapeObjects[i].parts[j].points[k].x, shapeObjects[i].parts[j].points[k].y, shapeObjects[i].parts[j].points[k].z); } polygon.addRing(&linearRing); } poFeature->SetGeometry(&polygon); } if (poLayer->CreateFeature(poFeature) != OGRERR_NONE) { printf("Failed to create feature in shapefile.\n"); return false; } OGRFeature::DestroyFeature(poFeature); } GDALClose(poDS); return true; }
OGRMultiPolygon* Building::extrude_box() const { OGRMultiPolygon* block = new OGRMultiPolygon; //extrude roof OGRPolygon roof; { roof.addRing(_footprint->getExteriorRing()); OGRLinearRing* ring = roof.getExteriorRing(); for(int i=0; i<ring->getNumPoints(); i++) ring->setPoint(i,ring->getX(i),ring->getY(i),_height); } if(int n = _footprint->getNumInteriorRings()) { for (int j=0; j<n; j++) { roof.addRing(_footprint->getInteriorRing(j)); OGRLinearRing* ring = roof.getInteriorRing(j); for(int i=0; i<ring->getNumPoints(); i++) ring->setPoint(i,ring->getX(i),ring->getY(i),_height); } } block->addGeometry(&roof); //extrude exter walls OGRLinearRing* ringEx = _footprint->getExteriorRing(); for(int i=0; i<ringEx->getNumPoints()-1; i++) { OGRPolygon wall; OGRLinearRing ring; ring.addPoint(ringEx->getX(i),ringEx->getY(i),0); ring.addPoint(ringEx->getX(i+1),ringEx->getY(i+1),0); ring.addPoint(ringEx->getX(i+1),ringEx->getY(i+1),_height); ring.addPoint(ringEx->getX(i),ringEx->getY(i),_height); ring.addPoint(ringEx->getX(i),ringEx->getY(i),0); wall.addRing(&ring); block->addGeometry(&wall); } //extrude inner walls if exist if(int n = _footprint->getNumInteriorRings()) { for (int i=0; i<n; i++) { OGRLinearRing* ringIn = _footprint->getInteriorRing(i); for(int j=0; j<ringIn->getNumPoints()-1; j++) { OGRPolygon wall; OGRLinearRing ring; ring.addPoint(ringIn->getX(j),ringIn->getY(j),0); ring.addPoint(ringIn->getX(j+1),ringIn->getY(j+1),0); ring.addPoint(ringIn->getX(j+1),ringIn->getY(j+1),_height); ring.addPoint(ringIn->getX(j),ringIn->getY(j),_height); ring.addPoint(ringIn->getX(j),ringIn->getY(j),0); wall.addRing(&ring); block->addGeometry(&wall); } } } return block; }
void CDlg_GISDataExchange::ExportToGISFile(LPCTSTR lpszCSVFileName,LPCTSTR lpszShapeFileName, CString GISTypeString ) { #ifndef _WIN64 m_MessageList.ResetContent (); CWaitCursor wait; CCSVParser parser; int i= 0; // open csv file if (parser.OpenCSVFile(lpszCSVFileName)) { CString message_str; OGRSFDriver *poDriver; OGRRegisterAll(); poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(GISTypeString ); if( poDriver == NULL ) { message_str.Format ( "%s driver not available.", GISTypeString ); m_MessageList.AddString (message_str); return; } OGRDataSource *poDS; poDS = poDriver->CreateDataSource(lpszShapeFileName, NULL ); if( poDS == NULL ) { message_str.Format ( "Creation of GIS output file %s failed.\nPlease do not overwrite the exiting file and please select a new file name.", lpszShapeFileName ); m_MessageList.AddString (message_str); return; } ///// export to link layer // link layer OGRLayer *poLayer; poLayer = poDS->CreateLayer( "link", NULL, wkbLineString, NULL ); if( poLayer == NULL ) { m_MessageList.AddString ("link Layer creation failed"); return; } vector<string> HeaderVector = parser.GetHeaderVector(); std::vector <CString> LongFieldVector; for(unsigned int i = 0; i < HeaderVector.size(); i++) { if(HeaderVector[i].find ("geometry") != string::npos|| HeaderVector[i].find ("name") != string::npos || HeaderVector[i].find ("code") != string::npos) { OGRFieldDefn oField (HeaderVector[i].c_str (), OFTString); CString str; if( poLayer->CreateField( &oField ) != OGRERR_NONE ) { str.Format("Creating field %s failed", oField.GetNameRef()); m_MessageList.AddString (str); return; } }else { CString field_string = HeaderVector[i].c_str (); OGRFieldDefn oField (field_string, OFTReal); CString str; if( poLayer->CreateField( &oField ) != OGRERR_NONE ) { str.Format("Creating field %s failed", oField.GetNameRef()); m_MessageList.AddString (str); return; } } if(HeaderVector[i].size()>=11) { LongFieldVector.push_back (HeaderVector[i].c_str ()); } } message_str.Format ("%d fields have been created.",HeaderVector.size()); m_MessageList.AddString (message_str); if(LongFieldVector.size() >=1) { message_str.Format("Warning: Arc GIS file only supports field names with not more than 10 characters.\nThe following fields have long field names. "); m_MessageList.AddString (message_str); for(unsigned l = 0; l< LongFieldVector.size(); l++) { message_str.Format ("%s",LongFieldVector[l]); m_MessageList.AddString (message_str); } } int count = 0 ; while(parser.ReadRecord()) { //create feature OGRFeature *poFeature; poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() ); //step 1: write all fields except geometry for(unsigned int i = 0; i < HeaderVector.size(); i++) { if(HeaderVector[i]!="geometry") { if(HeaderVector[i].find ("name") != string::npos || HeaderVector[i].find ("code") != string::npos) { std::string str_value; parser.GetValueByFieldName(HeaderVector[i],str_value); // TRACE("field: %s, value = %s\n",HeaderVector[i].c_str (),str_value.c_str ()); poFeature->SetField(i,str_value.c_str ()); }else { double value = 0; parser.GetValueByFieldName(HeaderVector[i],value); // TRACE("field: %s, value = %f\n",HeaderVector[i].c_str (),value); CString field_name = HeaderVector[i].c_str (); poFeature->SetField(i,value); } } } string geo_string; std::vector<CCoordinate> CoordinateVector; if(parser.GetValueByFieldName("geometry",geo_string)) { // overwrite when the field "geometry" exists CGeometry geometry(geo_string); CoordinateVector = geometry.GetCoordinateList(); if( m_GIS_data_type == GIS_Point_Type && CoordinateVector.size ()==1) { OGRPoint pt; pt.setX( CoordinateVector[0].X ); pt.setY( CoordinateVector[0].Y); poFeature->SetGeometry( &pt ); } if( m_GIS_data_type == GIS_Line_Type) { OGRLineString line; for(unsigned int si = 0; si< CoordinateVector.size(); si++) { line.addPoint (CoordinateVector[si].X , CoordinateVector[si].Y); } poFeature->SetGeometry( &line ); } if( m_GIS_data_type == GIS_Polygon_Type) { OGRPolygon polygon; OGRLinearRing ring; for(unsigned int si = 0; si< CoordinateVector.size(); si++) { ring.addPoint (CoordinateVector[si].X , CoordinateVector[si].Y,1); } polygon.addRing(&ring); poFeature->SetGeometry( &polygon ); } } else { // no geometry field /// create geometry data from m_GIS_data_type == GIS_Point_Type if( m_GIS_data_type == GIS_Point_Type ) { double x, y; if(parser.GetValueByFieldName("x",x) && parser.GetValueByFieldName("y",y) ) { OGRPoint pt; pt.setX( CoordinateVector[0].X ); pt.setY( CoordinateVector[0].Y); poFeature->SetGeometry( &pt ); }else { AfxMessageBox("Pleaes prepare fields x and y in the csv file in order to create a node GIS layer.", MB_ICONINFORMATION); return; } } ///create geometry if( m_GIS_data_type == GIS_Line_Type) { int number_of_shape_points = 0; if(parser.GetValueByFieldName("number_of_shape_points", number_of_shape_points)) { if(number_of_shape_points>=2) { OGRLineString line; for(int s= 1; s<= number_of_shape_points; s++) { CString str_x, str_y; str_x.Format ("x%d",s); str_y.Format ("y%d",s); double x = 0; double y = 0; string string_x, string_y; string_x = m_pDoc->CString2StdString (str_x); string_y = m_pDoc->CString2StdString (str_y); if(parser.GetValueByFieldName(string_x, x) && parser.GetValueByFieldName(string_y, y)) { line.addPoint(x,y); }else { AfxMessageBox("Pleaes prepare fields x1,y1,x2,y2,...,xn,yn in the csv file in order to create a link GIS layer.", MB_ICONINFORMATION); return; } } poFeature->SetGeometry( &line ); } }else { AfxMessageBox("Pleaes prepare fields number_of_shape_points, x1,y1,x2,y2,...,xn,yn in the csv file in order to create a link GIS layer.", MB_ICONINFORMATION); return; } } // if( m_GIS_data_type == GIS_Polygon_Type) { OGRPolygon polygon; OGRLinearRing ring; int number_of_shape_points = 0; if(parser.GetValueByFieldName("number_of_shape_points", number_of_shape_points)) { if(number_of_shape_points>=2) { OGRLineString line; for(int s= 0; s< number_of_shape_points; s++) { CString str_x, str_y; str_x.Format ("x%d",str_x); str_y.Format ("y%d",str_y); double x = 0; double y = 0; string string_x, string_y; string_x = m_pDoc->CString2StdString (str_x); string_y = m_pDoc->CString2StdString (str_y); if(parser.GetValueByFieldName(string_x, x) && parser.GetValueByFieldName(string_y, y)) { ring.addPoint (x,y,1); }else { AfxMessageBox("Pleaes prepare fields x1,y1,x2,y2,...,xn,yn in the csv file in order to create a zone GIS layer.", MB_ICONINFORMATION); return; } } polygon.addRing(&ring); poFeature->SetGeometry( &polygon ); } } } } if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) { AfxMessageBox("Failed to create line feature in shapefile.\n"); return; } OGRFeature::DestroyFeature( poFeature ); count++; } message_str.Format ("%d records have been created.",count); m_MessageList.AddString (message_str); OGRDataSource::DestroyDataSource( poDS ); CString ShapeFile = lpszShapeFileName; CString ShapeFileFolder = ShapeFile.Left(ShapeFile.ReverseFind('\\') + 1); ShellExecute( NULL, "explore", ShapeFileFolder, NULL, NULL, SW_SHOWNORMAL ); } #endif }
OGRFeature *OGROpenAirLayer::GetNextRawFeature() { const char* pszLine; CPLString osCLASS, osNAME, osFLOOR, osCEILING; OGRLinearRing oLR; /* double dfLastLat = 0, dfLastLon = 0; */ int bFirst = TRUE; int bClockWise = TRUE; double dfCenterLat = 0, dfCenterLon = 0; int bHasCenter = FALSE; OpenAirStyle sStyle; sStyle.penStyle = -1; sStyle.penWidth = -1; sStyle.penR = sStyle.penG = sStyle.penB = -1; sStyle.fillR = sStyle.fillG = sStyle.fillB = -1; if (bEOF) return NULL; while(TRUE) { if (bFirst && bHasLastLine) { pszLine = osLastLine.c_str(); bFirst = FALSE; } else { pszLine = CPLReadLine2L(fpOpenAir, 1024, NULL); if (pszLine == NULL) { bEOF = TRUE; if (oLR.getNumPoints() == 0) return NULL; if (osCLASS.size() != 0 && oStyleMap.find(osCLASS) != oStyleMap.end()) { memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle)); } break; } osLastLine = pszLine; bHasLastLine = TRUE; } if (pszLine[0] == '*' || pszLine[0] == '\0') continue; if (EQUALN(pszLine, "AC ", 3) || EQUALN(pszLine, "AC,", 3)) { if (osCLASS.size() != 0) { if (sStyle.penStyle != -1 || sStyle.fillR != -1) { if (oLR.getNumPoints() == 0) { OpenAirStyle* psStyle; if (oStyleMap.find(osCLASS) == oStyleMap.end()) { psStyle = (OpenAirStyle*)CPLMalloc( sizeof(OpenAirStyle)); oStyleMap[osCLASS] = psStyle; } else psStyle = oStyleMap[osCLASS]; memcpy(psStyle, &sStyle, sizeof(sStyle)); } else break; } else if (oStyleMap.find(osCLASS) != oStyleMap.end()) { memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle)); break; } else break; } sStyle.penStyle = -1; sStyle.penWidth = -1; sStyle.penR = sStyle.penG = sStyle.penB = -1; sStyle.fillR = sStyle.fillG = sStyle.fillB = -1; osCLASS = pszLine + 3; bClockWise = TRUE; bHasCenter = FALSE; } else if (EQUALN(pszLine, "AN ", 3)) { if (osNAME.size() != 0) break; osNAME = pszLine + 3; } else if (EQUALN(pszLine, "AH ", 3)) osCEILING = pszLine + 3; else if (EQUALN(pszLine, "AL ", 3)) osFLOOR = pszLine + 3; else if (EQUALN(pszLine, "AT ", 3)) { /* Ignored for that layer*/ } else if (EQUALN(pszLine, "SP ", 3)) { if (osCLASS.size() != 0) { char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0); if (CSLCount(papszTokens) == 5) { sStyle.penStyle = atoi(papszTokens[0]); sStyle.penWidth = atoi(papszTokens[1]); sStyle.penR = atoi(papszTokens[2]); sStyle.penG = atoi(papszTokens[3]); sStyle.penB = atoi(papszTokens[4]); } CSLDestroy(papszTokens); } } else if (EQUALN(pszLine, "SB ", 3)) { if (osCLASS.size() != 0) { char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0); if (CSLCount(papszTokens) == 3) { sStyle.fillR = atoi(papszTokens[0]); sStyle.fillG = atoi(papszTokens[1]); sStyle.fillB = atoi(papszTokens[2]); } CSLDestroy(papszTokens); } } else if (EQUALN(pszLine, "DP ", 3)) { pszLine += 3; double dfLat, dfLon; if (!OGROpenAirGetLatLon(pszLine, dfLat, dfLon)) continue; oLR.addPoint(dfLon, dfLat); /* dfLastLat = dfLat; */ /* dfLastLon = dfLon; */ } else if (EQUALN(pszLine, "DA ", 3)) { pszLine += 3; char* pszStar = strchr((char*)pszLine, '*'); if (pszStar) *pszStar = 0; char** papszTokens = CSLTokenizeString2(pszLine, ",", 0); if (bHasCenter && CSLCount(papszTokens) == 3) { double dfRadius = CPLAtof(papszTokens[0]) * 1852; double dfStartAngle = CPLAtof(papszTokens[1]); double dfEndAngle = CPLAtof(papszTokens[2]); if (bClockWise && dfEndAngle < dfStartAngle) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; double dfStartDistance = dfRadius; double dfEndDistance = dfRadius; int nSign = (bClockWise) ? 1 : -1; double dfAngle; double dfLat, dfLon; for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign) { double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfEndDistance, dfEndAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); /* dfLastLat = oLR.getY(oLR.getNumPoints() - 1); */ /* dfLastLon = oLR.getX(oLR.getNumPoints() - 1); */ } CSLDestroy(papszTokens); } else if (EQUALN(pszLine, "DB ", 3)) { pszLine += 3; char* pszStar = strchr((char*)pszLine, '*'); if (pszStar) *pszStar = 0; char** papszTokens = CSLTokenizeString2(pszLine, ",", 0); double dfFirstLat, dfFirstLon; double dfSecondLat, dfSecondLon; if (bHasCenter && CSLCount(papszTokens) == 2 && OGROpenAirGetLatLon(papszTokens[0], dfFirstLat, dfFirstLon) && OGROpenAirGetLatLon(papszTokens[1], dfSecondLat, dfSecondLon)) { double dfStartDistance =OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfFirstLat, dfFirstLon); double dfEndDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfSecondLat, dfSecondLon); double dfStartAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfFirstLat, dfFirstLon); double dfEndAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfSecondLat, dfSecondLon); if (bClockWise && dfEndAngle < dfStartAngle) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; int nSign = (bClockWise) ? 1 : -1; double dfAngle; for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign) { double dfLat, dfLon; double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } oLR.addPoint(dfSecondLon, dfSecondLat); /* dfLastLat = oLR.getY(oLR.getNumPoints() - 1); */ /* dfLastLon = oLR.getX(oLR.getNumPoints() - 1); */ } CSLDestroy(papszTokens); } else if ((EQUALN(pszLine, "DC ", 3) || EQUALN(pszLine, "DC=", 3)) && (bHasCenter || strstr(pszLine, "V X=") != NULL)) { if (!bHasCenter) { const char* pszVX = strstr(pszLine, "V X="); bHasCenter = OGROpenAirGetLatLon(pszVX, dfCenterLat, dfCenterLon); } if (bHasCenter) { pszLine += 3; double dfRADIUS = CPLAtof(pszLine) * 1852; double dfAngle; double dfLat, dfLon; for(dfAngle = 0; dfAngle < 360; dfAngle += 1) { OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); /* dfLastLat = oLR.getY(oLR.getNumPoints() - 1); */ /* dfLastLon = oLR.getX(oLR.getNumPoints() - 1); */ } } else if (EQUALN(pszLine, "V X=", 4)) { bHasCenter = OGROpenAirGetLatLon(pszLine + 4, dfCenterLat, dfCenterLon); } else if (EQUALN(pszLine, "V D=-", 5)) { bClockWise = FALSE; } else if (EQUALN(pszLine, "V D=+", 5)) { bClockWise = TRUE; } else { //CPLDebug("OpenAir", "Unexpected content : %s", pszLine); } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, osCLASS.c_str()); poFeature->SetField(1, osNAME.c_str()); poFeature->SetField(2, osFLOOR.c_str()); poFeature->SetField(3, osCEILING.c_str()); if (sStyle.penStyle != -1 || sStyle.fillR != -1) { CPLString osStyle; if (sStyle.penStyle != -1) { osStyle += CPLString().Printf("PEN(c:#%02X%02X%02X,w:%dpt", sStyle.penR, sStyle.penG, sStyle.penB, sStyle.penWidth); if (sStyle.penStyle == 1) osStyle += ",p:\"5px 5px\""; osStyle += ")"; } if (sStyle.fillR != -1) { if (osStyle.size() != 0) osStyle += ";"; osStyle += CPLString().Printf("BRUSH(fc:#%02X%02X%02X)", sStyle.fillR, sStyle.fillG, sStyle.fillB); } else { if (osStyle.size() != 0) osStyle += ";"; osStyle += "BRUSH(fc:#00000000,id:\"ogr-brush-1\")"; } if (osStyle.size() != 0) poFeature->SetStyleString(osStyle); } OGRPolygon* poPoly = new OGRPolygon(); oLR.closeRings(); poPoly->addRing(&oLR); poPoly->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
int main( int nArgc, char ** papszArgv ) { int nFirstSourceDataset = -1, bLayersWildcarded = TRUE, iArg; const char *pszFormat = "ESRI Shapefile"; const char *pszTileIndexField = "LOCATION"; const char *pszOutputName = NULL; int write_absolute_path = FALSE; int skip_different_projection = FALSE; char* current_path = NULL; int accept_different_schemas = FALSE; int bFirstWarningForNonMatchingAttributes = TRUE; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(papszArgv[0])) exit(1); /* -------------------------------------------------------------------- */ /* Register format(s). */ /* -------------------------------------------------------------------- */ OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 ) { pszFormat = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-write_absolute_path")) { write_absolute_path = TRUE; } else if( EQUAL(papszArgv[iArg],"-skip_different_projection")) { skip_different_projection = TRUE; } else if( EQUAL(papszArgv[iArg],"-accept_different_schemas")) { accept_different_schemas = TRUE; } else if( EQUAL(papszArgv[iArg],"-tileindex") && iArg < nArgc-1 ) { pszTileIndexField = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-lnum") || EQUAL(papszArgv[iArg],"-lname") ) { iArg++; bLayersWildcarded = FALSE; } else if( papszArgv[iArg][0] == '-' ) Usage(); else if( pszOutputName == NULL ) pszOutputName = papszArgv[iArg]; else if( nFirstSourceDataset == -1 ) nFirstSourceDataset = iArg; } if( pszOutputName == NULL || nFirstSourceDataset == -1 ) Usage(); /* -------------------------------------------------------------------- */ /* Try to open as an existing dataset for update access. */ /* -------------------------------------------------------------------- */ OGRDataSource *poDstDS; OGRLayer *poDstLayer = NULL; poDstDS = OGRSFDriverRegistrar::Open( pszOutputName, TRUE ); /* -------------------------------------------------------------------- */ /* If that failed, find the driver so we can create the tile index.*/ /* -------------------------------------------------------------------- */ if( poDstDS == NULL ) { OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); OGRSFDriver *poDriver = NULL; int iDriver; for( iDriver = 0; iDriver < poR->GetDriverCount() && poDriver == NULL; iDriver++ ) { if( EQUAL(poR->GetDriver(iDriver)->GetName(),pszFormat) ) { poDriver = poR->GetDriver(iDriver); } } if( poDriver == NULL ) { fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat ); fprintf( stderr, "The following drivers are available:\n" ); for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ ) { fprintf( stderr, " -> `%s'\n", poR->GetDriver(iDriver)->GetName() ); } exit( 1 ); } if( !poDriver->TestCapability( ODrCCreateDataSource ) ) { fprintf( stderr, "%s driver does not support data source creation.\n", pszFormat ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Now create it. */ /* -------------------------------------------------------------------- */ poDstDS = poDriver->CreateDataSource( pszOutputName, NULL ); if( poDstDS == NULL ) { fprintf( stderr, "%s driver failed to create %s\n", pszFormat, pszOutputName ); exit( 1 ); } if( poDstDS->GetLayerCount() == 0 ) { OGRFieldDefn oLocation( pszTileIndexField, OFTString ); oLocation.SetWidth( 200 ); if( nFirstSourceDataset < nArgc && papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; } OGRSpatialReference* poSrcSpatialRef = NULL; /* Fetches the SRS of the first layer and use it when creating the tileindex layer */ if (nFirstSourceDataset < nArgc) { OGRDataSource* poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], FALSE ); if (poDS) { int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; if ( poLayer->GetSpatialRef() ) poSrcSpatialRef = poLayer->GetSpatialRef()->Clone(); break; } } OGRDataSource::DestroyDataSource( poDS ); } poDstLayer = poDstDS->CreateLayer( "tileindex", poSrcSpatialRef ); poDstLayer->CreateField( &oLocation, OFTString ); OGRSpatialReference::DestroySpatialReference( poSrcSpatialRef ); } } /* -------------------------------------------------------------------- */ /* Identify target layer and field. */ /* -------------------------------------------------------------------- */ int iTileIndexField; poDstLayer = poDstDS->GetLayer(0); if( poDstLayer == NULL ) { fprintf( stderr, "Can't find any layer in output tileindex!\n" ); exit( 1 ); } iTileIndexField = poDstLayer->GetLayerDefn()->GetFieldIndex( pszTileIndexField ); if( iTileIndexField == -1 ) { fprintf( stderr, "Can't find %s field in tile index dataset.\n", pszTileIndexField ); exit( 1 ); } OGRFeatureDefn* poFeatureDefn = NULL; /* Load in memory existing file names in SHP */ int nExistingLayers = 0; char** existingLayersTab = NULL; OGRSpatialReference* alreadyExistingSpatialRef = NULL; int alreadyExistingSpatialRefValid = FALSE; nExistingLayers = poDstLayer->GetFeatureCount(); if (nExistingLayers) { int i; existingLayersTab = (char**)CPLMalloc(nExistingLayers * sizeof(char*)); for(i=0;i<nExistingLayers;i++) { OGRFeature* feature = poDstLayer->GetNextFeature(); existingLayersTab[i] = CPLStrdup(feature->GetFieldAsString( iTileIndexField)); if (i == 0) { OGRDataSource *poDS; char* filename = CPLStrdup(existingLayersTab[i]); int j; for(j=strlen(filename)-1;j>=0;j--) { if (filename[j] == ',') break; } if (j >= 0) { int iLayer = atoi(filename + j + 1); filename[j] = 0; poDS = OGRSFDriverRegistrar::Open(filename, FALSE ); if (poDS) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if (poLayer) { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (poLayer->GetSpatialRef()) ? poLayer->GetSpatialRef()->Clone() : NULL; if (poFeatureDefn == NULL) poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } OGRDataSource::DestroyDataSource( poDS ); } } } } } if (write_absolute_path) { current_path = CPLGetCurrentDir(); if (current_path == NULL) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n"); write_absolute_path = FALSE; } } /* ==================================================================== */ /* Process each input datasource in turn. */ /* ==================================================================== */ for(; nFirstSourceDataset < nArgc; nFirstSourceDataset++ ) { int i; OGRDataSource *poDS; if( papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; continue; } char* fileNameToWrite; VSIStatBuf sStatBuf; if (write_absolute_path && CPLIsFilenameRelative( papszArgv[nFirstSourceDataset] ) && VSIStat( papszArgv[nFirstSourceDataset], &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path,papszArgv[nFirstSourceDataset])); } else { fileNameToWrite = CPLStrdup(papszArgv[nFirstSourceDataset]); } poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], FALSE ); if( poDS == NULL ) { fprintf( stderr, "Failed to open dataset %s, skipping.\n", papszArgv[nFirstSourceDataset] ); CPLFree(fileNameToWrite); continue; } /* -------------------------------------------------------------------- */ /* Check all layers, and see if they match requests. */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; /* Checks that the layer is not already in tileindex */ for(i=0;i<nExistingLayers;i++) { char szLocation[5000]; sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); if (EQUAL(szLocation, existingLayersTab[i])) { fprintf(stderr, "Layer %d of %s is already in tileindex. Skipping it.\n", iLayer, papszArgv[nFirstSourceDataset]); break; } } if (i != nExistingLayers) { continue; } OGRSpatialReference* spatialRef = poLayer->GetSpatialRef(); if (alreadyExistingSpatialRefValid) { if ((spatialRef != NULL && alreadyExistingSpatialRef != NULL && spatialRef->IsSame(alreadyExistingSpatialRef) == FALSE) || ((spatialRef != NULL) != (alreadyExistingSpatialRef != NULL))) { fprintf(stderr, "Warning : layer %d of %s is not using the same projection system as " "other files in the tileindex. This may cause problems when " "using it in MapServer for example.%s\n", iLayer, papszArgv[nFirstSourceDataset], (skip_different_projection) ? " Skipping it" : ""); if (skip_different_projection) { continue; } } } else { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (spatialRef) ? spatialRef->Clone() : NULL; } /* -------------------------------------------------------------------- */ /* Check if all layers in dataset have the same attributes schema. */ /* -------------------------------------------------------------------- */ if( poFeatureDefn == NULL ) { poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } else if ( !accept_different_schemas ) { OGRFeatureDefn* poFeatureDefnCur = poLayer->GetLayerDefn(); assert(NULL != poFeatureDefnCur); int fieldCount = poFeatureDefnCur->GetFieldCount(); if( fieldCount != poFeatureDefn->GetFieldCount()) { fprintf( stderr, "Number of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } continue; } int bSkip = FALSE; for( int fn = 0; fn < poFeatureDefnCur->GetFieldCount(); fn++ ) { OGRFieldDefn* poField = poFeatureDefn->GetFieldDefn(fn); OGRFieldDefn* poFieldCur = poFeatureDefnCur->GetFieldDefn(fn); /* XXX - Should those pointers be checked against NULL? */ assert(NULL != poField); assert(NULL != poFieldCur); if( poField->GetType() != poFieldCur->GetType() || poField->GetWidth() != poFieldCur->GetWidth() || poField->GetPrecision() != poFieldCur->GetPrecision() || !EQUAL( poField->GetNameRef(), poFieldCur->GetNameRef() ) ) { fprintf( stderr, "Schema of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } bSkip = TRUE; break; } } if (bSkip) continue; } /* -------------------------------------------------------------------- */ /* Get layer extents, and create a corresponding polygon */ /* geometry. */ /* -------------------------------------------------------------------- */ OGREnvelope sExtents; OGRPolygon oRegion; OGRLinearRing oRing; if( poLayer->GetExtent( &sExtents, TRUE ) != OGRERR_NONE ) { fprintf( stderr, "GetExtent() failed on layer %s of %s, skipping.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset] ); continue; } oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRegion.addRing( &oRing ); /* -------------------------------------------------------------------- */ /* Add layer to tileindex. */ /* -------------------------------------------------------------------- */ char szLocation[5000]; OGRFeature oTileFeat( poDstLayer->GetLayerDefn() ); sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); oTileFeat.SetGeometry( &oRegion ); oTileFeat.SetField( iTileIndexField, szLocation ); if( poDstLayer->CreateFeature( &oTileFeat ) != OGRERR_NONE ) { fprintf( stderr, "Failed to create feature on tile index ... terminating." ); OGRDataSource::DestroyDataSource( poDstDS ); exit( 1 ); } } /* -------------------------------------------------------------------- */ /* Cleanup this data source. */ /* -------------------------------------------------------------------- */ CPLFree(fileNameToWrite); OGRDataSource::DestroyDataSource( poDS ); } /* -------------------------------------------------------------------- */ /* Close tile index and clear buffers. */ /* -------------------------------------------------------------------- */ OGRDataSource::DestroyDataSource( poDstDS ); OGRFeatureDefn::DestroyFeatureDefn( poFeatureDefn ); if (alreadyExistingSpatialRef != NULL) OGRSpatialReference::DestroySpatialReference( alreadyExistingSpatialRef ); CPLFree(current_path); if (nExistingLayers) { int i; for(i=0;i<nExistingLayers;i++) { CPLFree(existingLayersTab[i]); } CPLFree(existingLayersTab); } return 0; }
OGRFeature *OGRSUALayer::GetNextRawFeature() { if( bEOF ) return nullptr; CPLString osTYPE; CPLString osCLASS; CPLString osTITLE; CPLString osTOPS; CPLString osBASE; OGRLinearRing oLR; double dfLastLat = 0.0; double dfLastLon = 0.0; bool bFirst = true; while( true ) { const char* pszLine = nullptr; if( bFirst && bHasLastLine ) { pszLine = osLastLine.c_str(); bFirst = false; } else { pszLine = CPLReadLine2L(fpSUA, 1024, nullptr); if (pszLine == nullptr) { bEOF = true; if (oLR.getNumPoints() == 0) return nullptr; break; } osLastLine = pszLine; bHasLastLine = true; } if (pszLine[0] == '#' || pszLine[0] == '\0') continue; if (STARTS_WITH_CI(pszLine, "TYPE=")) { if (!osTYPE.empty()) break; osTYPE = pszLine + 5; } else if (STARTS_WITH_CI(pszLine, "CLASS=")) { if (!osCLASS.empty()) break; osCLASS = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TITLE=")) { if (!osTITLE.empty()) break; osTITLE = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TOPS=")) osTOPS = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "BASE=")) osBASE = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "POINT=")) { pszLine += 6; if (strlen(pszLine) != 16) continue; double dfLat = 0.0; double dfLon = 0.0; if (!GetLatLon(pszLine, dfLat, dfLon)) continue; oLR.addPoint(dfLon, dfLat); dfLastLat = dfLat; dfLastLon = dfLon; } else if (STARTS_WITH_CI(pszLine, "CLOCKWISE") || STARTS_WITH_CI(pszLine, "ANTI-CLOCKWISE")) { if (oLR.getNumPoints() == 0) continue; int bClockWise = STARTS_WITH_CI(pszLine, "CLOCKWISE"); /*const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == NULL) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852;*/ const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == nullptr) continue; pszCENTRE += 7; if (strlen(pszCENTRE) < 17 || pszCENTRE[16] != ' ') continue; double dfCenterLat = 0.0; double dfCenterLon = 0.0; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; const char* pszTO = strstr(pszLine, "TO="); if (pszTO == nullptr) continue; pszTO += 3; if (strlen(pszTO) != 16) continue; double dfToLat = 0.0; double dfToLon = 0.0; if (!GetLatLon(pszTO, dfToLat, dfToLon)) continue; const double dfStartDistance = OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); const double dfEndDistance = OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfToLat, dfToLon); const double dfStartAngle = OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); double dfEndAngle = OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfToLat, dfToLon); if( bClockWise && dfEndAngle < dfStartAngle ) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; int nSign = (bClockWise) ? 1 : -1; for( double dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign ) { const double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); const double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; double dfLat = 0.0; double dfLon = 0.0; OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } oLR.addPoint(dfToLon, dfToLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "CIRCLE")) { const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == nullptr) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852; const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == nullptr) continue; pszCENTRE += 7; if (strlen(pszCENTRE) != 16) continue; double dfCenterLat = 0.0; double dfCenterLon = 0.0; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; double dfLat = 0.0; double dfLon = 0.0; for( double dfAngle = 0; dfAngle < 360; dfAngle += 1 ) { OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "INCLUDE") || STARTS_WITH_CI(pszLine, "END")) { } else { CPLDebug("SUA", "Unexpected content : %s", pszLine); } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, osTYPE.c_str()); poFeature->SetField(1, osCLASS.c_str()); poFeature->SetField(2, osTITLE.c_str()); poFeature->SetField(3, osTOPS.c_str()); poFeature->SetField(4, osBASE.c_str()); OGRPolygon* poPoly = new OGRPolygon(); poPoly->assignSpatialReference(poSRS); oLR.closeRings(); poPoly->addRing(&oLR); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
/*! \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; }
void SavePolygons( const std::vector< std::string > InFilenames, const char *OutFilename, const cv::Mat klabels, const std::vector< cv::Mat > raster, const std::vector< u_int32_t > labelpixels, const std::vector< std::vector <double> > sumCH, const std::vector< std::vector <double> > avgCH, const std::vector< std::vector <double> > stdCH, std::vector< std::vector< LINE > >& linelists ) { CPLLocaleC oLocaleCForcer(); CPLErrorReset(); const char *pszDriverName = "ESRI Shapefile"; GDALDriver *liDriver; liDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName ); if( liDriver == NULL ) { printf( "\nERROR: %s driver not available.\n", pszDriverName ); exit( 1 ); } const size_t m_bands = raster.size(); const size_t m_labels = labelpixels.size(); GDALDataset *liDS; liDS = liDriver->Create( OutFilename, 0, 0, 0, GDT_Unknown, NULL ); if( liDS == NULL ) { printf( "\nERROR: Creation of output file failed.\n" ); exit( 1 ); } // dataset GDALDataset* piDataset; piDataset = (GDALDataset*) GDALOpen(InFilenames[0].c_str(), GA_ReadOnly); // spatialref OGRSpatialReference oSRS; oSRS.SetProjCS( piDataset->GetProjectionRef() ); OGRLayer *liLayer; liLayer = liDS->CreateLayer( "segments", &oSRS, wkbPolygon, NULL ); if( liLayer == NULL ) { printf( "\nERROR: Layer creation failed.\n" ); exit( 1 ); } // spatial transform double adfGeoTransform[6]; double oX = 0.0f; double oY = 0.0f; double mX = 1.0f; double mY = -1.0f; if( piDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { oX = adfGeoTransform[0]; oY = adfGeoTransform[3]; mX = adfGeoTransform[1]; mY = adfGeoTransform[5]; } GDALClose( (GDALDatasetH) piDataset ); OGRFieldDefn *clsIdField = new OGRFieldDefn( "CLASS", OFTInteger ); liLayer->CreateField( clsIdField ); OGRFieldDefn *pixArField = new OGRFieldDefn( "AREA", OFTInteger ); liLayer->CreateField( pixArField ); for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_AVERAGE"; OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal ); liLayer->CreateField( lavrgField ); } for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_STDDEV"; OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal ); liLayer->CreateField( lavrgField ); } int multiring = 0; printf ("Write File: %s (polygon)\n", OutFilename); for (size_t k = 0; k < m_labels; k++) { if (multiring == 1) { k = k - 1; multiring = 0; } if (linelists[k].size() == 0) continue; // insert field data OGRFeature *liFeature; liFeature = OGRFeature::CreateFeature( liLayer->GetLayerDefn() ); liFeature->SetField( "CLASS", (int) k ); liFeature->SetField( "AREA", (int) labelpixels.at(k) ); for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_AVERAGE"; liFeature->SetField( FieldName.c_str(), (double) avgCH[b].at(k) ); } for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_STDDEV"; liFeature->SetField( FieldName.c_str(), stdCH[b].at(k) ); } // initiate polygon start OGRLinearRing linestring; linestring.setCoordinateDimension(2); linestring.addPoint( oX + (double) linelists[k][0].sX * mX, oY + mY * (double) linelists[k][0].sY ); linestring.addPoint( oX + (double) linelists[k][0].eX * mX, oY + mY * (double) linelists[k][0].eY ); linelists[k].erase( linelists[k].begin() ); // construct polygon from lines while ( linelists[k].size() > 0 ) { if (multiring == 1) break; vector<LINE>::iterator it = linelists[k].begin(); for (; it != linelists[k].end(); ++it) { double ltX = linestring.getX(linestring.getNumPoints()-1); double ltY = linestring.getY(linestring.getNumPoints()-1); double csX = oX + (double) it->sX * mX; double csY = oY + mY * (double) it->sY; double ceX = oX + (double) it->eX * mX; double ceY = oY + mY * (double) it->eY; if ( ( csX == ltX ) && ( csY == ltY ) ) { linestring.addPoint(ceX, ceY); linelists[k].erase(it); break; } if ( ( ceX == ltX ) && ( ceY == ltY ) ) { linestring.addPoint(csX, csY); linelists[k].erase(it); break; } if (it == linelists[k].end()-1) { multiring = 1; break; } } } OGRPolygon polygon; linestring.closeRings(); // simplify poligons // remove colinear vertices OGRLinearRing linesimple; float pointPrevX = 0, pointPrevY = 0; for (int i = 0; i < linestring.getNumPoints(); i++) { OGRPoint point; linestring.getPoint(i, &point); // start if ( i == 0) { linesimple.addPoint( &point ); pointPrevX = point.getX(); pointPrevY = point.getY(); continue; } // end vertex if ( i == linestring.getNumPoints() - 1 ) { linesimple.addPoint( &point ); continue; } OGRPoint pointNext; linestring.getPoint(i+1, &pointNext); // | x1 y1 1 | // det | x2 y2 1 | = 0 => p1,p2,p3 are colinear // | x3 y3 1 | // x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2) == 0 // only if not colinear with previous and next if ( pointPrevX*(point.getY()-pointNext.getY()) + point.getX()*(pointNext.getY()-pointPrevY) + pointNext.getX()*(pointPrevY-point.getY()) != 0 ) { linesimple.addPoint( &point ); pointPrevX = point.getX(); pointPrevY = point.getY(); } } // as polygon geometry polygon.addRing( &linesimple ); liFeature->SetGeometry( &polygon ); if( liLayer->CreateFeature( liFeature ) != OGRERR_NONE ) { printf( "\nERROR: Failed to create feature in shapefile.\n" ); exit( 1 ); } OGRFeature::DestroyFeature( liFeature ); GDALTermProgress( (float)(k+1) / (float)(m_labels), NULL, NULL ); } GDALTermProgress( 1.0f, NULL, NULL ); GDALClose( liDS ); }