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; }
bool MapWidget::loadCountyShapes() { OGRRegisterAll(); std::string filename = g_dataDirectory + "/counties/tl_2009_48_county00.shp"; OGRDataSource * dataSource = OGRSFDriverRegistrar::Open(filename.c_str(), false); if(dataSource == NULL) { put_flog(LOG_ERROR, "could not open %s", filename.c_str()); return false; } OGRLayer * layer = dataSource->GetLayerByName("tl_2009_48_county00"); layer->ResetReading(); OGRFeature * feature; while((feature = layer->GetNextFeature()) != NULL) { // get county FIPS code int nodeId = feature->GetFieldAsInteger("COUNTYFP00"); if(nodeId == 0) { put_flog(LOG_WARN, "invalid county"); } // add a new county to the counties map corresponding to this nodeId boost::shared_ptr<MapShape> county(new MapShape()); counties_[nodeId] = county; OGRGeometry * geometry = feature->GetGeometryRef(); if(geometry != NULL && geometry->getGeometryType() == wkbPolygon) { OGRPolygon * polygon = (OGRPolygon *)geometry; OGRLinearRing * ring = polygon->getExteriorRing(); for(int i=0; i<ring->getNumPoints(); i++) { // x is longitude, y latitude county->addVertex(ring->getY(i), ring->getX(i)); } // set the centroid OGRPoint centroidPoint; if(polygon->Centroid(¢roidPoint) == OGRERR_NONE) { county->setCentroid(centroidPoint.getY(), centroidPoint.getX()); } else { put_flog(LOG_WARN, "no polygon centroid"); } } else { put_flog(LOG_WARN, "no polygon geometry"); } OGRFeature::DestroyFeature(feature); } OGRDataSource::DestroyDataSource(dataSource); return true; }