#ifndef MODGMT_STRUCT_H #define MODGMT_STRUCT_H #include #include #include #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(sign?res:-res); // minutes cw++; if(!str2int(*cw,&res)) return false; if(res<0 || res>=60) return false; m=static_cast(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 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 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