You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
403 lines
9.2 KiB
403 lines
9.2 KiB
#ifndef MODGMT_STRUCT_H |
|
#define MODGMT_STRUCT_H |
|
#include <cinttypes> |
|
#include <cmath> |
|
#include <map> |
|
#include "common.h" |
|
|
|
// Coordinate |
|
struct gmt_coord |
|
{ |
|
bool isdeg; |
|
union |
|
{ |
|
double r; |
|
struct |
|
{ |
|
bool sign; |
|
uint16_t d; |
|
uint8_t m; |
|
double s; |
|
}; |
|
}; |
|
|
|
std::string Value() const |
|
{ |
|
if(!isdeg) return std::to_string(r); |
|
else return (sign?"":"-")+std::to_string(d)+":"+std::to_string(m)+(s==0?"":":"+std::to_string(s)); |
|
} |
|
operator double() const |
|
{ |
|
if(isdeg) return (d+(m+s/60.0)/60.0)*(sign?1:-1); |
|
else return r; |
|
} |
|
bool Convert(const std::string& str) |
|
{ |
|
WordList wl; |
|
WordList::const_iterator cw; |
|
wl=Split(str,":",true); |
|
if(1==wl.size()) // No dd:mm |
|
{ |
|
isdeg=false; |
|
return str2double(str,&r); |
|
} |
|
if(0==wl.size() || wl.size()>3) return false; |
|
|
|
isdeg=true; |
|
int64_t res; |
|
|
|
// degrees |
|
cw=wl.begin(); |
|
if(!str2int(*cw,&res)) return false; |
|
if(res>360 || res<-360) res%=360; |
|
sign=(std::string::npos==cw->find('-')); |
|
d=static_cast<uint16_t>(sign?res:-res); |
|
// minutes |
|
cw++; |
|
if(!str2int(*cw,&res)) return false; |
|
if(res<0 || res>=60) return false; |
|
m=static_cast<uint8_t>(res); |
|
s=0; |
|
|
|
// seconds |
|
cw++; |
|
if(wl.end()==cw) return true; // No seconds |
|
if(!str2double(*cw,&s) ) return false; |
|
if(s<0.0 || s>=60.0) return false; |
|
return true; |
|
} |
|
bool Convert(double num) |
|
{ |
|
isdeg=false; |
|
r=num; |
|
return true; |
|
} |
|
}; |
|
|
|
|
|
// Region |
|
struct gmt_region |
|
{ |
|
enum Type {NORMAL,BBOX,GLOBAL360,GLOBAL180}; |
|
Type type; |
|
struct gmt_coord xb,xe,yb,ye; |
|
|
|
std::string Value() const |
|
{ |
|
switch(type) |
|
{ |
|
case(NORMAL): return std::string("-R")+xb.Value()+"/"+xe.Value()+"/"+yb.Value()+"/"+ye.Value(); |
|
case(BBOX): return std::string("-R")+xb.Value()+"/"+yb.Value()+"/"+xe.Value()+"/"+ye.Value()+"r"; |
|
case(GLOBAL360): return "-Rg"; |
|
case(GLOBAL180): return "-Rd"; |
|
} |
|
return ""; |
|
} |
|
|
|
// Only "global", "global180" and "global360" |
|
// TODO: add parsing of "-R" strings |
|
bool Convert(const std::string& istr) |
|
{ |
|
std::string str=istr; |
|
tolower(str); |
|
if("global180"==str) |
|
{ |
|
type=GLOBAL180; |
|
xb.Convert(-180.0); xe.Convert(180.0); |
|
yb.Convert(-90.0); ye.Convert(90.0); |
|
return true; |
|
} |
|
if("global360"==str || "global"==str) |
|
{ |
|
type=GLOBAL360; |
|
xb.Convert(0.0); xe.Convert(360.0); |
|
yb.Convert(-90.0); ye.Convert(90.0); |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
// Make by coordinates |
|
bool Convert(struct gmt_coord ixb, struct gmt_coord ixe, struct gmt_coord iyb, struct gmt_coord iye, bool isbbox=false) |
|
{ |
|
type=isbbox?BBOX:NORMAL; |
|
xb=ixb; yb=iyb; xe=ixe; ye=iye; |
|
return true; |
|
} |
|
}; |
|
|
|
|
|
// Projection |
|
struct gmt_projection |
|
{ |
|
// OBLIQMERCATOR types |
|
enum class OType {NOTDEF,A,B,C}; |
|
// No UTM (-Ju) |
|
enum projection {NOTDEF,XY,CYL_EQU,MERCATOR,TRANSMERCATOR,OBLIQMERCATOR,CASSINI,CYL_EQA,MILLER,CYL_STERE}; |
|
// Real size in cm of drawing area |
|
double rwidth,rheight; |
|
|
|
struct gmt_region region; |
|
projection proj; |
|
double width; // parameter of projection |
|
static const double default_width; |
|
|
|
union // other projection parameters |
|
{ |
|
// XY |
|
struct {double height;} x; |
|
// Cylindrical projections |
|
// CYL_EQU (Cylindrical Equidistant -Jq) |
|
struct {struct gmt_coord stpar,cmer;} q; |
|
// MERCATOR (-Jm) |
|
struct {struct gmt_coord stpar,cmer;} m; |
|
// TRANSMERCATOR (-Jt) |
|
struct {struct gmt_coord cmer,orlat; double scale;} t; |
|
// OBLIQMERCATOR (-Jo) |
|
struct |
|
{ |
|
OType type; |
|
struct gmt_coord clon,clat; |
|
union |
|
{ |
|
struct gmt_coord azimuth; // A |
|
struct {struct gmt_coord eqlon,eqlat;}; // B |
|
struct {struct gmt_coord polelon,polelat;}; // C |
|
}; |
|
} o; |
|
// CASSINI (-Jc) |
|
struct {struct gmt_coord clon,clat;} c; |
|
// CYL_EQA (Cylindrical equal-area -Jy) |
|
struct {struct gmt_coord stpar,cmer;} y; |
|
// MILLER (-Jj) |
|
struct {struct gmt_coord cmer;} j; |
|
// CYL_STERE (Cylindrical stereographic -Jcyl_stere) |
|
struct {struct gmt_coord stpar,cmer;} cyl_stere; |
|
}; |
|
std::string Value() const |
|
{ |
|
std::string ret; |
|
switch(proj) |
|
{ |
|
case(XY): {ret="-JX"+std::to_string(width)+"c/"+std::to_string(x.height)+"c"; break;} |
|
case(CYL_EQU): {ret="-JQ"+q.cmer.Value()+"/"+q.stpar.Value()+"/"+std::to_string(width)+"c"; break;} |
|
case(MERCATOR): {ret="-JM"+m.cmer.Value()+"/"+m.stpar.Value()+"/"+std::to_string(width)+"c"; break;} |
|
case(TRANSMERCATOR): {ret="-JT"+t.cmer.Value()+"/"+t.orlat.Value()+"/"+std::to_string(width)+"c --PROJ_SCALE_FACTOR="+std::to_string(t.scale); break;} |
|
case(OBLIQMERCATOR): |
|
{ |
|
switch(o.type) |
|
{ |
|
case(OType::A): {ret="-JOa"+o.clon.Value()+"/"+o.clat.Value()+"/"+o.azimuth.Value()+"/"+std::to_string(width)+"c"; break;} |
|
case(OType::B): {ret="-JOb"+o.clon.Value()+"/"+o.clat.Value()+"/"+o.eqlon.Value()+"/"+o.eqlat.Value()+"/"+std::to_string(width)+"c"; break;} |
|
case(OType::C): {ret="-JOb"+o.clon.Value()+"/"+o.clat.Value()+"/"+o.polelon.Value()+"/"+o.polelat.Value()+"/"+std::to_string(width)+"c"; break;} |
|
default: return ""; |
|
} |
|
} |
|
case(CASSINI): {ret="-JC"+c.clon.Value()+"/"+c.clat.Value()+"/"+std::to_string(width)+"c"; break;} |
|
case(CYL_EQA): {ret="-JY"+y.stpar.Value()+"/"+y.cmer.Value()+"/"+std::to_string(width)+"c"; break;} |
|
case(MILLER): {ret="-JJ"+j.cmer.Value()+"/"+std::to_string(width)+"c"; break;} |
|
case(CYL_STERE): {ret="-JCyl_stere"+cyl_stere.stpar.Value()+"/"+cyl_stere.cmer.Value()+"/"+std::to_string(width)+"c"; break;} |
|
default: return ""; |
|
} |
|
ret+=" "+region.Value(); |
|
return ret; |
|
} |
|
bool SetType(const std::string& s) |
|
{ |
|
proj=NOTDEF; |
|
std::string str=s; |
|
tolower(str); |
|
if(projnames.end()==projnames.find(str)) return false; |
|
proj=projnames[str]; |
|
return true; |
|
} |
|
|
|
static void FillProjNames(); |
|
|
|
private: |
|
static std::map<std::string,projection> projnames; |
|
}; |
|
|
|
|
|
// Color |
|
struct gmt_color |
|
{ |
|
enum ColorModel {RGB,GRAY,HSV,CMYK}; |
|
ColorModel model; |
|
union |
|
{ |
|
double gray; // 0-255 |
|
struct {double r,g,b;}; // 0-255 |
|
struct {double hue,saturation,value;}; // 0-360, 0-1, 0-1 |
|
struct {double cyan,magenta,yellow,black;}; // 0-100 |
|
}; |
|
double transparency; |
|
std::string Value() const |
|
{ |
|
std::string trans=(transparency!=0)?("@"+std::to_string(transparency)):""; |
|
switch(model) |
|
{ |
|
case(RGB): return std::to_string(r)+"/"+std::to_string(g)+"/"+std::to_string(b)+trans; |
|
case(GRAY): return std::to_string(gray)+trans; |
|
case(HSV): return std::to_string(hue)+"-"+std::to_string(saturation)+"-"+std::to_string(value)+trans; |
|
case(CMYK): return std::to_string(cyan)+"/"+std::to_string(magenta)+"/"+std::to_string(yellow)+"/"+std::to_string(black)+trans; |
|
} |
|
return ""; |
|
} |
|
double Gray() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2Gray().gray; |
|
case(GRAY): return gray; |
|
case(HSV): return HSV2Gray().gray; |
|
case(CMYK): return CMYK2Gray().gray; |
|
} |
|
return 0; |
|
} |
|
|
|
double R() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return r; |
|
case(GRAY): return Gray2RGB().r; |
|
case(HSV): return HSV2RGB().r; |
|
case(CMYK): return CMYK2RGB().r; |
|
} |
|
return 0; |
|
} |
|
double G() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return g; |
|
case(GRAY): return Gray2RGB().g; |
|
case(HSV): return HSV2RGB().g; |
|
case(CMYK): return CMYK2RGB().g; |
|
} |
|
return 0; |
|
} |
|
double B() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return b; |
|
case(GRAY): return Gray2RGB().b; |
|
case(HSV): return HSV2RGB().b; |
|
case(CMYK): return CMYK2RGB().b; |
|
} |
|
return 0; |
|
} |
|
|
|
double H() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2HSV().hue; |
|
case(GRAY): return Gray2HSV().hue; |
|
case(HSV): return hue; |
|
case(CMYK): return CMYK2HSV().hue; |
|
} |
|
return 0;// Own functions |
|
} |
|
double S() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2HSV().saturation; |
|
case(GRAY): return Gray2HSV().saturation; |
|
case(HSV): return saturation; |
|
case(CMYK): return CMYK2HSV().saturation; |
|
} |
|
return 0; |
|
} |
|
double V() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2HSV().value; |
|
case(GRAY): return Gray2HSV().value; |
|
case(HSV): return value; |
|
case(CMYK): return CMYK2HSV().value; |
|
} |
|
return 0; |
|
} |
|
|
|
double C() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2CMYK().cyan; |
|
case(GRAY): return Gray2CMYK().cyan; |
|
case(HSV): return HSV2CMYK().cyan; |
|
case(CMYK): return cyan; |
|
} |
|
return 0; |
|
} |
|
double M() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2CMYK().magenta; |
|
case(GRAY): return Gray2CMYK().magenta; |
|
case(HSV): return HSV2CMYK().magenta; |
|
case(CMYK): return magenta; |
|
} |
|
return 0; |
|
} |
|
double Y() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2CMYK().yellow; |
|
case(GRAY): return Gray2CMYK().yellow; |
|
case(HSV): return HSV2CMYK().yellow; |
|
case(CMYK): return yellow; |
|
} |
|
return 0; |
|
} |
|
double K() const |
|
{ |
|
switch(model) |
|
{ |
|
case(RGB): return RGB2CMYK().black; |
|
case(GRAY): return Gray2CMYK().black; |
|
case(HSV): return HSV2CMYK().black; |
|
case(CMYK): return black; |
|
} |
|
return 0; |
|
} |
|
// Transformation functions |
|
private: |
|
#include "colortransform.h" |
|
}; |
|
|
|
|
|
// Dash |
|
struct gmt_dash |
|
{ |
|
std::vector<double> dash; |
|
double shift; |
|
std::string Value() const |
|
{ |
|
std::string ret; |
|
if(dash.empty()) return ret; |
|
for(auto i:dash) ret+=std::to_string(i)+"_"; |
|
ret.back()=':'; |
|
ret+=std::to_string(shift)+"c"; |
|
return ret; |
|
} |
|
operator bool() const {return !dash.empty();} |
|
}; |
|
|
|
|
|
// Pen |
|
struct gmt_pen |
|
{ |
|
double width; |
|
struct gmt_color color; |
|
struct gmt_dash dash; |
|
std::string Value() const {return std::to_string(width)+","+color.Value()+(dash?(","+dash.Value()):"");} |
|
}; |
|
#endif
|
|
|