|
|
|
#include "modgmt_func.h"
|
|
|
|
|
|
|
|
static double AutoStep(double b, double e)
|
|
|
|
{
|
|
|
|
double n=pow(10.0,ceil(log10(e-b)-1.0));
|
|
|
|
double steps[]={0.5,1,2,5,10,0};
|
|
|
|
double div=0.0;
|
|
|
|
uint i=0;
|
|
|
|
|
|
|
|
do if((e-b)*steps[i]/n<10.0) div=n/steps[i]; while(0.0!=steps[++i]);
|
|
|
|
return div;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectBase* GMT_Header(const ObjectList* input)
|
|
|
|
{
|
|
|
|
return new ObjectString(header);
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectBase* GMT_Footer(const ObjectList* input)
|
|
|
|
{
|
|
|
|
return new ObjectString(footer);
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectBase* GMT_ColorGray(const ObjectList* input)
|
|
|
|
{
|
|
|
|
struct gmt_color c;
|
|
|
|
RPosPar<Base2RGB> g("gray");
|
|
|
|
OPosPar<Base2TransD> t("transparency",0.0);
|
|
|
|
|
|
|
|
ParsePositionalParameters params(input,g,t);
|
|
|
|
if(!params) return new ObjectError("ColorGray",params.Error());
|
|
|
|
|
|
|
|
c.model=gmt_color::GRAY;
|
|
|
|
c.gray=g; c.transparency=t;
|
|
|
|
|
|
|
|
return new ObjectGMTColor(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectBase* GMT_ColorRGB(const ObjectList* input)
|
|
|
|
{
|
|
|
|
struct gmt_color c;
|
|
|
|
|
|
|
|
RPosPar<Base2RGB> r("red"),g("green"),b("blue");
|
|
|
|
OPosPar<Base2TransD> t("transparency",0.0);
|
|
|
|
|
|
|
|
ParsePositionalParameters params(input,r,g,b,t);
|
|
|
|
if(!params) return new ObjectError("ColorRGB",params.Error());
|
|
|
|
|
|
|
|
c.model=gmt_color::RGB;
|
|
|
|
c.r=r; c.g=g; c.b=b; c.transparency=t;
|
|
|
|
|
|
|
|
return new ObjectGMTColor(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectBase* GMT_ColorHSV(const ObjectList* input)
|
|
|
|
{
|
|
|
|
struct gmt_color c;
|
|
|
|
|
|
|
|
RPosPar<Base2Hue> h("hue");
|
|
|
|
RPosPar<Base2SV> s("saturation"), v("value");
|
|
|
|
OPosPar<Base2TransD> t("transparency",0.0);
|
|
|
|
|
|
|
|
ParsePositionalParameters params(input,h,s,v,t);
|
|
|
|
if(!params) return new ObjectError("ColorHSV",params.Error());
|
|
|
|
|
|
|
|
c.model=gmt_color::HSV;
|
|
|
|
c.hue=h; c.saturation=s; c.value=v; c.transparency=t;
|
|
|
|
|
|
|
|
return new ObjectGMTColor(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectBase* GMT_ColorCMYK(const ObjectList* input)
|
|
|
|
{
|
|
|
|
struct gmt_color C;
|
|
|
|
|
|
|
|
RPosPar<Base2CMYK> c("cyan"),m("magenta"),y("yellow"),k("black");
|
|
|
|
OPosPar<Base2TransD> t("transparency",0.0);
|
|
|
|
|
|
|
|
ParsePositionalParameters params(input,c,m,y,k,t);
|
|
|
|
if(!params) return new ObjectError("ColorCMYK",params.Error());
|
|
|
|
|
|
|
|
C.model=gmt_color::CMYK;
|
|
|
|
C.cyan=c; C.magenta=m; C.yellow=y; C.black=k; C.transparency=t;
|
|
|
|
|
|
|
|
return new ObjectGMTColor(C);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Shifting layer
|
|
|
|
/*
|
|
|
|
Input:
|
|
|
|
1) Three arguments, first is Layer, second and third are double. Interprets as new absolute position in cm.
|
|
|
|
2) Pairs list. Names are l (layer), x, y, xrel (xr), yrel (yr). Pair with name l may be absent, in this case search in list and using as layer object with ObjectGMTLayer type. x and y are absolute positions in cm, xrel and yrel are shift from current position. x (y) and xrel (yrel) are mutually exlusive, but x (y) and yrel (xrel) can be used simultaneously. If position for some axis is absent, then this position is unchanged.
|
|
|
|
*/
|
|
|
|
const ObjectBase* GMT_LayerShift(const ObjectList* input)
|
|
|
|
{
|
|
|
|
auto size=input->Size();
|
|
|
|
struct gmt_layer layer;
|
|
|
|
|
|
|
|
// Case 1
|
|
|
|
if(3==size)
|
|
|
|
{
|
|
|
|
Base2Layer l(input,0);
|
|
|
|
Base2Double x(input,1), y(input,2);
|
|
|
|
bool suc=true;
|
|
|
|
layer=l(&suc);
|
|
|
|
if(!suc) goto case2;
|
|
|
|
layer.shiftx=x(&suc);
|
|
|
|
layer.shifty=y(&suc);
|
|
|
|
if(!suc) goto case2;
|
|
|
|
return new ObjectGMTLayer(layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
case2:
|
|
|
|
|
|
|
|
// Search layer for shifting
|
|
|
|
{
|
|
|
|
SearchParameter<struct gmt_layer> original(input,"layer","l");
|
|
|
|
bool suc=true;
|
|
|
|
layer=original(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed or too many arguments
|
|
|
|
}
|
|
|
|
// Do shift
|
|
|
|
{
|
|
|
|
BaseM2Double xr(input,"xrel","xr"), yr(input,"yrel","yr");
|
|
|
|
Base2Double x(input,"x"), y(input,"y");
|
|
|
|
bool suc=true;
|
|
|
|
// Check duplicate parameters
|
|
|
|
if( ( x.Exist() && xr.Exist() ) || ( y.Exist() && yr.Exist() ) ) goto fail;
|
|
|
|
if(x.Exist()) layer.shiftx=x(&suc);
|
|
|
|
if(y.Exist()) layer.shifty=y(&suc);
|
|
|
|
if(xr.Exist()) layer.shiftx+=x(&suc);
|
|
|
|
if(yr.Exist()) layer.shifty+=y(&suc);
|
|
|
|
if(!suc) goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new ObjectGMTLayer(layer);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Draw frame with tics
|
|
|
|
/*
|
|
|
|
Input: pairs list.
|
|
|
|
proj or projection or unnamed GMTProjection parameter - projection. This is mandatory argument.
|
|
|
|
xtics - position of tics for x axis. Can be none, up, down or both. Default is down.
|
|
|
|
ytics - position of tics for y axis. Can be none, left, right or both. Default is left.
|
|
|
|
xint - tics interval for x axis. Numerical value or word auto. Default is auto.
|
|
|
|
yint - tics interval for y axis. Numerical value or word auto. Default is auto.
|
|
|
|
domain - coordinates domain. Can be pos (0:360), neg (-360:0) or center (-180:180) (only for geographic projections). Default is pos.
|
|
|
|
mark - using letters (W, E, S, N) instead of sign for coordinates (only for geographic projections). Can be yes or no. Default is no.
|
|
|
|
font - font using for annotations. Default is 12,Times-Roman,black.
|
|
|
|
offset - distance from end of tick-mark to start of annotation in cm. Default is 0.18.
|
|
|
|
framewidth - width of frame (only for geographic projections) in cm. Default is 0.1.
|
|
|
|
framepen - pen for drawing frame. Default is 0.35,black.
|
|
|
|
ticklen - lenght of tick-marks in cm. Default is 0.18.
|
|
|
|
tickpen - pen for drawing ticks. Default is 0.3,black.
|
|
|
|
trans or transparency - transparency level, double from 0 to 100. Default is 0 (opaque).
|
|
|
|
transpmodel - transparency model, string. Choose from Color, ColorBurn, ColorDodge, Darken, Difference, Exclusion, HardLight, Hue, Lighten, Luminosity, Multiply, Normal, Overlay, Saturation, SoftLight, and Screen. Default is Normal.
|
|
|
|
x, xr or xrel - shift layer on x cm in horisontal direction. Default is 0.
|
|
|
|
y, yr or yrel - shift layer on y cm in vertical direction. Default is 0.
|
|
|
|
*/
|
|
|
|
const ObjectBase* GMT_DrawFrame(const ObjectList* input)
|
|
|
|
{
|
|
|
|
std::string opts="-P -O -K ";
|
|
|
|
bool suc=true;
|
|
|
|
struct gmt_layer layer;
|
|
|
|
// Defaults
|
|
|
|
std::string defxtics="down", defytics="left", defint="auto", defdomain="pos", deftranspmodel="Normal";
|
|
|
|
bool defmark=false;
|
|
|
|
gmt_font deffont; deffont.Convert("12,Times-Roman,black");
|
|
|
|
double defoffset=0.18, defframewidth=0.1, defticklen=0.18;
|
|
|
|
gmt_pen defframepen, deftickpen; defframepen.Convert("0.35,black"); deftickpen.Convert("0.3,black");
|
|
|
|
|
|
|
|
{ // Get projection
|
|
|
|
BaseMT2Projection proj(input,"proj","projection");
|
|
|
|
|
|
|
|
layer.proj=proj(&suc);
|
|
|
|
if(!suc) goto fail;
|
|
|
|
opts+=layer.proj.Value()+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get xint and yint
|
|
|
|
BaseMD2String xint(input,defint,"xint"), yint(input,defint,"yint");
|
|
|
|
double dx,dy;
|
|
|
|
std::string str;
|
|
|
|
|
|
|
|
str=xint(&suc);
|
|
|
|
if(suc && "auto"==str) dx=AutoStep(layer.proj.region.xb,layer.proj.region.xe);
|
|
|
|
else // No auto, get numeric value
|
|
|
|
{
|
|
|
|
Base2Double xint(input,"xint");
|
|
|
|
suc=true;
|
|
|
|
dx=xint(&suc);
|
|
|
|
if(!suc) goto fail; // Parameter exists, but conversion failed
|
|
|
|
}
|
|
|
|
|
|
|
|
str=yint(&suc);
|
|
|
|
if(suc && "auto"==str) dy=AutoStep(layer.proj.region.yb,layer.proj.region.ye);
|
|
|
|
else // No auto, get numeric value
|
|
|
|
{
|
|
|
|
Base2Double yint(input,"yint");
|
|
|
|
suc=true;
|
|
|
|
dy=yint(&suc);
|
|
|
|
if(!suc) goto fail; // Parameter exists, but conversion failed
|
|
|
|
}
|
|
|
|
opts+="-Bx"+ToString(dx)+" -By"+ToString(dy)+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get xtics and ytics
|
|
|
|
BaseMD2String x(input,defxtics,"xtics"), y(input,defytics,"ytics");
|
|
|
|
std::string xtics,ytics;
|
|
|
|
std::string xaxis,yaxis;
|
|
|
|
|
|
|
|
xtics=x(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
if("none"==xtics) xaxis="sn";
|
|
|
|
if("down"==xtics) xaxis="Sn";
|
|
|
|
if("up"==xtics) xaxis="sN";
|
|
|
|
if("both"==xtics) xaxis="SN";
|
|
|
|
|
|
|
|
ytics=y(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
if("none"==ytics) yaxis="we";
|
|
|
|
if("left"==ytics) yaxis="We";
|
|
|
|
if("right"==ytics) yaxis="wE";
|
|
|
|
if("both"==ytics) yaxis="WE";
|
|
|
|
|
|
|
|
if(xaxis.empty() || yaxis.empty()) goto fail; // Unknown value of xtics and/or ytics
|
|
|
|
|
|
|
|
opts+="-B"+xaxis+yaxis+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get domain and mark
|
|
|
|
BaseMD2String d(input,defdomain,"domain");
|
|
|
|
BaseMD2Bool m(input,defmark,"mark");
|
|
|
|
std::string format;
|
|
|
|
|
|
|
|
std::string domain=d(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
if("pos"==domain) format="+ddd:mm:ss";
|
|
|
|
if("neg"==domain) format="-ddd:mm:ss";
|
|
|
|
if("center"==domain) format="ddd:mm:ss";
|
|
|
|
if(format.empty()) goto fail; // Unknown domain
|
|
|
|
|
|
|
|
if(m(&suc)) format+="F";
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
|
|
|
|
opts+="--FORMAT_GEO_MAP="+format+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get font
|
|
|
|
BaseMD2Font f(input,deffont,"font");
|
|
|
|
gmt_font font;
|
|
|
|
font=f(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
opts+="--FONT_ANNOT_PRIMARY="+font.Value()+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get offset
|
|
|
|
BaseMD2Double o(input,defoffset,"offset");
|
|
|
|
double offset;
|
|
|
|
offset=o(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
opts+="--MAP_ANNOT_OFFSET_PRIMARY="+ToString(offset)+"c ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get framewidth
|
|
|
|
SearchParameterWDef<double,false,PMin<0> > f(input,defframewidth,"framewidth");
|
|
|
|
double framewidth;
|
|
|
|
framewidth=f(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
opts+="--MAP_FRAME_WIDTH="+ToString(framewidth)+"c ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get framepen
|
|
|
|
BaseMD2Pen p(input,defframepen,"framepen");
|
|
|
|
gmt_pen framepen;
|
|
|
|
framepen=p(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
opts+="--MAP_FRAME_PEN="+framepen.Value()+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get ticklen
|
|
|
|
BaseMD2Double t(input,defticklen,"ticklen","ticklength");
|
|
|
|
double ticklen;
|
|
|
|
ticklen=t(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
opts+="--MAP_TICK_LENGTH_PRIMARY="+ToString(ticklen)+"c ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get tickpen
|
|
|
|
BaseMD2Pen t(input,deftickpen,"tickpen");
|
|
|
|
gmt_pen tickpen;
|
|
|
|
tickpen=t(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
opts+="--MAP_TICK_PEN_PRIMARY="+tickpen.Value()+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get transparency
|
|
|
|
Base2Transp t(input,"trans","transp","transparency");
|
|
|
|
double transp;
|
|
|
|
transp=t(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
if(transp!=0) opts+="-t"+ToString(transp)+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get transpmodel
|
|
|
|
BaseMD2String tm(input,deftranspmodel,"transpmodel","transparencymodel");
|
|
|
|
std::string transpmodel;
|
|
|
|
transpmodel=tm(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
opts+="--PS_TRANSPARENCY="+transpmodel+" ";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Get x, y
|
|
|
|
BaseMD2Double x(input,0.0,"x","xr","xrel"), y(input,0.0,"y","yr","yrel");
|
|
|
|
layer.shiftx=x(&suc);
|
|
|
|
layer.shifty=y(&suc);
|
|
|
|
if(!suc) goto fail; // Conversion failed
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Calling psbasemap
|
|
|
|
void* gmtapi;
|
|
|
|
std::string* draw=new std::string;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
gmtapi=GMT_Create_Session("DrawFrame",2,GMTMODE,0);
|
|
|
|
if(0==gmtapi) goto fail; // Can't create GMT GMT_Create_Session
|
|
|
|
ret=callgmtmodule(gmtapi,"psbasemap",opts,draw);
|
|
|
|
GMT_Destroy_Session(gmtapi);
|
|
|
|
if(0!=ret) {delete draw; goto fail;} // Psbasemap error
|
|
|
|
layer.data.reset(draw);
|
|
|
|
}
|
|
|
|
|
|
|
|
layer.creator="psbasemap "+opts;
|
|
|
|
return new ObjectGMTLayer(layer);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return 0;
|
|
|
|
}
|