boost::optional<mapnik::datasource_geometry_t> ogr_datasource::get_geometry_type() const { boost::optional<mapnik::datasource_geometry_t> result; if (dataset_ && layer_.is_valid()) { OGRLayer* layer = layer_.layer(); // NOTE: wkbFlatten macro in ogr flattens 2.5d types into base 2d type #if GDAL_VERSION_NUM < 1800 switch (wkbFlatten(layer->GetLayerDefn()->GetGeomType())) #else switch (wkbFlatten(layer->GetGeomType())) #endif { case wkbPoint: case wkbMultiPoint: result.reset(mapnik::datasource_geometry_t::Point); break; case wkbLinearRing: case wkbLineString: case wkbMultiLineString: result.reset(mapnik::datasource_geometry_t::LineString); break; case wkbPolygon: case wkbMultiPolygon: result.reset(mapnik::datasource_geometry_t::Polygon); break; case wkbGeometryCollection: result.reset(mapnik::datasource_geometry_t::Collection); break; case wkbNone: case wkbUnknown: { // fallback to inspecting first actual geometry // TODO - csv and shapefile inspect first 4 features if (dataset_ && layer_.is_valid()) { layer = layer_.layer(); // only new either reset of setNext //layer->ResetReading(); layer->SetNextByIndex(0); OGRFeature *poFeature; while ((poFeature = layer->GetNextFeature()) != nullptr) { OGRGeometry* geom = poFeature->GetGeometryRef(); if (geom && ! geom->IsEmpty()) { switch (wkbFlatten(geom->getGeometryType())) { case wkbPoint: case wkbMultiPoint: result.reset(mapnik::datasource_geometry_t::Point); break; case wkbLinearRing: case wkbLineString: case wkbMultiLineString: result.reset(mapnik::datasource_geometry_t::LineString); break; case wkbPolygon: case wkbMultiPolygon: result.reset(mapnik::datasource_geometry_t::Polygon); break; case wkbGeometryCollection: result.reset(mapnik::datasource_geometry_t::Collection); break; default: break; } } OGRFeature::DestroyFeature( poFeature ); break; } } break; } default: break; } } return result; }