Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/plugins/export-world-map.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ commands:

::

ogr2ogr -a_srs "EPSG:3857" -of Parquet map.parquet -oo 'GEOM_POSSIBLE_NAMES=*wkt' -oo 'KEEP_GEOM_COLUMNS=NO' -oo 'AUTODETECT_TYPE=YES' map.csv
ogr2ogr -a_srs "EPSG:3857" -of Parquet regions.parquet -oo 'GEOM_POSSIBLE_NAMES=*wkt' -oo 'KEEP_GEOM_COLUMNS=NO' -oo 'AUTODETECT_TYPE=YES' regions.csv
ogr2ogr -a_srs "EPSG:3857" -of Parquet rivers.parquet -oo 'GEOM_POSSIBLE_NAMES=*wkt' -oo 'KEEP_GEOM_COLUMNS=NO' -oo 'AUTODETECT_TYPE=YES' rivers.csv
gdal raster convert elevation.vrt elevation.tif
29 changes: 29 additions & 0 deletions library/include/CoordTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ namespace DFHack
Coord2d() : x(initializer), y(initializer) {}
Coord2d(T x, T y) : x(x), y(y) {}

template<typename U>
explicit Coord2d(const Coord2d<U> &other) : x(static_cast<T>(other.x)), y(static_cast<T>(other.y)) {};

bool isValid() const { return x >= 0; }

void clear()
Expand Down Expand Up @@ -77,6 +80,32 @@ namespace DFHack
r = m * (r + y);
return r;
}

// dot product
T dotp(const Coord2d& other) const
{
return x * other.x + y * other.y;
}

// linear interpolation between two points
Coord2d lerp(const Coord2d& other, T t) const requires std::floating_point<T>
{
return *this + (other - *this) * t;
}

// orthogonal projection of the point onto the line (segment) AB
Coord2d project_onto_line(
const Coord2d& A,
const Coord2d& B,
bool clamp = false
) const requires std::floating_point<T>
{
auto P = *this;
auto AB = B - A;
auto AP = P - A;
auto t = AP.dotp(AB) / AB.dotp(AB);
return A + AB * (clamp ? std::clamp(t, 0.0, 1.0) : t);
}
};

template <typename T, T initializer = DFHack::coord_default_initializer<T>, typename U = DFHack::Coord2d<T, initializer>>
Expand Down
90 changes: 21 additions & 69 deletions plugins/export-world-map.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "CoordTemplate.h"
#include "Debug.h"
#include "Error.h"
#include "MiscUtils.h"
Expand All @@ -7,6 +8,7 @@
#include "modules/Maps.h"
#include "modules/Translation.h"

#include "df/coord2d.h"
#include "df/creature_raw.h"
#include "df/entity_raw.h"
#include "df/historical_entity.h"
Expand Down Expand Up @@ -198,11 +200,11 @@ static command_result export_sites(color_ostream &out)

// If you change anything in this vector, don't forget to change the
// corresponding comments and arguments in the call to print_csv_line below
constexpr std::array<std::string_view, 12> headings = {
constexpr auto headings = std::to_array<std::string_view>({
"site_id", "civ_id", "created_year", "cur_owner_id", "type",
"site_name_df", "site_name_en", "civ_name_df", "civ_name_en", "site_government_df", "site_government_en", "owner_race"
};
print_range(out_file, headings,"",";",";boundary_wkt\n" );
});
print_range(out_file, headings,"",";",";boundary_wkt\n");

#define TRANSLATE_DF_EN(guard, name_object)\
guard ? DF2UTF(Translation::translateName(&name_object, false)) : "NONE",\
Expand Down Expand Up @@ -441,12 +443,12 @@ static command_result export_regions(color_ostream &out)

// If you change anything in this vector, don't forget to change the
// corresponding comments and arguments in the call to print_csv_line below
constexpr std::array<std::string_view, 23> headings = {
constexpr auto headings = std::to_array<std::string_view>({
"world_x", "world_y", "num_tiles", "num_components", "biome_type",
"region_id", "region_name_en", "region_name_df", "landmass_id", "landmass_name_en", "landmass_name_df",
"region_id", "geo_index", "region_name_en", "region_name_df", "landmass_id", "landmass_name_en", "landmass_name_df",
"evilness", "savagery", "volcanism", "drainage", "temperature", "vegetation", "rainfall", "salinity",
"surroundings", "elevation", "reanimating", "has_bogeymen"
};
});
print_range(out_file, headings,"",";",";boundary_wkt\n" );

