diff --git a/src/Building.cpp b/src/Building.cpp index 1b95a477..f1e0d9b1 100644 --- a/src/Building.cpp +++ b/src/Building.cpp @@ -387,6 +387,42 @@ void Building::get_cityjson(nlohmann::json& j, std::unordered_mapget_cityjson_geom(g, dPts, "Solid"); + + if (_building_include_floor) { + for (auto& t : _triangles) { + unsigned long a, b, c; + float z = z_to_float(this->get_height_base()); + auto it = dPts.find(gen_key_bucket(&_vertices[t.v0].first, z)); + if (it == dPts.end()) { + a = dPts.size(); + dPts[gen_key_bucket(&_vertices[t.v0].first, z)] = a; + } + else { + a = it->second; + } + it = dPts.find(gen_key_bucket(&_vertices[t.v1].first, z)); + if (it == dPts.end()) { + b = dPts.size(); + dPts[gen_key_bucket(&_vertices[t.v1].first, z)] = b; + } + else { + b = it->second; + } + it = dPts.find(gen_key_bucket(&_vertices[t.v2].first, z)); + if (it == dPts.end()) { + c = dPts.size(); + dPts[gen_key_bucket(&_vertices[t.v2].first, z)] = c; + } + else { + c = it->second; + } + //reverse orientation for floor polygon, a-c-b instead of a-b-c. + if ((a != b) && (a != c) && (b != c)) { + g["boundaries"].at(0).push_back({{ a, c, b }}); + } + } + } + b["geometry"].push_back(g); j["CityObjects"][this->get_id()] = b; } diff --git a/src/TopoFeature.cpp b/src/TopoFeature.cpp index 0b6a1392..2ca10682 100644 --- a/src/TopoFeature.cpp +++ b/src/TopoFeature.cpp @@ -86,7 +86,7 @@ void TopoFeature::get_cityjson_geom(nlohmann::json& g, std::unordered_map>> shelli; + std::vector>> shelli; for (auto& t : _triangles) { unsigned long a, b, c; auto it = dPts.find(_vertices[t.v0].second); @@ -266,7 +266,7 @@ void TopoFeature::get_imgeo_object_info(std::wostream& of, std::string id) { } } -void TopoFeature::get_cityjson_attributes(nlohmann::json& f, AttributeMap attributes) { +void TopoFeature::get_cityjson_attributes(nlohmann::json& f, const AttributeMap& attributes) { for (auto& attribute : attributes) { // add attributes except gml_id if (attribute.first.compare("gml_id") != 0) @@ -274,7 +274,7 @@ void TopoFeature::get_cityjson_attributes(nlohmann::json& f, AttributeMap attrib } } -void TopoFeature::get_citygml_attributes(std::wostream& of, AttributeMap attributes) { +void TopoFeature::get_citygml_attributes(std::wostream& of, const AttributeMap& attributes) { for (auto& attribute : attributes) { // add attributes except gml_id if (attribute.first.compare("gml_id") != 0) { @@ -296,7 +296,7 @@ void TopoFeature::get_citygml_attributes(std::wostream& of, AttributeMap attribu } } -bool TopoFeature::get_multipolygon_features(OGRLayer* layer, std::string className, bool writeAttributes, AttributeMap extraAttributes) { +bool TopoFeature::get_multipolygon_features(OGRLayer* layer, std::string className, bool writeAttributes, const AttributeMap& extraAttributes) { OGRFeatureDefn *featureDefn = layer->GetLayerDefn(); OGRFeature *feature = OGRFeature::CreateFeature(featureDefn); OGRMultiPolygon multipolygon = OGRMultiPolygon(); @@ -657,7 +657,7 @@ void TopoFeature::construct_vertical_walls(const NodeColumn& nc) { } } -bool TopoFeature::has_segment(Point2& a, Point2& b, int& aringi, int& api, int& bringi, int& bpi) { +bool TopoFeature::has_segment(const Point2& a, const Point2& b, int& aringi, int& api, int& bringi, int& bpi) { double threshold = 0.001; double sqr_threshold = threshold * threshold; std::vector ringis, pis; @@ -678,7 +678,7 @@ bool TopoFeature::has_segment(Point2& a, Point2& b, int& aringi, int& api, int& return false; } -float TopoFeature::get_distance_to_boundaries(Point2& p) { +float TopoFeature::get_distance_to_boundaries(const Point2& p) { //-- collect the rings of the polygon std::vector therings; therings.push_back(_p2->outer()); @@ -801,7 +801,7 @@ int TopoFeature::get_vertex_elevation(int ringi, int pi) { return _p2z[ringi][pi]; } -int TopoFeature::get_vertex_elevation(Point2& p) { +int TopoFeature::get_vertex_elevation(const Point2& p) { std::vector ringis, pis; has_point2(p, ringis, pis); return _p2z[ringis[0]][pis[0]]; @@ -813,7 +813,7 @@ void TopoFeature::set_vertex_elevation(int ringi, int pi, int z) { //-- used to collect all points linked to the polygon //-- later all these values are used to lift the polygon (and put values in _p2z) -bool TopoFeature::assign_elevation_to_vertex(Point2 &p, double z, float radius) { +bool TopoFeature::assign_elevation_to_vertex(const Point2 &p, double z, float radius) { float sqr_radius = radius * radius; int zcm = int(z * 100); int ringi = 0; @@ -835,9 +835,9 @@ bool TopoFeature::assign_elevation_to_vertex(Point2 &p, double z, float radius) return true; } -bool TopoFeature::within_range(Point2 &p, Polygon2 &poly, double radius) { +bool TopoFeature::within_range(const Point2 &p, const Polygon2 &poly, double radius) { double sqr_radius = radius * radius; - Ring2 oring = poly.outer(); + const Ring2& oring = poly.outer(); //-- point is within range of the polygon rings for (int i = 0; i < oring.size(); i++) { if (sqr_distance(p, oring[i]) <= sqr_radius) { @@ -862,7 +862,7 @@ bool TopoFeature::within_range(Point2 &p, Polygon2 &poly, double radius) { // based on http://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon/2922778#2922778 bool TopoFeature::point_in_polygon(const Point2 &p, const Polygon2 &poly) { //test outer ring - Ring2 oring = poly.outer(); + const Ring2& oring = poly.outer(); int nvert = oring.size(); int i, j = 0; bool insideOuter = false; diff --git a/src/TopoFeature.h b/src/TopoFeature.h index c75c005c..c33a5fd6 100644 --- a/src/TopoFeature.h +++ b/src/TopoFeature.h @@ -62,22 +62,22 @@ class TopoFeature { std::string get_layername(); Point2 get_point2(int ringi, int pi); bool has_point2(const Point2& p, std::vector& ringis, std::vector& pis); - bool has_segment(Point2& a, Point2& b, int& aringi, int& api, int& bringi, int& bpi); + bool has_segment(const Point2& a, const Point2& b, int& aringi, int& api, int& bringi, int& bpi); bool adjacent(const Polygon2& poly); - float get_distance_to_boundaries(Point2& p); + float get_distance_to_boundaries(const Point2& p); int get_vertex_elevation(int ringi, int pi); - int get_vertex_elevation(Point2& p); + int get_vertex_elevation(const Point2& p); void set_vertex_elevation(int ringi, int pi, int z); void set_top_level(bool toplevel); bool has_vertical_walls(); void add_vertical_wall(); bool get_top_level(); - bool get_multipolygon_features(OGRLayer* layer, std::string className, bool writeAttributes, AttributeMap extraAttributes = AttributeMap()); + bool get_multipolygon_features(OGRLayer* layer, std::string className, bool writeAttributes, const AttributeMap& extraAttributes = AttributeMap()); void get_obj(std::unordered_map< std::string, unsigned long > &dPts, std::string mtl, std::string &fs); AttributeMap get_attributes(); void get_imgeo_object_info(std::wostream& of, std::string id); - void get_citygml_attributes(std::wostream& of, AttributeMap attributes); - void get_cityjson_attributes(nlohmann::json& f, AttributeMap attributes); + void get_citygml_attributes(std::wostream& of, const AttributeMap& attributes); + void get_cityjson_attributes(nlohmann::json& f, const AttributeMap& attributes); protected: Polygon2* _p2; std::vector< std::vector > _p2z; @@ -95,8 +95,8 @@ class TopoFeature { std::vector _triangles_vw; Point2 get_next_point2_in_ring(int ringi, int i, int& pi); - bool assign_elevation_to_vertex(Point2 &p, double z, float radius); - bool within_range(Point2 &p, Polygon2 &oly, double radius); + bool assign_elevation_to_vertex(const Point2 &p, double z, float radius); + bool within_range(const Point2 &p, const Polygon2 &oly, double radius); bool point_in_polygon(const Point2 &p, const Polygon2 &poly); void lift_each_boundary_vertices(float percentile); void lift_all_boundary_vertices_same_height(int height); diff --git a/src/main.cpp b/src/main.cpp index a5df5fd3..5329c453 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,7 +36,7 @@ #include #include -std::string VERSION = "1.0.2"; +std::string VERSION = "1.0.3"; bool validate_yaml(const char* arg, std::set& allowedFeatures); int main(int argc, const char * argv[]);