#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; bool suc=true; Base2RGB g(input,0); Base2Transp t(input,1); c.model=gmt_color::GRAY; c.gray=g(&suc); c.transparency=t(&suc); if(suc) return new ObjectGMTColor(c); else return 0; } const ObjectBase* GMT_ColorRGB(const ObjectList* input) { struct gmt_color c; bool suc=true; Base2RGB r(input,0),g(input,1),b(input,2); Base2Transp t(input,3); c.model=gmt_color::RGB; c.r=r(&suc); c.g=g(&suc); c.b=b(&suc); c.transparency=t(&suc); if(suc) return new ObjectGMTColor(c); else return 0; } const ObjectBase* GMT_ColorHSV(const ObjectList* input) { struct gmt_color c; bool suc=true; Base2Hue h(input,0); Base2SV s(input,1),v(input,2); Base2Transp t(input,3); c.model=gmt_color::HSV; c.hue=h(&suc); c.saturation=s(&suc); c.value=v(&suc); c.transparency=t(&suc); if(suc) return new ObjectGMTColor(c); else return 0; } const ObjectBase* GMT_ColorCMYK(const ObjectList* input) { struct gmt_color c; bool suc=true; Base2CMYK cyan(input,0),m(input,1),y(input,2),k(input,3); Base2Transp t(input,4); c.model=gmt_color::CMYK; c.cyan=cyan(&suc); c.magenta=m(&suc); c.yellow=y(&suc); c.black=k(&suc); c.transparency=t(&suc); if(suc) return new ObjectGMTColor(c); else return 0; } // 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 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 > 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; }