/* Preprocessing: cluster region tiles by the world tile used for the biome information */
Expand Down Expand Up @@ -518,8 +520,9 @@ static command_result export_regions(color_ostream &out)
region.size(),
components.size(),
ENUM_KEY_STR(biome_type,Maps::getBiomeType(biome_tile.x, biome_tile.y)),
// "region_id", "region_name_en", "region_name_df", "landmass_id", "landmass_name_en", "landmass_name_df"
// "region_id", "geo_index", "region_name_en", "region_name_df", "landmass_id", "landmass_name_en", "landmass_name_df"
region_map_entry.region_id,
region_map_entry.geo_index,
world_region ? DF2UTF(Translation::translateName(&world_region->name, true)) : "NONE",
world_region ? DF2UTF(Translation::translateName(&world_region->name, false)) : "NONE",
region_map_entry.landmass_id,
Expand Down Expand Up @@ -566,62 +569,8 @@ static command_result export_regions(color_ostream &out)
/* River Export */
/********************************************************************** */

//
// used for global coordinates at local tile granularity (129*768 = 99072 doesn't fit into df::coord2d)
template<typename T>
struct gcoord {
T x, y;

gcoord() = default;
gcoord(T x, T y) : x(x), y(y) {}

template<typename U>
explicit gcoord(const gcoord<U> &other) : x(static_cast<T>(other.x)), y(static_cast<T>(other.y)) {};

gcoord operator+(const gcoord &other) const
{
return {x + other.x, y + other.y};
}

gcoord operator-(const gcoord &other) const
{
return {x - other.x, y - other.y};
}

gcoord operator*(T s) const
{
return {x * s, y * s};
}

gcoord operator/(T s) const
{
return {x / s, y / s};
}

static T dotp(const gcoord& a, const gcoord& b)
{
return a.x * b.x + a.y * b.y;
}
};

// linear interpolation between two points
static gcoord<double> lerp(gcoord<double> A, gcoord<double> B, double t)
{
return A + (B - A) * t;
}

// "orthogonal" projection of the point P onto the line segment AB
static gcoord<double> project_onto_line(gcoord<double> A, gcoord<double> B, gcoord<double> P)
{
auto AB = B - A;
auto AP = P - A;
auto t = gcoord<double>::dotp(AP, AB) / gcoord<double>::dotp(AB, AB);
return A + AB * std::clamp(t, 0.0, 1.0);
}


struct river_tile {
using polygon_t = std::vector<gcoord<int>>;
using polygon_t = std::vector<Coord2d<int>>;
polygon_t polygon;
};

Expand All @@ -634,8 +583,9 @@ static void fix_confluence_tiles(river_tile::polygon_t& polygon)
{
assert(polygon.size() > 4 && polygon.size() % 2 == 0);

auto centroid =
gcoord<double>(std::reduce(polygon.begin(), polygon.end())) / static_cast<double>(polygon.size());
auto centroid = Coord2d<double>(
std::reduce(polygon.begin(), polygon.end(), Coord2d<int>(0, 0), std::plus<Coord2d<int>>())
) / static_cast<double>(polygon.size());

river_tile::polygon_t inset_polygon;

Expand All @@ -647,9 +597,11 @@ static void fix_confluence_tiles(river_tile::polygon_t& polygon)
inset_polygon.emplace_back(pair_start);
inset_polygon.emplace_back(pair_end);

auto projection = project_onto_line(gcoord<double>(pair_end), gcoord<double>(next_pair_start), centroid);
auto inset_point = lerp(projection, centroid, 0.6);
inset_polygon.emplace_back(gcoord<int>(inset_point));
auto projection = centroid.project_onto_line(
Coord2d<double>(pair_end), Coord2d<double>(next_pair_start), true
);
auto inset_point = projection.lerp(centroid, 0.6);
inset_polygon.emplace_back(Coord2d<int>(inset_point));
}

polygon = std::move(inset_polygon);
Expand Down Expand Up @@ -757,7 +709,7 @@ static command_result export_rivers(color_ostream &out)
for (int region_x = 0; region_x < 16; ++region_x) {
for (int region_y = 0; region_y < 16; ++region_y)
{
gcoord<int> base = { world_x * wdim + region_x * rdim, world_y * wdim + region_y * rdim };
Coord2d<int> base = { world_x * wdim + region_x * rdim, world_y * wdim + region_y * rdim };

auto north = gate::get(region_details, region_x, region_y, direction::North);
auto west = gate::get(region_details, region_x, region_y, direction::West);
Expand Down Expand Up @@ -817,7 +769,7 @@ static command_result export_rivers(color_ostream &out)
for (auto &tile : river_tiles) {
// close the polygon
tile.polygon.emplace_back(*tile.polygon.begin());
auto print_position = [](std::ostream &out, gcoord<int> pos) {
auto print_position = [](std::ostream &out, Coord2d<int> pos) {
out << pos.x << " " << -pos.y;
};
if (first) {
Expand Down
Loading