#ifndef MODGMT_STRUCT_H #define MODGMT_STRUCT_H #include // 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) { size_t bpos=0,pos=str.find(':'); if(std::string::npos==pos) { isdeg=false; return str2double(str,&r); } isdeg=true; int64_t res; // degrees if(! str2int(std::string(str.c_str(),str.c_str()+pos),&res) ) return false; if(res>360 || res<-360) res%=360; sign=(std::string::npos==str.find('-')); d=static_cast(sign?res:-res); // minutes bpos=pos+1; pos=str.find(':',bpos); if(std::string::npos==pos) { if(!str2int(str.substr(bpos),&res)) return false; if(res<0 || res>=60) return false; m=static_cast(res); s=0; return true; } if(! str2int(std::string(str.c_str()+bpos,str.c_str()+pos),&res) ) return false; if(res<0 || res>=60) return false; m=static_cast(res); // seconds if(! str2double(str.substr(pos+1),&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 {A,B,C}; // No UTM (-Ju) enum projection {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 union // other projection parameters { // XY struct {double height;} x; // Cylindrical projections // CYL_EQU (Cylindrical Equidistant -Jq) struct {double stpar,cmer;} q; // MERCATOR (-Jm) struct {double stpar,cmer;} m; // TRANSMERCATOR (-Jt) struct {double cmer,orlat,scale;} t; // OBLIQMERCATOR (-Jo) struct { OType type; double clon,clat; union { double azimuth; // A struct {double eqlon,eqlat;}; // B struct {double polelon,polelat;}; // C }; } o; // CASSINI (-Jc) struct {double clon,clat;} c; // CYL_EQA (Cylindrical equal-area -Jy) struct {double stpar,cmer;} y; // MILLER (-Jj) struct {double cmer;} j; // CYL_STERE (Cylindrical stereographic -Jcyl_stere) struct {double stpar,cmer;} cyl_stere; }; std::string Value() const { switch(proj) { case(XY): return "-JX"+std::to_string(width)+"c/"+std::to_string(x.height)+"c"; case(CYL_EQU): return "-JQ"+std::to_string(q.cmer)+"/"+std::to_string(q.stpar)+"/"+std::to_string(width)+"c"; case(MERCATOR): return "-JM"+std::to_string(m.cmer)+"/"+std::to_string(m.stpar)+"/"+std::to_string(width)+"c"; case(TRANSMERCATOR): return "-JT"+std::to_string(t.cmer)+"/"+std::to_string(t.orlat)+"/"+std::to_string(width)+"c --PROJ_SCALE_FACTOR="+std::to_string(t.scale); case(OBLIQMERCATOR): { switch(o.type) { case(OType::A): return "-JOa"+std::to_string(o.clon)+"/"+std::to_string(o.clat)+"/"+std::to_string(o.azimuth)+"/"+std::to_string(width)+"c"; case(OType::B): return "-JOb"+std::to_string(o.clon)+"/"+std::to_string(o.clat)+"/"+std::to_string(o.eqlon)+"/"+std::to_string(o.eqlat)+"/"+std::to_string(width)+"c"; case(OType::C): return "-JOb"+std::to_string(o.clon)+"/"+std::to_string(o.clat)+"/"+std::to_string(o.polelon)+"/"+std::to_string(o.polelat)+"/"+std::to_string(width)+"c"; } } case(CASSINI): return "-JC"+std::to_string(c.clon)+"/"+std::to_string(c.clat)+"/"+std::to_string(width)+"c"; case(CYL_EQA): return "-JY"+std::to_string(y.stpar)+"/"+std::to_string(y.cmer)+"/"+std::to_string(width)+"c"; case(MILLER): return "-JJ"+std::to_string(j.cmer)+"/"+std::to_string(width)+"c"; case(CYL_STERE): return "-JCyl_stere"+std::to_string(cyl_stere.stpar)+"/"+std::to_string(cyl_stere.cmer)+"/"+std::to_string(width)+"c"; } return ""; } }; // 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 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