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.
383 lines
8.8 KiB
383 lines
8.8 KiB
9 years ago
|
#ifndef MODGMT_STRUCT_H
|
||
|
#define MODGMT_STRUCT_H
|
||
|
#include <cinttypes>
|
||
|
|
||
|
// 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<uint16_t>(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<uint8_t>(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<uint8_t>(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<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
|