diff --git a/modules/gmt/modgmt_func.cpp b/modules/gmt/modgmt_func.cpp index 9d56d2e..6762576 100644 --- a/modules/gmt/modgmt_func.cpp +++ b/modules/gmt/modgmt_func.cpp @@ -129,7 +129,6 @@ const ObjectBase* GMT_LayerShift(const ObjectList* input) return new ObjectError("LayerShift",err); } - // Draw frame with tics /* Input: pairs list. @@ -147,169 +146,146 @@ 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. +model - 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. +rx or relx - shift layer on x cm in horisontal direction. Default is 0. +ry or rely - shift layer on y cm in vertical direction. Default is 0. */ +template +using SConvertor=Convert2Struct; +template +using DConvertor=Convert2Struct; + 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; + struct XYIntVal // Representing intervals for tics intervals + { + bool isauto; double val; + XYIntVal():isauto(true),val(0.0) {} // Default is auto + }; - 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 - } + class Base2TInt // Custom convertor class for xy tics intervals + { + public: + using ValueType=struct XYIntVal; - str=yint(&suc); - if(suc && "auto"==str) dy=AutoStep(layer.proj.region.yb,layer.proj.region.ye); - else // No auto, get numeric value + ValueType Convert(const ObjectBase* ob, bool* res, std::string& err) { - Base2Double yint(input,"yint"); - suc=true; - dy=yint(&suc); - if(!suc) goto fail; // Parameter exists, but conversion failed + ValueType ret; + ret.isauto=false; + + OBTypeM sp(ob); + OBTypeM dp(ob); + // Check string "auto" + if(sp.Error()==OBTypeErr::OK) + { + std::string s=sp(res,std::ref(err)); + if(!res) {err="Unknown error"; goto fail;} // Impossible case + tolower(s); + if("auto"==s) {ret.isauto=true; return ret;} + } + // Check double value + switch(dp.Error()) + { + case(OBTypeErr::OK): + { + ret.val=dp(res,std::ref(err)); + if(ret.val<=0.0) {err="Tics interval must be greater the zero"; break;} + return ret; + }; + case(OBTypeErr::NULLPTR): {err="Can't convert zero ObjectBase pointer to something meaningfull"; break;} + case(OBTypeErr::TYPEMISMATCH): {err="Can't convert "+ob->Type()+" to double: type mismatch"; break;} + } + fail: + *res=false; + return ret; } - 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"; + std::string err,fakerr; + std::string opts="-P -O -K "; - 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"; + struct gmt_layer layer; - if(xaxis.empty() || yaxis.empty()) goto fail; // Unknown value of xtics and/or ytics + struct gmt_font deffont; + struct gmt_pen defframepen,deftickpen; + deffont.Convert("12,Times-Roman,black",fakerr); + defframepen.Convert("0.35,black",fakerr); + deftickpen.Convert("0.3,black",fakerr); + + RNFPar proj("projection"); + ONPar xint("x[ ]interval"), yint("y[ ]interval"); + ONPar xtics("x[ ]tics[ ]position","down"), ytics("y[ ]t[ics[ ]position","left"); + ONPar domain("domain","pos"); + ONPar mark("mark",false); + ONPar font("font",deffont); + ONPar offset("offset",0.18); + ONPar framewidth("f[rame][ ]width",0.1); + ONPar framepen("f[rame][ ]pen",defframepen), tickpen("t[icks][ ]pen",deftickpen); + ONPar ticklen("t[icks][ ]length",0.18); + ONPar transp("transparency",0.0); + ONPar transpmodel("model","Normal"); + ONPar rx("r[el]x",0.0),ry("r[el]y",0.0); + + ParseNamedParameters params(input,proj,xint,yint,xtics,ytics,domain,mark,font,offset,framewidth,framepen,tickpen,ticklen,transp,transpmodel,rx,ry); if(!params) {err=params.Error(); goto fail;} // Error parsing parameters + + layer.proj=proj; // Get projection + opts+=layer.proj.Value()+" "; + + { // Get tics intervals + XYIntVal dx=xint,dy=yint; + opts+="-Bx"+ToString(dx.isauto?AutoStep(layer.proj.region.xb,layer.proj.region.xe):dx.val)+" -By"+ToString(dy.isauto?AutoStep(layer.proj.region.yb,layer.proj.region.ye):dy.val)+" "; + } + { // Get xtics and ytics positions + std::string xt=xtics, yt=ytics; + std::string xaxis, yaxis; + TemplateComparator none("none"), both("both"); + TemplateComparator up("up"), down("down"); + TemplateComparator left("left"), right("right"); + tolower(xt); tolower(yt); + + if(none.Compare(xt)) xaxis="sn"; + if(down.Compare(xt)) xaxis="Sn"; + if( up.Compare(xt)) xaxis="sN"; + if(both.Compare(xt)) xaxis="SN"; + + if( none.Compare(yt)) yaxis="we"; + if( left.Compare(yt)) yaxis="We"; + if(right.Compare(yt)) yaxis="wE"; + if( both.Compare(yt)) yaxis="WE"; + + if(xaxis.empty()) {err="Incorrect xtics position "+xtics.Value(); goto fail;} // Unknown value of xtics + if(yaxis.empty()) {err="Incorrect xtics position "+ytics.Value(); goto fail;} // Unknown value of ytics opts+="-B"+xaxis+yaxis+" "; } { // Get domain and mark - BaseMD2String d(input,defdomain,"domain"); - BaseMD2Bool m(input,defmark,"mark"); + std::string dom=domain; std::string format; + TemplateComparator p("positive"),n("negative"),c("centered"); + tolower(dom); - 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 + if(p.Compare(dom)) format="+ddd:mm:ss"; + if(n.Compare(dom)) format="-ddd:mm:ss"; + if(c.Compare(dom)) format="ddd:mm:ss"; + if(format.empty()) {err="Incorrect domain value "+domain.Value(); goto fail;} // Unknown domain + if(mark) format+="F"; 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+" "; - } + opts+="--FONT_ANNOT_PRIMARY="+font.Value().Value()+" "; // Get font + opts+="--MAP_ANNOT_OFFSET_PRIMARY="+ToString(offset.Value())+"c "; // Get offset + opts+="--MAP_FRAME_WIDTH="+ToString(framewidth.Value())+"c "; // Get framewidth + opts+="--MAP_FRAME_PEN="+framepen.Value().Value()+" "; // Get framepen + opts+="--MAP_TICK_LENGTH_PRIMARY="+ToString(ticklen.Value())+"c "; // Get ticklen + opts+="--MAP_TICK_PEN_PRIMARY="+tickpen.Value().Value()+" "; // Get tickpen + if(transp!=0) opts+="-t"+ToString(transp.Value())+" "; // Get transparency + opts+="--PS_TRANSPARENCY="+transpmodel.Value()+" "; // Get transparency model - { // 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 - } + // Get shift + layer.shiftx=rx; + layer.shifty=ry; { // Calling psbasemap void* gmtapi; @@ -328,5 +304,5 @@ const ObjectBase* GMT_DrawFrame(const ObjectList* input) return new ObjectGMTLayer(layer); fail: - return 0; + return new ObjectError("DrawFrame",err); } diff --git a/modules/gmt/modgmt_func.h b/modules/gmt/modgmt_func.h index fe5a386..c101117 100644 --- a/modules/gmt/modgmt_func.h +++ b/modules/gmt/modgmt_func.h @@ -168,6 +168,7 @@ template using Base2StructD=DefaultConverter::Converter>; // Simple aliases of convertors +using Base2Bool =Base2Struct; using Base2Double=Base2Struct; using Base2String=Base2Struct; using Base2Coord =Base2Struct; @@ -182,6 +183,9 @@ using Base2Layer =Base2Struct; // Simple aliases of convertors with default values using Base2StringD=Base2StructD; using Base2DoubleD=Base2StructD; +using Base2BoolD =Base2StructD; +using Base2PenD =Base2StructD; +using Base2FontD =Base2StructD; // Specialised convertors // Convertor with default value for gmt_coord. Added constructor for creating default value from double argument