From c2cbc87eb0e561bdf77f5702de18641352643869 Mon Sep 17 00:00:00 2001 From: Javier Jimenez Shaw Date: Sat, 24 Aug 2024 18:07:37 +0200 Subject: [PATCH] output with roman numerals in cs2cs --- src/apps/cs2cs.cpp | 74 +++++++++++++++++++++++++++++--- test/cli/test_cs2cs_various.yaml | 8 ++++ 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 88353bf8f0..be2ec51872 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -67,6 +67,8 @@ static bool destIsLongLat = false; static double destToRadians = 0.0; static bool destIsLatLong = false; +static bool romanNumerals = false; + static int reversein = 0, /* != 0 reverse input arguments */ reverseout = 0, /* != 0 reverse output arguments */ echoin = 0, /* echo input data to output line */ @@ -94,6 +96,54 @@ using namespace NS_PROJ::metadata; using namespace NS_PROJ::util; using namespace NS_PROJ::internal; +static std::string degToRoman(double angle, const std::string &pos, + const std::string &neg) { + const std::string sign = angle > 0.0 ? pos : neg; + angle = fabs(angle); + double r = angle; + r = floor(r * 3600 + .0005); + int sec = (int)fmod(r, 60.); + r = floor(r / 60.); + int min = (int)fmod(r, 60.); + r = floor(r / 60.); + int deg = (int)r; + + auto intToRoman = [](int i) { + int unit = i % 10; + int tenth = i / 10 % 10; + int houndr = i / 100 % 10; + auto oneDigit = [](int digit, const std::string &one, + const std::string &five, const std::string &ten) { + switch (digit) { + case (1): + return one; + case (2): + return one + one; + case (3): + return one + one + one; + case (4): + return one + five; + case (5): + return five; + case (6): + return five + one; + case (7): + return five + one + one; + case (8): + return five + one + one + one; + case (9): + return one + ten; + default: + return std::string{}; + } + }; + return oneDigit(houndr, "C", "D", "M") + + oneDigit(tenth, "X", "L", "C") + oneDigit(unit, "I", "V", "X"); + }; + return intToRoman(deg) + "d" + intToRoman(min) + "'" + intToRoman(sec) + + "\"" + sign; +} + /************************************************************************/ /* process() */ /* */ @@ -208,11 +258,21 @@ static void process(FILE *fid) fputs(rtodms(pline, sizeof(pline), data.u, 'N', 'S'), stdout); } else { - fputs(rtodms(pline, sizeof(pline), data.u, 'N', 'S'), - stdout); - putchar('\t'); - fputs(rtodms(pline, sizeof(pline), data.v, 'E', 'W'), - stdout); + if (romanNumerals) { + std::string ns = + (degToRoman(data.u * RAD_TO_DEG, "S", "M")); + std::string ew = + (degToRoman(data.v * RAD_TO_DEG, "OR", "OC")); + fputs(ns.c_str(), stdout); + putchar('\t'); + fputs(ew.c_str(), stdout); + } else { + fputs(rtodms(pline, sizeof(pline), data.u, 'N', 'S'), + stdout); + putchar('\t'); + fputs(rtodms(pline, sizeof(pline), data.v, 'E', 'W'), + stdout); + } } } else if (reverseout) { fputs(rtodms(pline, sizeof(pline), data.v, 'N', 'S'), stdout); @@ -506,6 +566,10 @@ int main(int argc, char **argv) { std::exit(1); } targetEpoch = *argv; + } else if (strcmp(*argv, "--roman") == 0) { + ++argv; + --argc; + romanNumerals = true; } else if (**argv == '-') { for (arg = *argv;;) { switch (*++arg) { diff --git a/test/cli/test_cs2cs_various.yaml b/test/cli/test_cs2cs_various.yaml index b6c621c853..0ac17b5936 100644 --- a/test/cli/test_cs2cs_various.yaml +++ b/test/cli/test_cs2cs_various.yaml @@ -1505,3 +1505,11 @@ tests: in: 16.248285304 -61.484212843 53.073 out: | 661991.318 1796999.201 93.846 +- comment: Test --roman + args: EPSG:4326 EPSG:10606 --roman + in: | + 45d8'47.014"N 1d53'20.681"E 0.000 + 49d28'26.014"S 4d6'18.281"W 0.000 + out: | + XLVdVIII'XLVII"S IdLIII'XX"OR 0.000 + XLIXdXXVIII'XXVI"M IVdVI'XVIII"OC 0.000