diff --git a/include/inset_state.hpp b/include/inset_state.hpp index b7519b61..c1b7cfeb 100644 --- a/include/inset_state.hpp +++ b/include/inset_state.hpp @@ -194,7 +194,7 @@ class InsetState nlohmann::json inset_to_geojson(bool, bool = false) const; // Function to go from equal area to cartogram - void integrate(ProgressTracker &); + void integrate(ProgressTracker &, size_t n_insets); std::vector intersecting_segments(unsigned int) const; std::vector> intersec_with_parallel_to( diff --git a/sample_data/belgium_by_region_since_1995/belgium_population_by_region_2022.csv b/sample_data/belgium_by_region_since_1995/belgium_population_by_region_2022.csv index bb275034..5b876339 100644 --- a/sample_data/belgium_by_region_since_1995/belgium_population_by_region_2022.csv +++ b/sample_data/belgium_by_region_since_1995/belgium_population_by_region_2022.csv @@ -1,4 +1,4 @@ shapeName,Population (people),Color,Inset,Label -Brussels-Capital,1222637,#fbb4ae,, -Flanders,6698876,#b3cde3,, +Brussels-Capital,1222637,,, +Flanders,6698876,,, Wallonia,3662495,#ccebc5,, diff --git a/src/cartogram_info/cartogram_info.cpp b/src/cartogram_info/cartogram_info.cpp index 08762d12..d36acef2 100644 --- a/src/cartogram_info/cartogram_info.cpp +++ b/src/cartogram_info/cartogram_info.cpp @@ -120,8 +120,10 @@ void CartogramInfo::preprocess() } if (args_.export_preprocessed) { + // Output rescaled GeoJSON write_geojson("input_processed"); + // processed = simplified + rescaled // and potentially projected + small polygons removed @@ -196,7 +198,7 @@ void CartogramInfo::replace_missing_and_zero_target_areas() double total_start_area_with_data = 0.0; double total_target_area_with_data = 0.0; for (const InsetState &inset_state : inset_states_) { - for (const auto &gd : inset_state.geo_divs()) { + for (const GeoDiv &gd : inset_state.geo_divs()) { if (!inset_state.target_area_is_missing(gd.id())) { total_start_area_with_data += gd.area(); total_target_area_with_data += inset_state.target_area_at(gd.id()); @@ -221,7 +223,7 @@ void CartogramInfo::replace_missing_and_zero_target_areas() bool small_target_area_exists = false; bool missing_target_area_exists = false; for (InsetState &inset_state : inset_states_) { - for (const auto &gd : inset_state.geo_divs()) { + for (const GeoDiv &gd : inset_state.geo_divs()) { const double target_area = inset_state.target_area_at(gd.id()); inset_state.insert_whether_input_target_area_is_missing( gd.id(), @@ -253,7 +255,7 @@ void CartogramInfo::replace_missing_and_zero_target_areas() << std::endl; double min_positive_area = dbl_inf; for (const InsetState &inset_state : inset_states_) { - for (const auto &gd : inset_state.geo_divs()) { + for (const GeoDiv &gd : inset_state.geo_divs()) { min_positive_area = std::min(min_positive_area, gd.area()); } } @@ -262,7 +264,7 @@ void CartogramInfo::replace_missing_and_zero_target_areas() // Replace the small target areas for (InsetState &inset_state : inset_states_) { - for (const auto &gd : inset_state.geo_divs()) { + for (const GeoDiv &gd : inset_state.geo_divs()) { // Current target area const double target_area = inset_state.target_area_at(gd.id()); @@ -295,7 +297,7 @@ void CartogramInfo::replace_missing_and_zero_target_areas() // Assign new target areas to GeoDivs for (InsetState &inset_state : inset_states_) { - for (const auto &gd : inset_state.geo_divs()) { + for (const GeoDiv &gd : inset_state.geo_divs()) { if (inset_state.target_area_is_missing(gd.id())) { double new_target_area; @@ -403,7 +405,7 @@ InsetState CartogramInfo::convert_to_inset_state() InsetState new_inset_state("", args_); for (const InsetState &inset_state : inset_states_) { - for (const auto &geo_div : inset_state.geo_divs()) { + for (const GeoDiv &geo_div : inset_state.geo_divs()) { new_inset_state.push_back(geo_div); new_inset_state.insert_color( geo_div.id(), @@ -448,7 +450,10 @@ void CartogramInfo::write_svg(const std::string &suffix) for (const InsetState &inset_state : inset_states_) { inset_names += inset_state.pos(); } - insets_combined.write_map( - map_name_ + "_" + inset_names + "_" + suffix, - false); -} \ No newline at end of file + // Only generate inset-named map if there's more than one inset + if (n_insets() > 1) { + insets_combined.write_map( + map_name_ + "_" + inset_names + "_" + suffix, + false); + } +} diff --git a/src/inset_state/auto_color.cpp b/src/inset_state/auto_color.cpp index 6a9558d5..1248a956 100644 --- a/src/inset_state/auto_color.cpp +++ b/src/inset_state/auto_color.cpp @@ -11,18 +11,17 @@ void InsetState::auto_color() std::vector palette; if (colors_.size() > 0) { - // If some colors are already provided, use a different palette - // From https://colorbrewer2.org/#type=qualitative&scheme=Dark2&n=8 - std::cerr << "Some but not all colors provided, using Dark color palette." + // If some but not all of the GeoDivs are colored, use only #f2f2f2 (light + // gray) to color the rest + std::cerr << "Some but not all colors provided, assigning #f2f2f2 (light " + "gray) to uncolored GeoDivs." << std::endl; - palette.emplace_back("#1b9e77"); // aqua green - palette.emplace_back("#d95f02"); // dark orange - palette.emplace_back("#7570b3"); // purple - palette.emplace_back("#e7298a"); // dark pink - palette.emplace_back("#66a61e"); // olive green - palette.emplace_back("#e6ab02"); // dark yellow - palette.emplace_back("#a6761d"); // brown - palette.emplace_back("#666666"); // dark grey + for (GeoDiv &gd : geo_divs_) { + if (!color_found(gd.id())) { + insert_color(gd.id(), Color("#f2f2f2")); + } + } + return; } else { // Using default palette for now // TODO: Accept palette from user @@ -43,7 +42,7 @@ void InsetState::auto_color() create_contiguity_graph(); // Iterate until we are able to color the entire map - for (const auto &gd : geo_divs_) { + for (const GeoDiv &gd : geo_divs_) { // If div already has a provided color, move to the next div if (color_found(gd.id())) continue; @@ -53,7 +52,7 @@ void InsetState::auto_color() bool shared_color = false; // Check whether adjacent GeoDivs have the same color - for (const auto &gd_id : gd.adjacent_geodivs()) { + for (const std::string &gd_id : gd.adjacent_geodivs()) { if (color_found(gd_id)) { if (color_at(gd_id) == c) { shared_color = true; diff --git a/src/inset_state/integrate.cpp b/src/inset_state/integrate.cpp index 2438d32b..76aaec4e 100644 --- a/src/inset_state/integrate.cpp +++ b/src/inset_state/integrate.cpp @@ -76,7 +76,7 @@ void InsetState::cleanup_after_integration() ref_to_fluxy_init().free(); } -void InsetState::integrate(ProgressTracker &progress_tracker) +void InsetState::integrate(ProgressTracker &progress_tracker, size_t n_insets) { timer.start(inset_name_); @@ -135,7 +135,11 @@ void InsetState::integrate(ProgressTracker &progress_tracker) // Write SVG for this inset, if requested if (args_.plot_polygons) { - write_map(inset_name() + "_output", args_.plot_grid, false); + if (n_insets > 1) { + write_map(inset_name() + "_output", args_.plot_grid, false); + } else { + write_map(inset_name() + "_cartogram", args_.plot_grid, false); + } } // Project original map with cumulative projection diff --git a/src/main.cpp b/src/main.cpp index cf62e2d7..f505879e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,7 +52,7 @@ int main(const int argc, const char *argv[]) // Iterate over insets and integrate each one for (InsetState &inset_state : cart_info.ref_to_inset_states()) { - inset_state.integrate(progress_tracker); + inset_state.integrate(progress_tracker, cart_info.n_insets()); } // Rescale insets in correct proportion to each other