Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/gdal-1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Commandeur committed May 18, 2017
2 parents b64f76f + 81a56ec commit 47af189
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 105 deletions.
4 changes: 2 additions & 2 deletions Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ void Bridge::get_citygml_imgeo(std::ofstream& of) {
of << "</cityObjectMember>\n";
}

bool Bridge::get_shape(OGRLayer* layer) {
return TopoFeature::get_multipolygon_features(layer, "Bridge");
bool Bridge::get_shape(OGRLayer* layer, bool writeAttributes) {
return TopoFeature::get_multipolygon_features(layer, "Bridge", writeAttributes);
}
2 changes: 1 addition & 1 deletion Bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Bridge: public Flat {
void get_citygml(std::ofstream& of);
void get_citygml_imgeo(std::ofstream& of);
std::string get_mtl();
bool get_shape(OGRLayer * layer);
bool get_shape(OGRLayer* layer, bool writeAttributes);
TopoClass get_class();
bool is_hard();
static float _heightref;
Expand Down
4 changes: 2 additions & 2 deletions Building.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,6 @@ void Building::get_imgeo_nummeraanduiding(std::ofstream& of) {
}
}

bool Building::get_shape(OGRLayer* layer) {
return TopoFeature::get_multipolygon_features(layer, "Building", true, this->get_height_base(), this->get_height());
bool Building::get_shape(OGRLayer* layer, bool writeAttributes) {
return TopoFeature::get_multipolygon_features(layer, "Building", writeAttributes, true, this->get_height_base(), this->get_height());
}
2 changes: 1 addition & 1 deletion Building.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Building: public Flat {
void get_csv(std::ofstream& of);
std::string get_all_z_values();
std::string get_mtl();
bool get_shape(OGRLayer * layer);
bool get_shape(OGRLayer* layer, bool writeAttributes);
TopoClass get_class();
bool is_hard();
int get_height_base();
Expand Down
4 changes: 2 additions & 2 deletions Forest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,6 @@ void Forest::get_citygml_imgeo(std::ofstream& of) {
of << "</cityObjectMember>\n";
}

bool Forest::get_shape(OGRLayer* layer) {
return TopoFeature::get_multipolygon_features(layer, "Forest");
bool Forest::get_shape(OGRLayer* layer, bool writeAttributes) {
return TopoFeature::get_multipolygon_features(layer, "Forest", writeAttributes);
}
2 changes: 1 addition & 1 deletion Forest.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Forest: public TIN {
void get_citygml(std::ofstream& of);
void get_citygml_imgeo(std::ofstream& of);
std::string get_mtl();
bool get_shape(OGRLayer * layer);
bool get_shape(OGRLayer* layer, bool writeAttributes);
TopoClass get_class();
bool is_hard();
private:
Expand Down
67 changes: 48 additions & 19 deletions Map3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,16 +326,23 @@ void Map3d::get_obj_per_class(std::ofstream& of, int z_exaggeration) {

bool Map3d::get_gdal_output(std::string filename, std::string drivername, bool multi) {
#if GDAL_VERSION_MAJOR < 2
std::cerr << "ERROR: cannot write MultiPolygonZ files with GDAL < 2.0.\n";
return false;
#else
if (GDALGetDriverCount() == 0)
GDALAllRegister();
GDALDriver *driver = GetGDALDriverManager()->GetDriverByName(drivername.c_str());

if (!multi) {
OGRLayer *layer = create_gdal_layer(driver, filename, "my3dmap", true);
OGRLayer *layer = create_gdal_layer(driver, filename, "my3dmap", AttributeMap(), true);
if (layer == NULL) {
std::cerr << "ERROR: Cannot open file '" + filename + "' for writing" << std::endl;
GDALClose(layer);
GDALClose(driver);
return false;
}
for (auto& f : _lsFeatures) {
f->get_shape(layer);
f->get_shape(layer, false);
}
GDALClose(layer);
GDALClose(driver);
Expand All @@ -350,9 +357,18 @@ bool Map3d::get_gdal_output(std::string filename, std::string drivername, bool m
if (drivername == "ESRI Shapefile") {
tmpFilename = filename + layername;
}
layers.emplace(layername, create_gdal_layer(driver, tmpFilename, layername, false));
OGRLayer *layer = create_gdal_layer(driver, tmpFilename, layername, f->get_attributes(), f->get_class() == BUILDING);
if (layer == NULL) {
std::cerr << "ERROR: Cannot open file '" + filename + "' for writing" << std::endl;
for (auto& layer : layers) {
GDALClose(layer.second);
}
GDALClose(driver);
return false;
}
layers.emplace(layername, layer);
}
f->get_shape(layers[layername]);
f->get_shape(layers[layername], true);
}
for (auto& layer : layers) {
GDALClose(layer.second);
Expand All @@ -363,8 +379,8 @@ bool Map3d::get_gdal_output(std::string filename, std::string drivername, bool m
#endif
}

#if GDAL_VERSION_MAJOR > 2
OGRLayer* Map3d::create_gdal_layer(GDALDriver *driver, std::string filename, std::string layername, bool forceHeightAttributes) {
#if GDAL_VERSION_MAJOR >= 2
OGRLayer* Map3d::create_gdal_layer(GDALDriver *driver, std::string filename, std::string layername, AttributeMap attributes, bool addHeightAttributes) {
GDALDataset *dataSource = driver->Create(filename.c_str(), 0, 0, 0, GDT_Unknown, NULL);

if (dataSource == NULL) {
Expand All @@ -377,17 +393,17 @@ OGRLayer* Map3d::create_gdal_layer(GDALDriver *driver, std::string filename, std
sr->importFromEPSG(7415);
layer = dataSource->CreateLayer(layername.c_str(), sr, OGR_GT_SetZ(wkbMultiPolygon), NULL);

OGRFieldDefn oField("Id", OFTString);
OGRFieldDefn oField("3dfier_Id", OFTString);
if (layer->CreateField(&oField) != OGRERR_NONE) {
std::cerr << "Creating Id field failed.\n";
std::cerr << "Creating 3dfier_Id field failed.\n";
return NULL;
}
OGRFieldDefn oField2("Class", OFTString);
OGRFieldDefn oField2("3dfier_Class", OFTString);
if (layer->CreateField(&oField2) != OGRERR_NONE) {
std::cerr << "Creating Class field failed.\n";
std::cerr << "Creating 3dfier_Class field failed.\n";
return NULL;
}
if (forceHeightAttributes || layername == "buildingpart") {
if (addHeightAttributes) {
OGRFieldDefn oField3("BaseHeight", OFTReal);
if (layer->CreateField(&oField3) != OGRERR_NONE) {
std::cerr << "Creating BaseHeight field failed.\n";
Expand All @@ -399,35 +415,45 @@ OGRLayer* Map3d::create_gdal_layer(GDALDriver *driver, std::string filename, std
return NULL;
}
}
for (auto attr : attributes) {
OGRFieldDefn oField(attr.first.c_str(), attr.second.first);
if (layer->CreateField(&oField) != OGRERR_NONE) {
std::cerr << "Creating " + attr.first + " field failed.\n";
return NULL;
}
}
}
return layer;
}
#endif

bool Map3d::get_shapefile2d(std::string filename) {
#if GDAL_VERSION_MAJOR < 2
return false;
if (OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount() == 0)
OGRRegisterAll();
OGRSFDriver *driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("ESRI Shapefile");
OGRDataSource *dataSource = driver->CreateDataSource(filename.c_str(), NULL);
#else

if (GDALGetDriverCount() == 0)
GDALAllRegister();
GDALDriver *driver = GetGDALDriverManager()->GetDriverByName("ESRI Shapefile");
GDALDataset *dataSource = driver->Create(filename.c_str(), 0, 0, 0, GDT_Unknown, NULL);
#endif

if (dataSource == NULL) {
std::cerr << "\tERROR: could not open file, skipping it.\n";
return false;
}
OGRLayer *layer = dataSource->CreateLayer("my3dmap", NULL, wkbMultiPolygon, NULL);

OGRFieldDefn oField("Id", OFTString);
OGRFieldDefn oField("3dfier_Id", OFTString);
if (layer->CreateField(&oField) != OGRERR_NONE) {
std::cerr << "Creating Id field failed.\n";
std::cerr << "Creating 3dfier_Id field failed.\n";
return false;
}
OGRFieldDefn oField2("Class", OFTString);
OGRFieldDefn oField2("3dfier_Class", OFTString);
if (layer->CreateField(&oField2) != OGRERR_NONE) {
std::cerr << "Creating Class field failed.\n";
std::cerr << "Creating 3dfier_Class field failed.\n";
return false;
}
OGRFieldDefn oField3("BaseHeight", OFTReal);
Expand All @@ -441,11 +467,14 @@ bool Map3d::get_shapefile2d(std::string filename) {
return false;
}
for (auto& f : _lsFeatures) {
f->get_shape(layer);
f->get_shape(layer, false);
}
#if GDAL_VERSION_MAJOR < 2
OGRDataSource::DestroyDataSource(dataSource);
#else
GDALClose(dataSource);
return true;
#endif
return true;
}

unsigned long Map3d::get_num_polygons() {
Expand Down
2 changes: 1 addition & 1 deletion Map3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ class Map3d {
#if GDAL_VERSION_MAJOR < 2
bool extract_and_add_polygon(OGRDataSource* dataSource, PolygonFile* file);
#else
OGRLayer* create_gdal_layer(GDALDriver *driver, std::string filename, std::string layername, bool forceHeightAttributes);
bool extract_and_add_polygon(GDALDataset* dataSource, PolygonFile* file);
OGRLayer* create_gdal_layer(GDALDriver *driver, std::string filename, std::string layername, AttributeMap attributes, bool addHeightAttributes);
#endif
void extract_feature(OGRFeature * f, std::string layerName, const char * idfield, const char * heightfield, std::string layertype, bool multiple_heights);
void stitch_one_vertex(TopoFeature* f, int ringi, int pi, std::vector< std::tuple<TopoFeature*, int, int> >& star);
Expand Down
4 changes: 2 additions & 2 deletions Road.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,6 @@ void Road::get_citygml_imgeo(std::ofstream& of) {
of << "</cityObjectMember>\n";
}

bool Road::get_shape(OGRLayer* layer) {
return TopoFeature::get_multipolygon_features(layer, "Road");
bool Road::get_shape(OGRLayer* layer, bool writeAttributes) {
return TopoFeature::get_multipolygon_features(layer, "Road", writeAttributes);
}
2 changes: 1 addition & 1 deletion Road.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Road: public Boundary3D {
void get_citygml(std::ofstream& of);
void get_citygml_imgeo(std::ofstream& of);
std::string get_mtl();
bool get_shape(OGRLayer * layer);
bool get_shape(OGRLayer* layer, bool writeAttributes);
static float _heightref;
TopoClass get_class();
bool is_hard();
Expand Down
4 changes: 2 additions & 2 deletions Separation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,6 @@ void Separation::get_citygml_imgeo(std::ofstream& of) {
of << "</cityObjectMember>\n";
}

bool Separation::get_shape(OGRLayer* layer) {
return TopoFeature::get_multipolygon_features(layer, "Separation");
bool Separation::get_shape(OGRLayer* layer, bool writeAttributes) {
return TopoFeature::get_multipolygon_features(layer, "Separation", writeAttributes);
}
2 changes: 1 addition & 1 deletion Separation.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Separation: public Boundary3D {
void get_citygml(std::ofstream& of);
void get_citygml_imgeo(std::ofstream& of);
std::string get_mtl();
bool get_shape(OGRLayer * layer);
bool get_shape(OGRLayer* layer, bool writeAttributes);
TopoClass get_class();
bool is_hard();
protected:
Expand Down
4 changes: 2 additions & 2 deletions Terrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ void Terrain::get_citygml_imgeo(std::ofstream& of) {
of << "</cityObjectMember>\n";
}

bool Terrain::get_shape(OGRLayer* layer) {
return TopoFeature::get_multipolygon_features(layer, "Terrain");
bool Terrain::get_shape(OGRLayer* layer, bool writeAttributes) {
return TopoFeature::get_multipolygon_features(layer, "Terrain", writeAttributes);
}
2 changes: 1 addition & 1 deletion Terrain.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Terrain: public TIN {
void get_citygml(std::ofstream& of);
void get_citygml_imgeo(std::ofstream& of);
std::string get_mtl();
bool get_shape(OGRLayer * layer);
bool get_shape(OGRLayer* layer, bool writeAttributes);
TopoClass get_class();
bool is_hard();
};
Expand Down
114 changes: 62 additions & 52 deletions TopoFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ void TopoFeature::get_obj(std::unordered_map< std::string, unsigned long > &dPts
}
}

AttributeMap TopoFeature::get_attributes() {
return _attributes;
}

void TopoFeature::get_imgeo_object_info(std::ofstream& of, std::string id) {
std::string attribute;
if (get_attribute("creationDate", attribute)) {
Expand Down Expand Up @@ -229,59 +233,65 @@ void TopoFeature::get_citygml_attributes(std::ofstream& of, AttributeMap attribu
}
}

bool TopoFeature::get_multipolygon_features(OGRLayer* layer, std::string className, bool writeHeights, int height_base, int height) {
OGRFeatureDefn *featureDefn = layer->GetLayerDefn();
OGRFeature *feature = OGRFeature::CreateFeature(featureDefn);
OGRMultiPolygon multipolygon = OGRMultiPolygon();
Point3 p;

//-- add all triangles to the layer
for (auto& t: _triangles) {
OGRPolygon polygon = OGRPolygon();
OGRLinearRing ring = OGRLinearRing();

p = _vertices[t.v0].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices[t.v1].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices[t.v2].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());

ring.closeRings();
polygon.addRing(&ring);
multipolygon.addGeometry(&polygon);
}

//-- add all vertical wall triangles to the layer
for (auto& t: _triangles_vw) {
OGRPolygon polygon = OGRPolygon();
OGRLinearRing ring = OGRLinearRing();

p = _vertices_vw[t.v0].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices_vw[t.v1].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices_vw[t.v2].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());

ring.closeRings();
polygon.addRing(&ring);
multipolygon.addGeometry(&polygon);
}

feature->SetGeometry(&multipolygon);
feature->SetField("Id", this->get_id().c_str());
feature->SetField("Class", className.c_str());
if (writeHeights) {
feature->SetField("BaseHeight", z_to_float(height_base));
feature->SetField("RoofHeight", z_to_float(height));
}
if (layer->CreateFeature(feature) != OGRERR_NONE)
{
std::cerr << "Failed to create feature " << this->get_id() << " in shapefile.\n";
return false;
bool TopoFeature::get_multipolygon_features(OGRLayer* layer, std::string className, bool writeAttributes, bool writeHeights, int height_base, int height) {
OGRFeatureDefn *featureDefn = layer->GetLayerDefn();
OGRFeature *feature = OGRFeature::CreateFeature(featureDefn);
OGRMultiPolygon multipolygon = OGRMultiPolygon();
Point3 p;

//-- add all triangles to the layer
for (auto& t : _triangles) {
OGRPolygon polygon = OGRPolygon();
OGRLinearRing ring = OGRLinearRing();

p = _vertices[t.v0].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices[t.v1].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices[t.v2].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());

ring.closeRings();
polygon.addRing(&ring);
multipolygon.addGeometry(&polygon);
}

//-- add all vertical wall triangles to the layer
for (auto& t : _triangles_vw) {
OGRPolygon polygon = OGRPolygon();
OGRLinearRing ring = OGRLinearRing();

p = _vertices_vw[t.v0].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices_vw[t.v1].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());
p = _vertices_vw[t.v2].first;
ring.addPoint(p.get<0>(), p.get<1>(), p.get<2>());

ring.closeRings();
polygon.addRing(&ring);
multipolygon.addGeometry(&polygon);
}

feature->SetGeometry(&multipolygon);
feature->SetField("3dfier_Id", this->get_id().c_str());
feature->SetField("3dfier_Class", className.c_str());
if (writeHeights) {
feature->SetField("BaseHeight", z_to_float(height_base));
feature->SetField("RoofHeight", z_to_float(height));
}
if (writeAttributes) {
for (auto attr : _attributes) {
if (!(attr.second.first == OFTDateTime && attr.second.second == "0000/00/00 00:00:00")) {
feature->SetField(attr.first.c_str(), attr.second.second.c_str());
}
}
OGRFeature::DestroyFeature(feature);
}
if (layer->CreateFeature(feature) != OGRERR_NONE) {
std::cerr << "Failed to create feature " << this->get_id() << " in shapefile.\n";
return false;
}
OGRFeature::DestroyFeature(feature);
return true;
}

Expand Down
Loading

0 comments on commit 47af189

Please sign in to comment.