int main(int argc, char **argv) { // Get data from ogr OGRRegisterAll(); std::cout << "Opening: " << argv[1] << std::endl; OGRDataSource *shp = OGRSFDriverRegistrar::Open(argv[1], FALSE); IsValid(shp, "Error opening file."); std::cout << "Shape contains " << shp->GetLayerCount() << " layers." << std::endl; OGRLayer *layer = shp->GetLayerByName(argv[2]); IsValid(layer, "Couldn't grab layer"); OGRSpatialReference *srcSRS = NULL; srcSRS = layer->GetSpatialRef(); // Set up writing const char *kDriverName = "ESRI Shapefile"; OGRSFDriver *shpDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(kDriverName); IsValid(shpDriver, "Couldn't grab the shapefile driver."); IsValid(argv[3], "Please provide a output shp."); std::cout << "Writing to: " << argv[3] << std::endl; OGRDataSource *shpOut = shpDriver->CreateDataSource(argv[3], NULL); IsValid(shpOut, "Couldn't open output file"); OGRLayer *outLayer = shpOut->CreateLayer(layer->GetName(), srcSRS, wkbMultiLineString, NULL); IsValid(outLayer, "Couldn't create an output layer"); // copy over the fields from the source file OGRFeatureDefn *source = layer->GetLayerDefn(); for(int i=0; i < source->GetFieldCount(); i++){ OGRFieldDefn *field = source->GetFieldDefn(i); if(outLayer->CreateField(field) != OGRERR_NONE) { std::cout << "Couldn't make layer" << std::endl; exit(1); }; } // Loop through features and grab the hull and put it into CGAL then // skeletonize the points OGRFeature *feature; int count = 0; while((feature = layer->GetNextFeature()) != NULL) { OGRMultiPolygon *geometry = dynamic_cast<OGRMultiPolygon *>(OGRGeometryFactory::forceToMultiPolygon(feature->GetGeometryRef())); IsValid(geometry, "No geometry."); OGRFeature *outFeature = OGRFeature::CreateFeature(outLayer->GetLayerDefn()); IsValid(outFeature, "Couldn't make a feature."); for(int i=0; i < source->GetFieldCount(); i++){ OGRField *field = feature->GetRawFieldRef(i); outFeature->SetField(i, field); } OGRGeometry* line = NULL; for(int i=0; i < geometry->getNumGeometries(); i++){ OGRGeometry* segment = BuildMultiLine(geometry->getGeometryRef(i)); if(segment != NULL){ if(line == NULL) { line = new OGRLineString; } OGRGeometry* tmp = line->Union(segment); if(tmp != NULL){ delete line; line = tmp; } delete segment; } } outFeature->SetGeometry(line); if(outLayer->CreateFeature(outFeature) != OGRERR_NONE){ std::cout << "Couldn't create feature." << std::endl; exit(1); } // clean up OGRFeature::DestroyFeature(outFeature); std::cout << std::endl << ++count << std::endl; } // cleanup OGRDataSource::DestroyDataSource(shp); OGRDataSource::DestroyDataSource(shpOut); return 0; }
std::vector<Polygon> Polygon::polygons() const { std::vector<Polygon> polys; OGRwkbGeometryType t = m_geom->getGeometryType(); if (t == wkbPolygon || t == wkbPolygon25D) polys.emplace_back(*this); else if (t == wkbMultiPolygon || t == wkbMultiPolygon25D) { // Not until GDAL 2.3 /** OGRMultiPolygon *mPoly = m_geom->toMultiPolygon(); for (auto it = mPoly->begin(); it != mPoly->end(); ++it) { Polygon p; p.m_geom.reset((*it)->clone()); polys.push_back(p); } **/ OGRMultiPolygon *mPoly = static_cast<OGRMultiPolygon *>(m_geom.get()); for (int i = 0; i < mPoly->getNumGeometries(); ++i) { Polygon p; p.m_geom.reset(mPoly->getGeometryRef(i)->clone()); polys.push_back(p); } } return polys; }
OGRMultiPolygon* make() { OGRMultiPolygon* poCollection = new OGRMultiPolygon(); poCollection->addGeometryDirectly(make<OGRPolygon>()); return poCollection; }
OGRFeature* create_area_feature(const shared_ptr<Osmium::OSM::Area const>& area) { OGRFeature* feature = OGRFeature::CreateFeature(m_layer_polygon->GetLayerDefn()); Osmium::Geometry::MultiPolygon mp(*area); OGRMultiPolygon* ogrgeom = Osmium::Geometry::create_ogr_geometry(mp); ogrgeom->transform(m_transformation); feature->SetGeometryDirectly(ogrgeom); sprintf(longint, "%ld", area->from_way() ? area->orig_id() : -area->orig_id()); feature->SetField("osm_id", longint); feature->SetField("z_order", calculate_z_order(area.get())); feature->SetField("way_area", ogrgeom->get_Area()); return feature; }
OGRGeometry *OGRGeometryFactory::forceToMultiPolygon( OGRGeometry *poGeom ) { if( poGeom == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Check for the case of a geometrycollection that can be */ /* promoted to MultiPolygon. */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) == wkbGeometryCollection ) { int iGeom; int bAllPoly = TRUE; OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom; for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ ) { if( wkbFlatten(poGC->getGeometryRef(iGeom)->getGeometryType()) != wkbPolygon ) bAllPoly = FALSE; } if( !bAllPoly ) return poGeom; OGRMultiPolygon *poMP = new OGRMultiPolygon(); while( poGC->getNumGeometries() > 0 ) { poMP->addGeometryDirectly( poGC->getGeometryRef(0) ); poGC->removeGeometry( 0, FALSE ); } delete poGC; return poMP; } /* -------------------------------------------------------------------- */ /* Eventually we should try to split the polygon into component */ /* island polygons. But thats alot of work and can be put off. */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) != wkbPolygon ) return poGeom; OGRMultiPolygon *poMP = new OGRMultiPolygon(); poMP->addGeometryDirectly( poGeom ); return poMP; }
int main() { // Read in raster data for night time lights int band_number = 1; // only one band, starts with one Raster* raster = import_raster("raster.tif", band_number); // Read in shapefile data containing municipality administrative regions int layer_number = 0; // only one layer, starts with zero OGRLayer* shapelayer = import_shapefile("MEX_adm2.shp", layer_number); shapelayer->SetAttributeFilter("ID_1 = 1834"); // Filter for Yucatan const int idx_of_number_field = 5; // Column number of municipality number const int idx_of_name_field = 6; // Column number of municipality name OGRFeature* poFeature; int feature_ctr = 0; while( (poFeature = shapelayer->GetNextFeature()) != NULL ) { cerr << "Feature: " << feature_ctr++ << "\t"; int feature_num = poFeature->GetFieldAsInteger(idx_of_number_field); string feature_name = poFeature->GetFieldAsString(idx_of_name_field); OGRFeatureDefn *poFDefn = shapelayer->GetLayerDefn(); for( int iField = 0; iField < poFDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField ); if( poFieldDefn->GetType() == OFTString ) cerr << poFeature->GetFieldAsString(iField) << ","; } OGRGeometry* poGeometry = poFeature->GetGeometryRef(); if( poGeometry != NULL) { // For contiguous regions if ( wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon ) { cerr << " polygon" << endl; report_raster_data_within_polygon(raster, (OGRPolygon *) poGeometry, feature_num, feature_name); // For disjoint regions } else if ( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon ) { cerr << " multipolygon" << endl; OGRMultiPolygon *multipolygon = (OGRMultiPolygon *) poGeometry; for (int i = 0; i<multipolygon->getNumGeometries(); i++) { report_raster_data_within_polygon(raster, (OGRPolygon*) multipolygon->getGeometryRef(i), feature_num, feature_name); } // Is this really the right shapefile? } else { cerr << "No polygon or multipolygon geometry for this feature: " << poGeometry->getGeometryName() << endl; } } else { cerr << "No geometry for this feature" << endl; } } OGRFeature::DestroyFeature( poFeature ); }
void GDALMergeFaces::run() { OGRGeometry * geo; leadingView.resetReading(); OGRFeature * f; std::set<int> indizes; while (f = leadingView.getNextFeature()) { indizes.insert(f->GetFieldAsInteger(this->attriubteName.c_str())); } //int cluster_id = 1; int counter = 1; foreach (int cluster_id, indizes) { //while(geo = joinCluster(cluster_id)) { //cluster_id++; geo = joinCluster(cluster_id); if (counter % 100 == 0) { DM::Logger(DM::Standard) << "merged " << counter << "/" << indizes.size(); } counter++; if (!geo) continue; if (wkbMultiPolygon == geo->getGeometryType()){ geo = geo->UnionCascaded(); OGRMultiPolygon * mgeo = (OGRMultiPolygon*) geo; if (mgeo->getNumGeometries() == 0) { continue; } geo = mgeo->getGeometryRef(0); int n = mgeo->getNumGeometries(); for (int i = 0; i < n; i++) { OGRFeature * f = combinedView.createFeature(); f->SetGeometry(mgeo->getGeometryRef(i)); f->SetField("test_id", counter); } continue; } OGRFeature * f = combinedView.createFeature(); f->SetGeometry(geo); }
OGRGeometry *OGRMultiPolygon::clone() const { OGRMultiPolygon *poNewGC; poNewGC = new OGRMultiPolygon; poNewGC->assignSpatialReference( getSpatialReference() ); for( int i = 0; i < getNumGeometries(); i++ ) { poNewGC->addGeometry( getGeometryRef(i) ); } return poNewGC; }
void Polygon::simplify(double distance_tolerance, double area_tolerance) { throwNoGeos(); auto deleteSmallRings = [area_tolerance](OGRGeometry *geom) { // Missing until GDAL 2.3. // OGRPolygon *poly = geom->toPolygon(); OGRPolygon *poly = static_cast<OGRPolygon *>(geom); std::vector<int> deleteRings; for (int i = 0; i < poly->getNumInteriorRings(); ++i) { OGRLinearRing *lr = poly->getInteriorRing(i); if (lr->get_Area() < area_tolerance) deleteRings.push_back(i + 1); } // Note that interior rings are in a list with the exterior ring, // which is why the ring numbers are offset by one when used in // this context (what a mess). for (auto i : deleteRings) // Missing until 2.3 // poly->removeRing(i, true); OGR_G_RemoveGeometry(gdal::toHandle(poly), i, true); }; OGRGeometry *g = m_geom->SimplifyPreserveTopology(distance_tolerance); m_geom.reset(g); OGRwkbGeometryType t = m_geom->getGeometryType(); if (t == wkbPolygon || t == wkbPolygon25D) deleteSmallRings(m_geom.get()); else if (t == wkbMultiPolygon || t == wkbMultiPolygon25D) { // Missing until 2.3 /** OGRMultiPolygon *mpoly = m_geom->toMultiPolygon(); for (auto it = mpoly->begin(); it != mpoly->end(); ++it) deleteSmallRings(*it); **/ OGRMultiPolygon *mpoly = static_cast<OGRMultiPolygon *>(m_geom.get()); for (int i = 0; i < mpoly->getNumGeometries(); ++i) deleteSmallRings(mpoly->getGeometryRef(i)); } }
OGRMultiPolygon* OGRMSSQLGeometryParser::ReadMultiPolygon(int iShape) { int i; OGRMultiPolygon* poMultiPolygon = new OGRMultiPolygon(); OGRGeometry* poGeom; for (i = iShape + 1; i < nNumShapes; i++) { poGeom = NULL; if (ParentOffset(i) == (unsigned int)iShape) { if ( ShapeType(i) == ST_POLYGON ) poGeom = ReadPolygon(i); } if ( poGeom ) poMultiPolygon->addGeometryDirectly( poGeom ); } return poMultiPolygon; }
double Polygon::area() const { throwNoGeos(); OGRwkbGeometryType t = m_geom->getGeometryType(); // Not until GDAL 2.3 /** if (t == wkbPolygon || t == wkbPolygon25D) return m_geom->toPolygon()->get_Area(); else if (t == wkbMultiPolygon || t == wkbMultiPolygon25D) return m_geom->toMultiPolygon()->get_Area(); **/ if (t == wkbPolygon || t == wkbPolygon25D) { OGRPolygon *p = static_cast<OGRPolygon *>(m_geom.get()); return p->get_Area(); } else if (t == wkbMultiPolygon || t == wkbMultiPolygon25D) { OGRMultiPolygon *p = static_cast<OGRMultiPolygon *>(m_geom.get()); return p->get_Area(); } return 0; }
void PCLoaderArcView::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill, PCTypeMap&) { #ifdef HAVE_GDAL GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing(); // get defaults std::string prefix = oc.getString("prefix"); std::string type = oc.getString("type"); RGBColor color = RGBColor::parseColor(oc.getString("color")); int layer = oc.getInt("layer"); std::string idField = oc.getString("shapefile.id-column"); bool useRunningID = oc.getBool("shapefile.use-running-id"); // start parsing std::string shpName = file + ".shp"; OGRRegisterAll(); OGRDataSource* poDS = OGRSFDriverRegistrar::Open(shpName.c_str(), FALSE); if (poDS == NULL) { throw ProcessError("Could not open shape description '" + shpName + "'."); } // begin file parsing OGRLayer* poLayer = poDS->GetLayer(0); poLayer->ResetReading(); // build coordinate transformation OGRSpatialReference* origTransf = poLayer->GetSpatialRef(); OGRSpatialReference destTransf; // use wgs84 as destination destTransf.SetWellKnownGeogCS("WGS84"); OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf); if (poCT == NULL) { if (oc.isSet("shapefile.guess-projection")) { OGRSpatialReference origTransf2; origTransf2.SetWellKnownGeogCS("WGS84"); poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf); } if (poCT == 0) { WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed."); } } OGRFeature* poFeature; poLayer->ResetReading(); unsigned int runningID = 0; while ((poFeature = poLayer->GetNextFeature()) != NULL) { // read in edge attributes std::string id = useRunningID ? toString(runningID) : poFeature->GetFieldAsString(idField.c_str()); ++runningID; id = StringUtils::prune(id); if (id == "") { throw ProcessError("Missing id under '" + idField + "'"); } id = prefix + id; // read in the geometry OGRGeometry* poGeometry = poFeature->GetGeometryRef(); if (poGeometry == 0) { OGRFeature::DestroyFeature(poFeature); continue; } // try transform to wgs84 poGeometry->transform(poCT); OGRwkbGeometryType gtype = poGeometry->getGeometryType(); switch (gtype) { case wkbPoint: { OGRPoint* cgeom = (OGRPoint*) poGeometry; Position pos((SUMOReal) cgeom->getX(), (SUMOReal) cgeom->getY()); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for POI '" + id + "'."); } PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer); if (!toFill.insert(id, poi, layer)) { WRITE_ERROR("POI '" + id + "' could not be added."); delete poi; } } break; case wkbLineString: { OGRLineString* cgeom = (OGRLineString*) poGeometry; PositionVector shape; for (int j = 0; j < cgeom->getNumPoints(); j++) { Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(id, type, color, shape, false, (SUMOReal)layer); if (!toFill.insert(id, poly, layer)) { WRITE_ERROR("Polygon '" + id + "' could not be added."); delete poly; } } break; case wkbPolygon: { OGRLinearRing* cgeom = ((OGRPolygon*) poGeometry)->getExteriorRing(); PositionVector shape; for (int j = 0; j < cgeom->getNumPoints(); j++) { Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(id, type, color, shape, true, (SUMOReal)layer); if (!toFill.insert(id, poly, layer)) { WRITE_ERROR("Polygon '" + id + "' could not be added."); delete poly; } } break; case wkbMultiPoint: { OGRMultiPoint* cgeom = (OGRMultiPoint*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRPoint* cgeom2 = (OGRPoint*) cgeom->getGeometryRef(i); Position pos((SUMOReal) cgeom2->getX(), (SUMOReal) cgeom2->getY()); std::string tid = id + "#" + toString(i); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for POI '" + tid + "'."); } PointOfInterest* poi = new PointOfInterest(tid, type, color, pos, (SUMOReal)layer); if (!toFill.insert(tid, poi, layer)) { WRITE_ERROR("POI '" + tid + "' could not be added."); delete poi; } } } break; case wkbMultiLineString: { OGRMultiLineString* cgeom = (OGRMultiLineString*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRLineString* cgeom2 = (OGRLineString*) cgeom->getGeometryRef(i); PositionVector shape; std::string tid = id + "#" + toString(i); for (int j = 0; j < cgeom2->getNumPoints(); j++) { Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(tid, type, color, shape, false, (SUMOReal)layer); if (!toFill.insert(tid, poly, layer)) { WRITE_ERROR("Polygon '" + tid + "' could not be added."); delete poly; } } } break; case wkbMultiPolygon: { OGRMultiPolygon* cgeom = (OGRMultiPolygon*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRLinearRing* cgeom2 = ((OGRPolygon*) cgeom->getGeometryRef(i))->getExteriorRing(); PositionVector shape; std::string tid = id + "#" + toString(i); for (int j = 0; j < cgeom2->getNumPoints(); j++) { Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(tid, type, color, shape, true, (SUMOReal)layer); if (!toFill.insert(tid, poly, layer)) { WRITE_ERROR("Polygon '" + tid + "' could not be added."); delete poly; } } } break; default: WRITE_WARNING("Unsupported shape type occured (id='" + id + "')."); break; } OGRFeature::DestroyFeature(poFeature); } PROGRESS_DONE_MESSAGE(); #else WRITE_ERROR("SUMO was compiled without GDAL support."); #endif }
static CPLErr OGRPolygonContourWriter( double dfLevelMin, double dfLevelMax, const OGRMultiPolygon& multipoly, void *pInfo ) { OGRContourWriterInfo *poInfo = static_cast<OGRContourWriterInfo *>(pInfo); OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn( static_cast<OGRLayerH>(poInfo->hLayer) ); OGRFeatureH hFeat = OGR_F_Create( hFDefn ); if( poInfo->nIDField != -1 ) OGR_F_SetFieldInteger( hFeat, poInfo->nIDField, poInfo->nNextID++ ); if( poInfo->nElevFieldMin != -1 ) OGR_F_SetFieldDouble( hFeat, poInfo->nElevFieldMin, dfLevelMin ); if( poInfo->nElevFieldMax != -1 ) OGR_F_SetFieldDouble( hFeat, poInfo->nElevFieldMax, dfLevelMax ); const bool bHasZ = wkbHasZ(OGR_FD_GetGeomType(hFDefn)); OGRGeometryH hGeom = OGR_G_CreateGeometry( bHasZ ? wkbMultiPolygon25D : wkbMultiPolygon ); for ( int iPart = 0; iPart < multipoly.getNumGeometries(); iPart++ ) { OGRPolygon* poNewPoly = new OGRPolygon(); const OGRPolygon* poPolygon = static_cast<const OGRPolygon*>(multipoly.getGeometryRef(iPart)); for ( int iRing = 0; iRing < poPolygon->getNumInteriorRings() + 1; iRing++ ) { const OGRLinearRing* poRing = iRing == 0 ? poPolygon->getExteriorRing() : poPolygon->getInteriorRing(iRing - 1); OGRLinearRing* poNewRing = new OGRLinearRing(); for ( int iPoint = 0; iPoint < poRing->getNumPoints(); iPoint++ ) { const double dfX = poInfo->adfGeoTransform[0] + poInfo->adfGeoTransform[1] * poRing->getX(iPoint) + poInfo->adfGeoTransform[2] * poRing->getY(iPoint); const double dfY = poInfo->adfGeoTransform[3] + poInfo->adfGeoTransform[4] * poRing->getX(iPoint) + poInfo->adfGeoTransform[5] * poRing->getY(iPoint); if( bHasZ ) OGR_G_SetPoint( OGRGeometry::ToHandle( poNewRing ), iPoint, dfX, dfY, dfLevelMax ); else OGR_G_SetPoint_2D( OGRGeometry::ToHandle( poNewRing ), iPoint, dfX, dfY ); } poNewPoly->addRingDirectly( poNewRing ); } OGR_G_AddGeometryDirectly( hGeom, OGRGeometry::ToHandle( poNewPoly ) ); } OGR_F_SetGeometryDirectly( hFeat, hGeom ); const OGRErr eErr = OGR_L_CreateFeature(static_cast<OGRLayerH>(poInfo->hLayer), hFeat); OGR_F_Destroy( hFeat ); return eErr == OGRERR_NONE ? CE_None : CE_Failure; }
static OGRGeometry *GML2OGRGeometry_XMLNode( CPLXMLNode *psNode ) { const char *pszBaseGeometry = BareGMLElement( psNode->pszValue ); /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"Polygon") ) { CPLXMLNode *psChild; OGRPolygon *poPolygon = new OGRPolygon(); OGRLinearRing *poRing; // Find outer ring. psChild = FindBareXMLChild( psNode, "outerBoundaryIs" ); if( psChild == NULL || psChild->psChild == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing outerBoundaryIs property on Polygon." ); delete poPolygon; return NULL; } // Translate outer ring and add to polygon. poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poRing == NULL ) { delete poPolygon; return NULL; } if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as outerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"innerBoundaryIs") ) { poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as innerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); } } return poPolygon; } /* -------------------------------------------------------------------- */ /* LinearRing */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LinearRing") ) { OGRLinearRing *poLinearRing = new OGRLinearRing(); if( !ParseGMLCoordinates( psNode, poLinearRing ) ) { delete poLinearRing; return NULL; } return poLinearRing; } /* -------------------------------------------------------------------- */ /* LineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LineString") ) { OGRLineString *poLine = new OGRLineString(); if( !ParseGMLCoordinates( psNode, poLine ) ) { delete poLine; return NULL; } return poLine; } /* -------------------------------------------------------------------- */ /* PointType */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"PointType") || EQUAL(pszBaseGeometry,"Point") ) { OGRPoint *poPoint = new OGRPoint(); if( !ParseGMLCoordinates( psNode, poPoint ) ) { delete poPoint; return NULL; } return poPoint; } /* -------------------------------------------------------------------- */ /* Box */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"BoxType") || EQUAL(pszBaseGeometry,"Box") ) { OGRLineString oPoints; if( !ParseGMLCoordinates( psNode, &oPoints ) ) return NULL; if( oPoints.getNumPoints() < 2 ) return NULL; OGRLinearRing *poBoxRing = new OGRLinearRing(); OGRPolygon *poBoxPoly = new OGRPolygon(); poBoxRing->setNumPoints( 5 ); poBoxRing->setPoint( 0, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 1, oPoints.getX(1), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 2, oPoints.getX(1), oPoints.getY(1), oPoints.getZ(1) ); poBoxRing->setPoint( 3, oPoints.getX(0), oPoints.getY(1), oPoints.getZ(0) ); poBoxRing->setPoint( 4, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxPoly->addRingDirectly( poBoxRing ); return poBoxPoly; } /* -------------------------------------------------------------------- */ /* MultiPolygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPolygon") ) { CPLXMLNode *psChild; OGRMultiPolygon *poMPoly = new OGRMultiPolygon(); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"polygonMember") ) { OGRPolygon *poPolygon; poPolygon = (OGRPolygon *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPolygon == NULL ) { delete poMPoly; return NULL; } if( !EQUAL(poPolygon->getGeometryName(),"POLYGON") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as polygonMember instead of MULTIPOLYGON.", poPolygon->getGeometryName() ); delete poPolygon; delete poMPoly; return NULL; } poMPoly->addGeometryDirectly( poPolygon ); } } return poMPoly; } /* -------------------------------------------------------------------- */ /* MultiPoint */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPoint") ) { CPLXMLNode *psChild; OGRMultiPoint *poMP = new OGRMultiPoint(); // collect points. for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"pointMember") ) { OGRPoint *poPoint; poPoint = (OGRPoint *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPoint == NULL || wkbFlatten(poPoint->getGeometryType()) != wkbPoint ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as pointMember instead of MULTIPOINT", poPoint ? poPoint->getGeometryName() : "NULL" ); delete poPoint; delete poMP; return NULL; } poMP->addGeometryDirectly( poPoint ); } } return poMP; } /* -------------------------------------------------------------------- */ /* MultiLineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiLineString") ) { CPLXMLNode *psChild; OGRMultiLineString *poMP = new OGRMultiLineString(); // collect lines for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"lineStringMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL || wkbFlatten(poGeom->getGeometryType()) != wkbLineString ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as Member instead of LINESTRING.", poGeom ? poGeom->getGeometryName() : "NULL" ); delete poGeom; delete poMP; return NULL; } poMP->addGeometryDirectly( poGeom ); } } return poMP; } /* -------------------------------------------------------------------- */ /* GeometryCollection */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"GeometryCollection") ) { CPLXMLNode *psChild; OGRGeometryCollection *poGC = new OGRGeometryCollection(); // collect geoms for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"geometryMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to get geometry in geometryMember" ); delete poGeom; delete poGC; return NULL; } poGC->addGeometryDirectly( poGeom ); } } return poGC; } CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised geometry type <%.500s>.", pszBaseGeometry ); return NULL; }
bool ShpReader::Open(std::wstring fullPath, StudyControllerPtr studyController, VectorMapControllerPtr vectorMapController, ProgressDlgPtr progressDlg) { // Registers all format drivers built into GDAL/OGR. OGRRegisterAll(); OGRDataSource *OGRDataset; // Open vector file path std::string tempStr( fullPath.begin(), fullPath.end() ); OGRDataset = OGRSFDriverRegistrar::Open( tempStr.c_str(), FALSE ); // Return if no vector files are found if( OGRDataset == NULL ) { Log::Inst().Warning("(Warning) Failed to open file at " + tempStr + "."); return false; } if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() >0 ) MapControllerPtr mapController= App::Inst().GetLayerTreeController()->GetLayerTreeModel()->GetStudy(0)->GetMapLayer(0)->GetMapController(); // It appears that shapefiles (*.SHP) only support up to one layer per file // This will need to be further investigated for other vector filetypes (e.g., KML) // For now just grab layer at position 0 OGRLayer *poLayer = OGRDataset->GetLayer( 0 ); // Determine the XY boundaries for the entire vector dataset OGREnvelope psEnvelope; VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel(); poLayer->GetExtent( &psEnvelope ); vectorMapModel->SetVectorBoundary(psEnvelope); if(!SetupVectorProjection(OGRDataset,studyController,poLayer,vectorMapController )) { OGRDataset->DestroyDataSource(OGRDataset); return false; } if(progressDlg) { if(!progressDlg->Update(0, _T("Reading Vector Map Information..."))) { OGRDataset->DestroyDataSource(OGRDataset); return false; } } GLdouble minX, minY, maxX, maxY; minX = minY = std::numeric_limits<float>::max(); maxX = maxY = -std::numeric_limits<float>::max(); // Retrieve features from the dataset OGRFeature *poFeature; poLayer->ResetReading(); int numFeatures = poLayer->GetFeatureCount(); int count=0; //Log::Inst().Write("Loading shapefile with the following meta data:"); while ( ( poFeature = poLayer->GetNextFeature() ) != NULL ) { ///////////////////////////////////////////////// // PHASE 1: Retrieve METADATA from the dataset // ///////////////////////////////////////////////// OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn(); int iField; for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField ); //if( poFieldDefn->GetType() == OFTInteger ) // printf( "%d,", poFeature->GetFieldAsInteger( iField ) ); //else if( poFieldDefn->GetType() == OFTReal ) // printf( "%.3f,", poFeature->GetFieldAsDouble(iField) ); //else if( poFieldDefn->GetType() == OFTString ) // printf( "%s,", poFeature->GetFieldAsString(iField) ); //else // printf( "%s,", poFeature->GetFieldAsString(iField) ); //ofs << poFeature->GetFieldAsString(iField) << ","; std::string metaData = poFeature->GetFieldAsString(iField); // do something with the meta data... //Log::Inst().Write(metaData); } count++; if(progressDlg) { if(!progressDlg->Update(int(50 + (float(count)/numFeatures)*50))) return false; } /////////////////////////////////////////////////// // PHASE 2: Retrieve GEOMETRIES from the dataset // /////////////////////////////////////////////////// OGRGeometry *poGeometry; poGeometry = poFeature->GetGeometryRef(); // Move to the next feature in the set if no geometry present if( poGeometry == NULL ) { OGRFeature::DestroyFeature( poFeature ); continue; } OGRwkbGeometryType whatisit = poGeometry->getGeometryType(); // Handle POINTS if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPoint ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = (OGRPoint *) poGeometry; geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } //Handle MultiPoint else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPoint ) { OGRMultiPoint *poMultiPoint = (OGRMultiPoint *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPoint->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = ( OGRPoint* )poMultiPoint->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } //Handle Polylines else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbLineString ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = (OGRLineString *) poGeometry; geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); // Convert and store the points for ( int currentPoint = 0; currentPoint < poLine->getNumPoints(); currentPoint++ ) { // Convert and store the points if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MultiPolyLine else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiLineString ) { OGRMultiLineString *poMultiLine = (OGRMultiLineString *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiLine->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = ( OGRLineString* )poMultiLine->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLine ->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } // Handle POLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPolygon ) { GeoVector* geoVector = new GeoVector(); OGRPolygon *poPolygon = ( OGRPolygon* )poGeometry; OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MULTIPOLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPolygon ) { OGRMultiPolygon *poMultiPolygon = (OGRMultiPolygon *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPolygon->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); // OGRPolygon http://www.gdal.org/ogr/classOGRPolygon.html OGRPolygon *poPolygon = ( OGRPolygon* )poMultiPolygon->getGeometryRef( currGeometry ); // Retrieve the EXTERNAL ring of the multipolygon OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); // Retrieve all the INTERNAL rings of the multipolygon for ( int currentRing = 0; currentRing < poPolygon->getNumInteriorRings(); currentRing++ ) { GeoVector* geoVector2 = new GeoVector(); poLinearRing = poPolygon->getInteriorRing( currentRing ); geoVector2->SetGeometryType( wkbLinearRing ); geoVector2->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector2->pointX[currentPoint] = x; geoVector2->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector2->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector2->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector2 ); } } } // Report a warning message for unhandled geometries else { Log::Inst().Warning("(Warning) Could not load vector data: unsupported geometry."); } OGRFeature::DestroyFeature( poFeature ); } if (float(minX) == float(maxX) && float(minY) == float(maxY)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } if(needProjection) { vectorMapModel->SetVectorBoundary_MinX(minX); vectorMapModel->SetVectorBoundary_MaxX(maxX); vectorMapModel->SetVectorBoundary_MinY(minY); vectorMapModel->SetVectorBoundary_MaxY(maxY); } if(!SetupVectorScaling(vectorMapModel,progressDlg)) { OGRDataset->DestroyDataSource(OGRDataset); return false; } VectorMetaDataInfo(OGRDataset, studyController, vectorMapController); OGRDataSource::DestroyDataSource( OGRDataset ); return true; }
OGRErr OGRBNALayer::CreateFeature( OGRFeature *poFeature ) { int i,j,k,n; OGRGeometry *poGeom = poFeature->GetGeometryRef(); char eol[3]; const char* partialEol = (poDS->GetMultiLine()) ? eol : poDS->GetCoordinateSeparator(); if (poGeom == NULL || poGeom->IsEmpty() ) { CPLError(CE_Failure, CPLE_AppDefined, "OGR BNA driver cannot write features with empty geometries."); return OGRERR_FAILURE; } if (poDS->GetUseCRLF()) { eol[0] = 13; eol[1] = 10; eol[2] = 0; } else { eol[0] = 10; eol[1] = 0; } if ( ! bWriter ) { return OGRERR_FAILURE; } if( poFeature->GetFID() == OGRNullFID ) poFeature->SetFID( nFeatures++ ); VSILFILE* fp = poDS->GetOutputFP(); int nbPairPerLine = poDS->GetNbPairPerLine(); switch( poGeom->getGeometryType() ) { case wkbPoint: case wkbPoint25D: { OGRPoint* point = (OGRPoint*)poGeom; WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "1"); VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, point->getX(), point->getY()); VSIFPrintfL( fp, "%s", eol); break; } case wkbPolygon: case wkbPolygon25D: { OGRPolygon* polygon = (OGRPolygon*)poGeom; OGRLinearRing* ring = polygon->getExteriorRing(); if (ring == NULL) { return OGRERR_FAILURE; } double firstX = ring->getX(0); double firstY = ring->getY(0); int nBNAPoints = ring->getNumPoints(); int is_ellipse = FALSE; /* This code tries to detect an ellipse in a polygon geometry */ /* This will only work presumably on ellipses already read from a BNA file */ /* Mostly a BNA to BNA feature... */ if (poDS->GetEllipsesAsEllipses() && polygon->getNumInteriorRings() == 0 && nBNAPoints == 361) { double oppositeX = ring->getX(180); double oppositeY = ring->getY(180); double quarterX = ring->getX(90); double quarterY = ring->getY(90); double antiquarterX = ring->getX(270); double antiquarterY = ring->getY(270); double center1X = 0.5*(firstX + oppositeX); double center1Y = 0.5*(firstY + oppositeY); double center2X = 0.5*(quarterX + antiquarterX); double center2Y = 0.5*(quarterY + antiquarterY); if (fabs(center1X - center2X) < 1e-5 && fabs(center1Y - center2Y) < 1e-5 && fabs(oppositeY - firstY) < 1e-5 && fabs(quarterX - antiquarterX) < 1e-5) { double major_radius = fabs(firstX - center1X); double minor_radius = fabs(quarterY - center1Y); is_ellipse = TRUE; for(i=0;i<360;i++) { if (!(fabs(center1X + major_radius * cos(i * (M_PI / 180)) - ring->getX(i)) < 1e-5 && fabs(center1Y + minor_radius * sin(i * (M_PI / 180)) - ring->getY(i)) < 1e-5)) { is_ellipse = FALSE; break; } } if ( is_ellipse == TRUE ) { WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "2"); VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, center1X, center1Y); VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, major_radius, minor_radius); VSIFPrintfL( fp, "%s", eol); } } } if ( is_ellipse == FALSE) { int nInteriorRings = polygon->getNumInteriorRings(); for(i=0;i<nInteriorRings;i++) { nBNAPoints += polygon->getInteriorRing(i)->getNumPoints() + 1; } if (nBNAPoints <= 3) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); return OGRERR_FAILURE; } WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "%d", nBNAPoints); n = ring->getNumPoints(); int nbPair = 0; for(i=0;i<n;i++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(i), ring->getY(i)); nbPair++; } for(i=0;i<nInteriorRings;i++) { ring = polygon->getInteriorRing(i); n = ring->getNumPoints(); for(j=0;j<n;j++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(j), ring->getY(j)); nbPair++; } VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, firstX, firstY); nbPair++; } VSIFPrintfL( fp, "%s", eol); } break; } case wkbMultiPolygon: case wkbMultiPolygon25D: { OGRMultiPolygon* multipolygon = (OGRMultiPolygon*)poGeom; int N = multipolygon->getNumGeometries(); int nBNAPoints = 0; double firstX = 0, firstY = 0; for(i=0;i<N;i++) { OGRPolygon* polygon = (OGRPolygon*)multipolygon->getGeometryRef(i); OGRLinearRing* ring = polygon->getExteriorRing(); if (ring == NULL) continue; if (nBNAPoints) nBNAPoints ++; else { firstX = ring->getX(0); firstY = ring->getY(0); } nBNAPoints += ring->getNumPoints(); int nInteriorRings = polygon->getNumInteriorRings(); for(j=0;j<nInteriorRings;j++) { nBNAPoints += polygon->getInteriorRing(j)->getNumPoints() + 1; } } if (nBNAPoints <= 3) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); return OGRERR_FAILURE; } WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "%d", nBNAPoints); int nbPair = 0; for(i=0;i<N;i++) { OGRPolygon* polygon = (OGRPolygon*)multipolygon->getGeometryRef(i); OGRLinearRing* ring = polygon->getExteriorRing(); if (ring == NULL) continue; n = ring->getNumPoints(); int nInteriorRings = polygon->getNumInteriorRings(); for(j=0;j<n;j++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(j), ring->getY(j)); nbPair++; } if (i != 0) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, firstX, firstY); nbPair++; } for(j=0;j<nInteriorRings;j++) { ring = polygon->getInteriorRing(j); n = ring->getNumPoints(); for(k=0;k<n;k++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(k), ring->getY(k)); nbPair++; } VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, firstX, firstY); nbPair++; } } VSIFPrintfL( fp, "%s", eol); break; } case wkbLineString: case wkbLineString25D: { OGRLineString* line = (OGRLineString*)poGeom; int n = line->getNumPoints(); int i; if (n < 2) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); return OGRERR_FAILURE; } WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "-%d", n); int nbPair = 0; for(i=0;i<n;i++) { VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, line->getX(i), line->getY(i)); nbPair++; } VSIFPrintfL( fp, "%s", eol); break; } default: { CPLError( CE_Failure, CPLE_AppDefined, "Unsupported geometry type : %s.", poGeom->getGeometryName() ); return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } } return OGRERR_NONE; }
void DrawShape::paintMap(WPaintDevice *paintDevice) { WPainter painter(paintDevice); painter.setRenderHint(WPainter::LowQualityShadows); painter.save(); if(!sfile.empty()) { vector<LABELS> label_list; OGRDataSource *poDS,*PointDS; string dfile = sfile + ".shp"; string shp = "g_4326/" + sfile + ".shp"; poDS = OGRSFDriverRegistrar::Open(shp.c_str(), FALSE ); //comment till here if(poDS==NULL) { printf( "Open failed.\n" ); exit( 1 ); } OGRLayer *poLayer; poLayer = poDS->GetLayerByName( sfile.c_str() ); // comment here OGRFeature *poFeature; OGREnvelope * psExtent = new OGREnvelope(); poLayer->GetExtent(psExtent); double xMin = psExtent->MinX; double yMin = psExtent->MinY; double xMax = psExtent->MaxX; double yMax = psExtent->MaxY; stringstream strm; strm << xMin; string exp; double scaleFactor; string bound_string = strm.str(); int size = bound_string.size(); size_t found=bound_string.find("+"); if (found!=string::npos) { exp = bound_string.substr(found+1,size); } if(exp.empty()) { stringstream strExtent; strExtent << yMin; bound_string = strExtent.str(); size = bound_string.size(); found = bound_string.find("+"); if(found!=string::npos) { exp = bound_string.substr(found+1,size); } } if(exp.empty()) { stringstream strExtent; strExtent << xMax; bound_string = strExtent.str(); size = bound_string.size(); found = bound_string.find("+"); if(found!=string::npos) { exp = bound_string.substr(found+1,size); } } if(exp.empty()) { stringstream strExtent; strExtent << yMax; bound_string = strExtent.str(); size = bound_string.size(); found = bound_string.find("+"); if(found!=string::npos) { exp = bound_string.substr(found+1,size); } } //cout << "EXXP: " << exp << endl; if(!exp.empty()) { int exponent = boost::lexical_cast<int>(exp); exponent-=3; scaleFactor = pow (10,exponent); } else { //cout << "EXXP is empty " << exp << endl; scaleFactor = 1; } xMin/=scaleFactor; xMax/=scaleFactor; yMin/=scaleFactor; yMax/=scaleFactor; double gWidth = xMax - xMin; double gHeight = yMax - yMin; double widthFactor = 1; double pwidth = abs(gWidth-gHeight); double s = gWidth - gHeight; if(s<0.16) gWidth = gHeight + 0.16; double ratio=gWidth/gHeight; //for zoom n pan if(increase_width<100 && increase_height<100){ painter.setWindow(xMin +(-x_pos_shift+increase_width/2)/100*gWidth* widthFactor, yMax+(y_pos_shift-increase_height/2)/100*gHeight * widthFactor, gWidth* widthFactor*(100-increase_width)/100, gHeight * widthFactor*(-1+increase_height/100)); brush.setStyle(SolidPattern); brush.setColor(backcolor); painter.setBrush(brush); painter.drawRect(xMin +(-x_pos_shift+increase_width/2)/100*gWidth* widthFactor, yMax+(y_pos_shift-increase_height/2)/100*gHeight * widthFactor, gWidth* widthFactor*(100-increase_width)/100, gHeight * widthFactor*(-1+increase_height/100)); } else{ painter.setWindow(xMin +x_pos_shift, yMax-y_pos_shift, 0, 0); } // for normal picture //painter.setWindow(xMin , yMax, gWidth* widthFactor, -gHeight * widthFactor); pwidth/=480; pwidth*=4; //if(iwidth<0.06) // iwidth=0.06; if(iwidth == 0.0015){ pen.setWidth(pwidth); } else { pen.setWidth(iwidth); } //std::cerr<<pwidth<<" "<<iwidth<<"\n"; pen.setColor(bordercolor); brush.setStyle(SolidPattern); brush.setColor(fillcolor); font= new WFont(); font->setSize(WLength(labelpercentage*gWidth*widthFactor)); painter.setFont(*font); painter.setPen(pen); painter.setBrush(brush); WPainterPath path; poLayer->ResetReading(); OGRPoint *centroid = new OGRPoint(); char label[100]; while( (poFeature = poLayer->GetNextFeature()) != NULL ) { centroid->empty(); label[0]=0; if(labelindex>0) { OGRFeatureDefn *PointFDefn = poLayer->GetLayerDefn(); OGRFieldDefn *PointFieldDefn = PointFDefn->GetFieldDefn(labelindex-1); if( PointFieldDefn->GetType() == OFTInteger ) sprintf(label, "%d", poFeature->GetFieldAsInteger(labelindex-1) ); else if( PointFieldDefn->GetType() == OFTReal ) sprintf(label, "%.3f", poFeature->GetFieldAsDouble(labelindex-1) ); else if( PointFieldDefn->GetType() == OFTString ) sprintf(label, "%s", poFeature->GetFieldAsString(labelindex-1) ); else sprintf(label, "%s", poFeature->GetFieldAsString(labelindex-1) ); } OGRGeometry *poGeometry; poGeometry = poFeature->GetGeometryRef(); if( poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbPoint ) { OGRPoint *poPoint = (OGRPoint *) poGeometry; double x = poPoint->getX(); double y = poPoint->getY(); //painter.drawPoint(x/scaleFactor,y/scaleFactor); painter.drawEllipse(x/scaleFactor-0.005*gWidth*widthFactor,y/scaleFactor-0.005*gWidth*widthFactor,0.01*gWidth*widthFactor,0.01*gWidth*widthFactor); poGeometry->Centroid(centroid); } //end wkbpoint else if( poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbLineString ) { OGRLineString *poPoint = (OGRLineString *) poGeometry; for(int i=0;i<poPoint->getNumPoints();i++) { double x=poPoint->getX(i) ; double y = poPoint->getY(i); x/=scaleFactor; y/=scaleFactor; if(i==0) path = WPainterPath( WPointF(x, y)); else path.lineTo( x , y); } painter.drawPath(path); poGeometry->Centroid(centroid); } else if( (poGeometry != NULL) && wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon) { OGRPolygon *poPoint = (OGRPolygon *) poGeometry; OGRLinearRing *extring = poPoint->getExteriorRing(); int n = extring->getNumPoints(); double x, y; for(int i=0;i<n;i++) { x = extring->getX(i); y = extring->getY(i); x/=scaleFactor; y/=scaleFactor; if(i==0) path = WPainterPath( WPointF(x , y)); else path.lineTo( x , y); } painter.drawPath(path); poGeometry->Centroid(centroid); } else if( (poGeometry != NULL) && wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon) { double x, y; OGRMultiPolygon *poPoint = (OGRMultiPolygon *) poGeometry; int p = poPoint->getNumGeometries(); for(int k=0;k<p;k++) { OGRGeometry* geom = poPoint->getGeometryRef(k); OGRPolygon *poly = (OGRPolygon *) geom; OGRLinearRing *ring = poly->getExteriorRing(); for(int i=0;i<ring->getNumPoints();i++) { x = ring->getX(i); y = ring->getY(i); x/=scaleFactor; y/=scaleFactor; if(i==0) path = WPainterPath( WPointF(x , y)); else path.lineTo( x , y); } painter.drawPath(path); poGeometry->Centroid(centroid); } } if(labelindex>0 && !centroid->IsEmpty()){ LABELS l={centroid->getX(),centroid->getY(),label}; label_list.push_back(l); } } painter.restore(); //labelling the contents if(increase_width<100 && increase_height<100){ painter.setWindow(0.0, 0.0, (paintDevice->width()).value(),(paintDevice->height()).value()); font= new WFont(WFont::SansSerif); font->setSize(WLength(10*labelpercentage)); painter.setFont(*font); pen.setColor(labelcolor); painter.setPen(pen); std::vector<LABELS>::iterator the_iterator = label_list.begin(); double x, y, minx=(xMin+(-x_pos_shift+increase_width/2)/100*gWidth* widthFactor),miny=(yMax+(y_pos_shift-increase_height/2)/100*gHeight*widthFactor); double multx=(paintDevice->width().value())/(gWidth* widthFactor*(100-increase_width)/100); double multy=(paintDevice->height().value())/(gHeight*widthFactor*(-1+increase_height/100)); while( the_iterator != label_list.end() ) { x=((*the_iterator).x/scaleFactor-minx)*multx; y=((*the_iterator).y/scaleFactor-miny)*multy; painter.drawText(WRectF( x-(*the_iterator).label.size()*5*labelpercentage, y-5*labelpercentage, (*the_iterator).label.size() *10*labelpercentage,10*labelpercentage),AlignCenter,(*the_iterator).label); ++the_iterator; } pen.setColor(red); painter.setPen(pen); painter.setFont(*font); //painter.drawText(WRectF(paintDevice->width().value()-dfile.size()*10*labelpercentage,paintDevice->height().value()-10*labelpercentage*(paintDevice->height()).value(), dfile.size()*10*labelpercentage,10*labelpercentage ),AlignCenter,dfile); //this text is not seen in the picture when painted. } } }
OGRFeature* OGRPLScenesLayer::GetNextRawFeature() { if( bEOF || (!bFilterMustBeClientSideEvaluated && nFeatureCount >= 0 && nNextFID > nFeatureCount) ) return NULL; if( poGeoJSONLayer == NULL ) { if( !GetNextPage() ) return NULL; } #ifdef notdef if( CSLTestBoolean(CPLGetConfigOption("OGR_LIMIT_TOO_MANY_FEATURES", "FALSE")) && nFeatureCount > nPageSize ) { bEOF = TRUE; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); OGRGeometry* poGeom; const char* pszWKT = "MULTIPOLYGON(((-180 90,180 90,180 -90,-180 -90,-180 90)))"; OGRGeometryFactory::createFromWkt((char**)&pszWKT, poSRS, &poGeom); poFeature->SetGeometryDirectly(poGeom); return poFeature; } #endif OGRFeature* poGeoJSONFeature = poGeoJSONLayer->GetNextFeature(); if( poGeoJSONFeature == NULL ) { osRequestURL = osNextURL; bStillInFirstPage = FALSE; if( !GetNextPage() ) return NULL; poGeoJSONFeature = poGeoJSONLayer->GetNextFeature(); if( poGeoJSONFeature == NULL ) { bEOF = TRUE; return NULL; } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID++); OGRGeometry* poGeom = poGeoJSONFeature->StealGeometry(); if( poGeom != NULL ) { if( poGeom->getGeometryType() == wkbPolygon ) { OGRMultiPolygon* poMP = new OGRMultiPolygon(); poMP->addGeometryDirectly(poGeom); poGeom = poMP; } poGeom->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poGeom); } for(int i=0;i<poFeatureDefn->GetFieldCount();i++) { OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i); OGRFieldType eType = poFieldDefn->GetType(); int iSrcField = poGeoJSONFeature->GetFieldIndex(poFieldDefn->GetNameRef()); if( iSrcField >= 0 && poGeoJSONFeature->IsFieldSet(iSrcField) ) { if( eType == OFTInteger ) poFeature->SetField(i, poGeoJSONFeature->GetFieldAsInteger(iSrcField)); else if( eType == OFTReal ) poFeature->SetField(i, poGeoJSONFeature->GetFieldAsDouble(iSrcField)); else poFeature->SetField(i, poGeoJSONFeature->GetFieldAsString(iSrcField)); } } delete poGeoJSONFeature; return poFeature; }
void OGRILI1Layer::PolygonizeAreaLayer( OGRILI1Layer* poAreaLineLayer, int nAreaFieldIndex, int nPointFieldIndex ) { //add all lines from poAreaLineLayer to collection OGRGeometryCollection *gc = new OGRGeometryCollection(); poAreaLineLayer->ResetReading(); while (OGRFeature *feature = poAreaLineLayer->GetNextFeatureRef()) gc->addGeometry(feature->GetGeometryRef()); //polygonize lines CPLDebug( "OGR_ILI", "Polygonizing layer %s with %d multilines", poAreaLineLayer->GetLayerDefn()->GetName(), gc->getNumGeometries()); poAreaLineLayer = 0; OGRMultiPolygon* polys = Polygonize( gc , false); CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries()); if (polys->getNumGeometries() != GetFeatureCount()) { CPLDebug( "OGR_ILI", "Feature count of layer %s: " CPL_FRMT_GIB, GetLayerDefn()->GetName(), GetFeatureCount()); CPLDebug( "OGR_ILI", "Polygonizing again with crossing line fix"); delete polys; polys = Polygonize( gc, true ); //try again with crossing line fix CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries()); } delete gc; //associate polygon feature with data row according to centroid #if defined(HAVE_GEOS) int i; OGRPolygon emptyPoly; GEOSGeom *ahInGeoms = NULL; CPLDebug( "OGR_ILI", "Associating layer %s with area polygons", GetLayerDefn()->GetName()); ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*), polys->getNumGeometries()); GEOSContextHandle_t hGEOSCtxt = OGRGeometry::createGEOSContext(); for( i = 0; i < polys->getNumGeometries(); i++ ) { ahInGeoms[i] = polys->getGeometryRef(i)->exportToGEOS(hGEOSCtxt); if (!GEOSisValid_r(hGEOSCtxt, ahInGeoms[i])) ahInGeoms[i] = NULL; } for ( int nFidx = 0; nFidx < nFeatures; nFidx++) { OGRFeature *feature = papoFeatures[nFidx]; OGRGeometry* geomRef = feature->GetGeomFieldRef(nPointFieldIndex); if( !geomRef ) { continue; } GEOSGeom point = (GEOSGeom)(geomRef->exportToGEOS(hGEOSCtxt)); for (i = 0; i < polys->getNumGeometries(); i++ ) { if (ahInGeoms[i] && GEOSWithin_r(hGEOSCtxt, point, ahInGeoms[i])) { feature->SetGeomField(nAreaFieldIndex, polys->getGeometryRef(i)); break; } } if (i == polys->getNumGeometries()) { CPLDebug( "OGR_ILI", "Association between area and point failed."); feature->SetGeometry( &emptyPoly ); } GEOSGeom_destroy_r( hGEOSCtxt, point ); } for( i = 0; i < polys->getNumGeometries(); i++ ) GEOSGeom_destroy_r( hGEOSCtxt, ahInGeoms[i] ); CPLFree( ahInGeoms ); OGRGeometry::freeGEOSContext( hGEOSCtxt ); #endif poAreaLineLayer = 0; delete polys; }
OGRFeature * OGRBNALayer::BuildFeatureFromBNARecord (BNARecord* record, long fid) { OGRFeature *poFeature; int i; poFeature = new OGRFeature( poFeatureDefn ); for(i=0;i<nIDs;i++) { poFeature->SetField( i, record->ids[i] ? record->ids[i] : ""); } poFeature->SetFID( fid ); if (bnaFeatureType == BNA_POINT) { poFeature->SetGeometryDirectly( new OGRPoint( record->tabCoords[0][0], record->tabCoords[0][1] ) ); } else if (bnaFeatureType == BNA_POLYLINE) { OGRLineString* lineString = new OGRLineString (); lineString->setCoordinateDimension(2); lineString->setNumPoints(record->nCoords); for(i=0;i<record->nCoords;i++) { lineString->setPoint(i, record->tabCoords[i][0], record->tabCoords[i][1] ); } poFeature->SetGeometryDirectly(lineString); } else if (bnaFeatureType == BNA_POLYGON) { double firstX = record->tabCoords[0][0]; double firstY = record->tabCoords[0][1]; int isFirstPolygon = 1; double secondaryFirstX = 0, secondaryFirstY = 0; OGRLinearRing* ring = new OGRLinearRing (); ring->setCoordinateDimension(2); ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] ); /* record->nCoords is really a safe upper bound */ int nbPolygons = 0; OGRPolygon** tabPolygons = (OGRPolygon**)CPLMalloc(record->nCoords * sizeof(OGRPolygon*)); for(i=1;i<record->nCoords;i++) { ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); if (isFirstPolygon == 1 && record->tabCoords[i][0] == firstX && record->tabCoords[i][1] == firstY) { OGRPolygon* polygon = new OGRPolygon (); polygon->addRingDirectly(ring); tabPolygons[nbPolygons] = polygon; nbPolygons++; if (i == record->nCoords - 1) { break; } isFirstPolygon = 0; i ++; secondaryFirstX = record->tabCoords[i][0]; secondaryFirstY = record->tabCoords[i][1]; ring = new OGRLinearRing (); ring->setCoordinateDimension(2); ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); } else if (isFirstPolygon == 0 && record->tabCoords[i][0] == secondaryFirstX && record->tabCoords[i][1] == secondaryFirstY) { OGRPolygon* polygon = new OGRPolygon (); polygon->addRingDirectly(ring); tabPolygons[nbPolygons] = polygon; nbPolygons++; if (i < record->nCoords - 1) { /* After the closing of a subpolygon, the first coordinates of the first polygon */ /* should be recalled... in theory */ if (record->tabCoords[i+1][0] == firstX && record->tabCoords[i+1][1] == firstY) { if (i + 1 == record->nCoords - 1) break; i ++; } else { #if 0 CPLError(CE_Warning, CPLE_AppDefined, "Geometry of polygon of fid %d starting at line %d is not strictly conformant. " "Trying to go on...\n", fid, offsetAndLineFeaturesTable[fid].line + 1); #endif } i ++; secondaryFirstX = record->tabCoords[i][0]; secondaryFirstY = record->tabCoords[i][1]; ring = new OGRLinearRing (); ring->setCoordinateDimension(2); ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); } else { #if 0 CPLError(CE_Warning, CPLE_AppDefined, "Geometry of polygon of fid %d starting at line %d is not strictly conformant. Trying to go on...\n", fid, offsetAndLineFeaturesTable[fid].line + 1); #endif } } } if (i == record->nCoords) { /* Let's be a bit tolerant abount non closing polygons */ if (isFirstPolygon) { ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] ); OGRPolygon* polygon = new OGRPolygon (); polygon->addRingDirectly(ring); tabPolygons[nbPolygons] = polygon; nbPolygons++; } } if (nbPolygons == 1) { /* Special optimization here : we directly put the polygon into the multipolygon. */ /* This should save quite a few useless copies */ OGRMultiPolygon* multipolygon = new OGRMultiPolygon(); multipolygon->addGeometryDirectly(tabPolygons[0]); poFeature->SetGeometryDirectly(multipolygon); } else { int isValidGeometry; poFeature->SetGeometryDirectly( OGRGeometryFactory::organizePolygons((OGRGeometry**)tabPolygons, nbPolygons, &isValidGeometry, NULL)); if (!isValidGeometry) { CPLError(CE_Warning, CPLE_AppDefined, "Geometry of polygon of fid %ld starting at line %d cannot be translated to Simple Geometry. " "All polygons will be contained in a multipolygon.\n", fid, offsetAndLineFeaturesTable[fid].line + 1); } } CPLFree(tabPolygons); } else { /* Circle or ellipses are not part of the OGR Simple Geometry, so we discretize them into polygons by 1 degree step */ OGRPolygon* polygon = new OGRPolygon (); OGRLinearRing* ring = new OGRLinearRing (); ring->setCoordinateDimension(2); double center_x = record->tabCoords[0][0]; double center_y = record->tabCoords[0][1]; double major_radius = record->tabCoords[1][0]; double minor_radius = record->tabCoords[1][1]; if (minor_radius == 0) minor_radius = major_radius; for(i=0;i<360;i++) { ring->addPoint(center_x + major_radius * cos(i * (M_PI / 180)), center_y + minor_radius * sin(i * (M_PI / 180)) ); } ring->addPoint(center_x + major_radius, center_y); polygon->addRingDirectly ( ring ); poFeature->SetGeometryDirectly(polygon); poFeature->SetField( nIDs, major_radius); poFeature->SetField( nIDs+1, minor_radius); } return poFeature; }
int main (int argc, const char * argv[]) { time_t startTime = time(NULL); if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { usage(); return(0); } OGRGeometry *geometry; for (int argNum = 1; argNum < argc; ++argNum) { //-- whether to compute the robustness or not if (strcmp(argv[argNum], "--robustness") == 0) { computeRobustness = true; } //-- whether to use the point set topology paradigm or not //-- if not, odd-even paradigm is used by default else if (strcmp(argv[argNum], "--setdiff") == 0) { pointSet = true; } //-- mininum area to keep in output else if (strcmp(argv[argNum], "--minarea") == 0) { minArea = atof(argv[argNum+1]); ++argNum; } //-- ISR snapping tolerance else if (strcmp(argv[argNum], "--isr") == 0) { isrTolerance = atof(argv[argNum+1]); ++argNum; // TODO : scale dataset if tolerance < 1.0 because of CGAL bug } //-- output a shapefile (out.shp) instead of a WKT else if (strcmp(argv[argNum], "--shpOut") == 0) { shpOut = true; } //-- time the results else if (strcmp(argv[argNum], "--time") == 0) { timeResults = true; } //-- reading from WKT passed directly else if (strcmp(argv[argNum], "--wkt") == 0) { unsigned int bufferSize = 100000000; char *inputWKT = (char *)malloc(bufferSize*sizeof(char)); strcpy(inputWKT, argv[argNum+1]); ++argNum; OGRErr err = OGRGeometryFactory::createFromWkt(&inputWKT, NULL, &geometry); if (err != OGRERR_NONE) { switch (err) { case OGRERR_UNSUPPORTED_GEOMETRY_TYPE: std::cerr << "Error: geometry must be Polygon or MultiPolygon" << std::endl; break; case OGRERR_NOT_ENOUGH_DATA: case OGRERR_CORRUPT_DATA: std::cerr << "Error: corrupted input" << std::endl; break; default: std::cerr << "Error: corrupted input" << std::endl; break; } return 1; } if (geometry->IsEmpty() == 1) { std::cerr << "Error: empty geometry" << std::endl; return 1; } if ( (geometry->getGeometryType() != wkbPolygon) && (geometry->getGeometryType() != wkbMultiPolygon) ) { std::cerr << "Error: geometry must be Polygon or MultiPolygon" << std::endl; return 1; } } //-- reading from WKT stored in first line of a text file else if (strcmp(argv[argNum], "-f") == 0) { unsigned int bufferSize = 100000000; char *inputWKT = (char *)malloc(bufferSize*sizeof(char)); if (argNum + 1 <= argc - 1 && argv[argNum+1][0] != '-') { std::ifstream infile(argv[argNum+1], std::ifstream::in); infile.getline(inputWKT, bufferSize); ++argNum; } else { std::cerr << "Error: Missing input file name." << std::endl; return 1; } OGRGeometryFactory::createFromWkt(&inputWKT, NULL, &geometry); if (geometry == NULL) { std::cout << "Error: WKT is not valid" << std::endl; return 1; } } //-- reading from a ogr dataset (most supported: shp, geojson, gml, etc) else if (strcmp(argv[argNum], "--ogr") == 0) { OGRRegisterAll(); OGRDataSource *dataSource = OGRSFDriverRegistrar::Open(argv[argNum+1], false); ++argNum; if (dataSource == NULL) { std::cerr << "Error: Could not open file." << std::endl; return false; } OGRLayer *dataLayer = dataSource->GetLayer(0); //-- get first layer dataLayer->ResetReading(); //-- Reads all features in this layer OGRFeature *feature; //-- get first feature if (dataLayer->GetFeatureCount(true) > 1) std::cout << "Reading only the first feature in the shapefile." << std::endl; feature = dataLayer->GetNextFeature(); if (feature->GetGeometryRef()->getGeometryType() == wkbPolygon) { geometry = static_cast<OGRPolygon *>(feature->GetGeometryRef());feature->GetGeometryRef(); } else { std::cout << "First feature ain't a POLYGON." << std::endl; return(0); } } else { usage(); return(0); } } if (!timeResults) startTime = 0; PolygonRepair prepair; //-- compute robustness if (computeRobustness == true) std::cout << "Robustness of input polygon: " << sqrt(prepair.computeRobustness(geometry)) <<std::endl; OGRMultiPolygon *outPolygons; if (pointSet) { outPolygons = prepair.repairPointSet(geometry, startTime); } else { outPolygons = prepair.repairOddEven(geometry, startTime); } if (minArea > 0) { prepair.removeSmallPolygons(outPolygons, minArea); } //-- output well known text if (shpOut) { prepair.saveToShp(outPolygons, "out.shp"); } else { char *outputWKT; outPolygons->exportToWkt(&outputWKT); std::cout << outputWKT << std::endl; } //-- compute robustness if (computeRobustness == true) std::cout << "Robustness of output polygon: " << sqrt(prepair.computeRobustness()) <<std::endl; //-- time results if (timeResults) { time_t totalTime = time(NULL)-startTime; std::cout << "Done! Process finished in " << totalTime/60 << " minutes " << totalTime%60 << " seconds." << std::endl; } return 0; }
void OGRILI1Layer::PolygonizeAreaLayer() { if (poAreaLineLayer == 0) return; //add all lines from poAreaLineLayer to collection OGRGeometryCollection *gc = new OGRGeometryCollection(); poAreaLineLayer->ResetReading(); while (OGRFeature *feature = poAreaLineLayer->GetNextFeatureRef()) gc->addGeometry(feature->GetGeometryRef()); //polygonize lines CPLDebug( "OGR_ILI", "Polygonizing layer %s with %d multilines", poAreaLineLayer->GetLayerDefn()->GetName(), gc->getNumGeometries()); OGRMultiPolygon* polys = Polygonize( gc , false); CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries()); if (polys->getNumGeometries() != poAreaReferenceLayer->GetFeatureCount()) { CPLDebug( "OGR_ILI", "Feature count of layer %s: %d", poAreaReferenceLayer->GetLayerDefn()->GetName(), GetFeatureCount()); CPLDebug( "OGR_ILI", "Polygonizing again with crossing line fix"); delete polys; polys = Polygonize( gc, true ); //try again with crossing line fix } delete gc; //associate polygon feature with data row according to centroid #if defined(HAVE_GEOS) int i; OGRPolygon emptyPoly; GEOSGeom *ahInGeoms = NULL; CPLDebug( "OGR_ILI", "Associating layer %s with area polygons", GetLayerDefn()->GetName()); ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*),polys->getNumGeometries()); for( i = 0; i < polys->getNumGeometries(); i++ ) { ahInGeoms[i] = polys->getGeometryRef(i)->exportToGEOS(); if (!GEOSisValid(ahInGeoms[i])) ahInGeoms[i] = NULL; } poAreaReferenceLayer->ResetReading(); while (OGRFeature *feature = poAreaReferenceLayer->GetNextFeatureRef()) { GEOSGeom point = (GEOSGeom)feature->GetGeometryRef()->exportToGEOS(); for (i = 0; i < polys->getNumGeometries(); i++ ) { if (ahInGeoms[i] && GEOSWithin(point, ahInGeoms[i])) { OGRFeature* areaFeature = feature->Clone(); areaFeature->SetGeometry( polys->getGeometryRef(i) ); AddFeature(areaFeature); break; } } if (i == polys->getNumGeometries()) { CPLDebug( "OGR_ILI", "Association between area and point failed."); feature->SetGeometry( &emptyPoly ); } GEOSGeom_destroy( point ); } for( i = 0; i < polys->getNumGeometries(); i++ ) GEOSGeom_destroy( ahInGeoms[i] ); CPLFree( ahInGeoms ); #endif poAreaReferenceLayer = 0; poAreaLineLayer = 0; }
OGRErr OGRCARTODBTableLayer::ICreateFeature( OGRFeature *poFeature ) { int i; if( bDeferedCreation ) { if( RunDeferedCreationIfNecessary() != OGRERR_NONE ) return OGRERR_FAILURE; } GetLayerDefn(); int bHasUserFieldMatchingFID = FALSE; if( osFIDColName.size() ) bHasUserFieldMatchingFID = poFeatureDefn->GetFieldIndex(osFIDColName) >= 0; if (!poDS->IsReadWrite()) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return OGRERR_FAILURE; } CPLString osSQL; int bHasJustGotNextFID = FALSE; if( !bHasUserFieldMatchingFID && bInDeferedInsert && nNextFID < 0 && osFIDColName.size() ) { osSQL.Printf("SELECT nextval('%s') AS nextid", OGRCARTODBEscapeLiteral(CPLSPrintf("%s_%s_seq", osName.c_str(), osFIDColName.c_str())).c_str()); json_object* poObj = poDS->RunSQL(osSQL); json_object* poRowObj = OGRCARTODBGetSingleRow(poObj); if( poRowObj != NULL ) { json_object* poID = json_object_object_get(poRowObj, "nextid"); if( poID != NULL && json_object_get_type(poID) == json_type_int ) { nNextFID = json_object_get_int64(poID); bHasJustGotNextFID = TRUE; } } if( poObj != NULL ) json_object_put(poObj); } osSQL.Printf("INSERT INTO %s ", OGRCARTODBEscapeIdentifier(osName).c_str()); int bMustComma = FALSE; for(i = 0; i < poFeatureDefn->GetFieldCount(); i++) { if( !poFeature->IsFieldSet(i) ) continue; if( bMustComma ) osSQL += ", "; else { osSQL += "("; bMustComma = TRUE; } osSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetFieldDefn(i)->GetNameRef()); } for(i = 0; i < poFeatureDefn->GetGeomFieldCount(); i++) { if( poFeature->GetGeomFieldRef(i) == NULL ) continue; if( bMustComma ) osSQL += ", "; else { osSQL += "("; bMustComma = TRUE; } osSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetGeomFieldDefn(i)->GetNameRef()); } if( !bHasUserFieldMatchingFID && osFIDColName.size() && (poFeature->GetFID() != OGRNullFID || nNextFID >= 0) ) { if( bMustComma ) osSQL += ", "; else { osSQL += "("; bMustComma = TRUE; } osSQL += OGRCARTODBEscapeIdentifier(osFIDColName); } if( !bMustComma ) osSQL += " DEFAULT VALUES"; else { osSQL += ") VALUES ("; bMustComma = FALSE; for(i = 0; i < poFeatureDefn->GetFieldCount(); i++) { if( !poFeature->IsFieldSet(i) ) continue; if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; OGRFieldType eType = poFeatureDefn->GetFieldDefn(i)->GetType(); if( eType == OFTString || eType == OFTDateTime || eType == OFTDate || eType == OFTTime ) { osSQL += "'"; osSQL += OGRCARTODBEscapeLiteral(poFeature->GetFieldAsString(i)); osSQL += "'"; } else if( (eType == OFTInteger || eType == OFTInteger64) && poFeatureDefn->GetFieldDefn(i)->GetSubType() == OFSTBoolean ) { osSQL += poFeature->GetFieldAsInteger(i) ? "'t'" : "'f'"; } else osSQL += poFeature->GetFieldAsString(i); } for(i = 0; i < poFeatureDefn->GetGeomFieldCount(); i++) { OGRGeometry* poGeom = poFeature->GetGeomFieldRef(i); if( poGeom == NULL ) continue; if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; OGRCartoDBGeomFieldDefn* poGeomFieldDefn = (OGRCartoDBGeomFieldDefn *)poFeatureDefn->GetGeomFieldDefn(i); int nSRID = poGeomFieldDefn->nSRID; if( nSRID == 0 ) nSRID = 4326; char* pszEWKB; if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon && wkbFlatten(GetGeomType()) == wkbMultiPolygon ) { OGRMultiPolygon* poNewGeom = new OGRMultiPolygon(); poNewGeom->addGeometry(poGeom); pszEWKB = OGRGeometryToHexEWKB(poNewGeom, nSRID, FALSE); delete poNewGeom; } else pszEWKB = OGRGeometryToHexEWKB(poGeom, nSRID, FALSE); osSQL += "'"; osSQL += pszEWKB; osSQL += "'"; CPLFree(pszEWKB); } if( !bHasUserFieldMatchingFID ) { if( osFIDColName.size() && nNextFID >= 0 ) { if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; if( bHasJustGotNextFID ) { osSQL += CPLSPrintf(CPL_FRMT_GIB, nNextFID); } else { osSQL += CPLSPrintf("nextval('%s')", OGRCARTODBEscapeLiteral(CPLSPrintf("%s_%s_seq", osName.c_str(), osFIDColName.c_str())).c_str()); } poFeature->SetFID(nNextFID); nNextFID ++; } else if( osFIDColName.size() && poFeature->GetFID() != OGRNullFID ) { if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; osSQL += CPLSPrintf(CPL_FRMT_GIB, poFeature->GetFID()); } } osSQL += ")"; } if( bInDeferedInsert ) { OGRErr eRet = OGRERR_NONE; if( osDeferedInsertSQL.size() != 0 && (int)osDeferedInsertSQL.size() + (int)osSQL.size() > nMaxChunkSize ) { osDeferedInsertSQL = "BEGIN;" + osDeferedInsertSQL + "COMMIT;"; json_object* poObj = poDS->RunSQL(osDeferedInsertSQL); if( poObj != NULL ) json_object_put(poObj); else { bInDeferedInsert = FALSE; eRet = OGRERR_FAILURE; } osDeferedInsertSQL = ""; } osDeferedInsertSQL += osSQL; osDeferedInsertSQL += ";"; if( (int)osDeferedInsertSQL.size() > nMaxChunkSize ) { osDeferedInsertSQL = "BEGIN;" + osDeferedInsertSQL + "COMMIT;"; json_object* poObj = poDS->RunSQL(osDeferedInsertSQL); if( poObj != NULL ) json_object_put(poObj); else { bInDeferedInsert = FALSE; eRet = OGRERR_FAILURE; } osDeferedInsertSQL = ""; } return eRet; } if( osFIDColName.size() ) { osSQL += " RETURNING "; osSQL += OGRCARTODBEscapeIdentifier(osFIDColName); json_object* poObj = poDS->RunSQL(osSQL); json_object* poRowObj = OGRCARTODBGetSingleRow(poObj); if( poRowObj == NULL ) { if( poObj != NULL ) json_object_put(poObj); return OGRERR_FAILURE; } json_object* poID = json_object_object_get(poRowObj, osFIDColName); if( poID != NULL && json_object_get_type(poID) == json_type_int ) { poFeature->SetFID(json_object_get_int64(poID)); } if( poObj != NULL ) json_object_put(poObj); return OGRERR_NONE; } else { OGRErr eRet = OGRERR_FAILURE; json_object* poObj = poDS->RunSQL(osSQL); if( poObj != NULL ) { json_object* poTotalRows = json_object_object_get(poObj, "total_rows"); if( poTotalRows != NULL && json_object_get_type(poTotalRows) == json_type_int ) { int nTotalRows = json_object_get_int(poTotalRows); if( nTotalRows == 1 ) { eRet = OGRERR_NONE; } } json_object_put(poObj); } return eRet; } }
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; }
OGRFeature *OGRGmtLayer::GetNextRawFeature() { #if 0 int bMultiVertex = poFeatureDefn->GetGeomType() != wkbPoint && poFeatureDefn->GetGeomType() != wkbUnknown; #endif CPLString osFieldData; OGRGeometry *poGeom = NULL; /* -------------------------------------------------------------------- */ /* Read lines associated with this feature. */ /* -------------------------------------------------------------------- */ for( ; true; ReadLine() ) { if( osLine.length() == 0 ) break; if( osLine[0] == '>' ) { if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) { OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom; if( ScanAheadForHole() ) { // Add a hole to the current polygon. ((OGRPolygon *) poMP->getGeometryRef( poMP->getNumGeometries()-1 ))-> addRingDirectly( new OGRLinearRing() ); } else if( !NextIsFeature() ) { OGRPolygon *poPoly = new OGRPolygon(); poPoly->addRingDirectly( new OGRLinearRing() ); poMP->addGeometryDirectly( poPoly ); } else break; /* done geometry */ } else if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon) { if( ScanAheadForHole() ) ((OGRPolygon *)poGeom)-> addRingDirectly( new OGRLinearRing() ); else break; /* done geometry */ } else if( poGeom != NULL && (wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString) && !NextIsFeature() ) { ((OGRMultiLineString *) poGeom)-> addGeometryDirectly( new OGRLineString() ); } else if( poGeom != NULL ) { break; } else if( poFeatureDefn->GetGeomType() == wkbUnknown ) { poFeatureDefn->SetGeomType( wkbLineString ); /* bMultiVertex = TRUE; */ } } else if( osLine[0] == '#' ) { for( int i = 0; papszKeyedValues != NULL && papszKeyedValues[i] != NULL; i++ ) { if( papszKeyedValues[i][0] == 'D' ) osFieldData = papszKeyedValues[i] + 1; } } else { // Parse point line. double dfX; double dfY; double dfZ = 0.0; const int nDim = CPLsscanf( osLine, "%lf %lf %lf", &dfX, &dfY, &dfZ ); if( nDim >= 2 ) { if( poGeom == NULL ) { switch( poFeatureDefn->GetGeomType() ) { case wkbLineString: poGeom = new OGRLineString(); break; case wkbPolygon: poGeom = new OGRPolygon(); reinterpret_cast<OGRPolygon *>(poGeom)->addRingDirectly( new OGRLinearRing() ); break; case wkbMultiPolygon: { OGRPolygon *poPoly = new OGRPolygon(); poPoly->addRingDirectly( new OGRLinearRing() ); poGeom = new OGRMultiPolygon(); reinterpret_cast<OGRMultiPolygon *>(poGeom)-> addGeometryDirectly( poPoly ); } break; case wkbMultiPoint: poGeom = new OGRMultiPoint(); break; case wkbMultiLineString: poGeom = new OGRMultiLineString(); reinterpret_cast<OGRMultiLineString *>(poGeom)-> addGeometryDirectly(new OGRLineString() ); break; case wkbPoint: case wkbUnknown: default: poGeom = new OGRPoint(); break; } } switch( wkbFlatten(poGeom->getGeometryType()) ) { case wkbPoint: reinterpret_cast<OGRPoint *>(poGeom)->setX( dfX ); reinterpret_cast<OGRPoint *>(poGeom)->setY( dfY ); if( nDim == 3 ) reinterpret_cast<OGRPoint *>(poGeom)->setZ( dfZ ); break; case wkbLineString: if( nDim == 3 ) reinterpret_cast<OGRLineString *>(poGeom)-> addPoint( dfX, dfY, dfZ); else reinterpret_cast<OGRLineString *>(poGeom)-> addPoint( dfX, dfY ); break; case wkbPolygon: case wkbMultiPolygon: { OGRPolygon *poPoly = NULL; if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) { OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom; poPoly = (OGRPolygon*) poMP->getGeometryRef( poMP->getNumGeometries() - 1 ); } else poPoly = reinterpret_cast<OGRPolygon *>(poGeom); OGRLinearRing *poRing = NULL; if( poPoly->getNumInteriorRings() == 0 ) poRing = poPoly->getExteriorRing(); else poRing = poPoly->getInteriorRing( poPoly->getNumInteriorRings()-1 ); if( nDim == 3 ) poRing->addPoint( dfX, dfY, dfZ ); else poRing->addPoint( dfX, dfY ); } break; case wkbMultiLineString: { OGRMultiLineString *poML = (OGRMultiLineString *) poGeom; OGRLineString *poLine = reinterpret_cast<OGRLineString *>( poML->getGeometryRef( poML->getNumGeometries() -1 ) ); if( nDim == 3 ) poLine->addPoint( dfX, dfY, dfZ ); else poLine->addPoint( dfX, dfY ); } break; default: CPLAssert( FALSE ); } } } if( poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) { ReadLine(); break; } } if( poGeom == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Create feature. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); poGeom->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poGeom ); poFeature->SetFID( iNextFID++ ); /* -------------------------------------------------------------------- */ /* Process field values. */ /* -------------------------------------------------------------------- */ char **papszFD = CSLTokenizeStringComplex( osFieldData, "|", TRUE, TRUE ); for( int iField = 0; papszFD != NULL && papszFD[iField] != NULL; iField++ ) { if( iField >= poFeatureDefn->GetFieldCount() ) break; poFeature->SetField( iField, papszFD[iField] ); } CSLDestroy( papszFD ); m_nFeaturesRead++; return poFeature; }