diff --git a/modules/gmt/modgmt_func.h b/modules/gmt/modgmt_func.h index 26b8ca8..3aa92ac 100644 --- a/modules/gmt/modgmt_func.h +++ b/modules/gmt/modgmt_func.h @@ -323,18 +323,15 @@ template<> class Convert2Struct { public: - struct gmt_projection operator()(const ObjectList* input, bool* issuc) const + struct gmt_projection operator()(const ObjectList* input, bool* issuc, std::string& err) const { - typedef SearchParameter > BaseM2Nonneg; struct gmt_projection p; - auto size=input->Size(); - bool suc=true; - if(1==size) // Cases 1, and 2 + if(1==input->Size()) // Cases 1, and 2 { - Base2Projection proj(input,0); + Base2Proj proj; bool suc=true; - p=proj(&suc); + p=proj.Convert(input->At(0),&suc,err); if(!suc) goto fail; // Conversion failed return p; } @@ -343,502 +340,321 @@ class Convert2Struct { bool upd; bool changetype=false; - { - BaseMT2Projection updarg(input,"p","proj","projection"); - p=updarg(&upd,&suc); - if(upd && !suc) goto fail; // Conversion failed or too many arguments - suc=true; - } - // Try to set type of projection - { - BaseM2String type(input,"t","type","projtype"); - if(!(type.Exist() || upd)) goto case4; // No named parameter, not update mode, go to case 4 - // Check on redundant parameters - if(type.Exist()) - { - std::string typestr=type(&suc); - if(!suc) goto fail; // Wrong parameter type - if(!p.SetType(typestr)) goto fail; // Incorrect projection type - changetype=true; - } - } + ONFPar proj("projection"); + ONFPar region("region"); + ONPar type("[projection][( |_)]t[ype]","mercator"); + ONPar width("width",gmt_projection::default_width),height("height",gmt_projection::default_width); + + {ParseNamedParameters params(input,type,region,proj,width,height); if(!params) {err=params.Error(); goto fail;}} // Fail to parse by variant 3 - // We need the region + upd=proj.Exist(); + if(upd) p=proj; + + if(!(type.Exist() || upd)) goto case4; // No named parameter, not update mode, go to case 4 + + // Check projection type + if(type.Exist()) { - BaseMT2Region region(input,"r","region"); - if(!(region.Exist() || upd)) goto fail; // Region must be defined in "new" mode - if(region.Exist()) p.region=region(&suc); - if(!suc) goto fail; // Conversion failed + if(!p.SetType(type,err)) goto fail; // Incorrect projection type + changetype=true; } + // Region required in new mode + if(!(region.Exist() || upd)) {err="Region must be specified"; goto fail;} + if(region.Exist()) p.region=region; + + ONPar cmer("c[entral][( |_)]meridian",(p.region.xb+p.region.xe)*0.5), stpar("s[tandar(t|d)][( |_)]parallel",(p.region.yb+p.region.ye)*0.5); + ONPar clon("(l[ongitude][( |_)][of( |_)]center|c[enter][( |_)]longitude)",(p.region.xb+p.region.xe)*0.5); + ONPar clat("(l[atitude][( |_)][of( |_)]center|c[enter][( |_)]latitude)",(p.region.yb+p.region.ye)*0.5); + // Get parameters of projection switch(p.proj) { case(gmt_projection::XY): // x Parameter height (by default equal width) { - BaseM2Nonneg height(input,"height","h"); - if(height.Exist()) - { - bool suc=true; - p.x.height=height(&suc); - if(!suc) goto fail; // Parsing error - } - else - { - BaseM2Nonneg width(input,"width","w"); - if(!width.Exist() && changetype) p.x.height=gmt_projection::default_width; // We ignore case when parameter width exists but have wrong type. It will be handled later. - else - { - bool suc=true; - p.x.height=width(&suc); - if(!suc) goto fail; // Parsing error - } - } + // Width is processing later + if(height.Exist()) p.x.height=height; + else if(changetype) p.x.height=width; // By default, height equal width break; } - case(gmt_projection::CYL_EQU): // q Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region) + case(gmt_projection::CYL_EQU): // q Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region) { - Base2Coord cmer(input,"cmer"), stpar(input,"stpar"); - if(cmer.Exist()) - { - bool suc=true; - p.q.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.q.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.q.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.q.stpar.Convert((p.region.yb+p.region.ye)*0.5); + {ParseNamedParameters apar(input,cmer,stpar); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if( cmer.Exist() || changetype) p.q.cmer =cmer; + if(stpar.Exist() || changetype) p.q.stpar=stpar; break; } case(gmt_projection::MERCATOR): // m Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region) { - Base2Coord cmer(input,"cmer"), stpar(input,"stpar"); - if(cmer.Exist()) - { - bool suc=true; - p.m.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.m.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.m.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.m.stpar.Convert((p.region.yb+p.region.ye)*0.5); + {ParseNamedParameters apar(input,cmer,stpar); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if( cmer.Exist() || changetype) p.m.cmer =cmer; + if(stpar.Exist() || changetype) p.m.stpar=stpar; break; } case(gmt_projection::TRANSMERCATOR): // t Parameters: central meridian (cmer, default is center of region), latitude of origin (orlat, default is 0.0), scale factor (scale, default is 1.0) { - Base2Coord cmer(input,"cmer"), orlat(input,"orlat"); - Base2Double scale(input,"scale"); - if(cmer.Exist()) - { - bool suc=true; - p.t.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.t.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(orlat.Exist()) - { - bool suc=true; - p.t.orlat=orlat(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.t.orlat.Convert(0.0); - if(scale.Exist()) - { - bool suc=true; - p.t.scale=scale(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.t.scale=1.0; + ONPar scale("scale",1.0); + ONPar orlat("(l[atitude][( |_)][of( |_)]origin|o[rigin][( |_)]latitude)",0.0); + {ParseNamedParameters apar(input,cmer,scale,orlat); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if( cmer.Exist() || changetype) p.t.cmer =cmer; + if(orlat.Exist() || changetype) p.t.orlat=orlat; + if(scale.Exist() || changetype) p.t.scale=scale; break; } case(gmt_projection::OBLIQMERCATOR): // o Parameters: longitude of projection center (clon, default is center of region), latitude of projection center (clat, default is center of region). Other parameters may form one of three combinations and doesn't have default values. 1) Azimuth of the oblique equator (azimuth). 2) Longitude and latitude of second point on oblique equator (eqlon, eqlat). 3) Longitude and latitude of projection pole (polelon, polelat). { - Base2Coord clon(input,"clon"), clat(input,"clat"); - Base2Coord azimuth(input,"azimuth"), eqlon(input,"eqlon"), eqlat(input,"eqlat"), polelon(input,"polelon"), polelat(input,"polelat"); + ONPar eqlon("(l[ongitude][( |_)][of( |_)]equator|e[quator][( |_)]longitude)"), eqlat("(l[atitude][( |_)][of( |_)]equator|e[quator][( |_)]latitude)"); + ONPar polelon("(l[ongitude][( |_)][of( |_)]pole|p[ole][( |_)]longitude)"), polelat("(l[atitude][( |_)][of( |_)]pole|p[ole][( |_)]latitude)"); + ONPar azimuth("azimuth"); + {ParseNamedParameters apar(input,clon,clat,eqlon,eqlat,polelon,polelat,azimuth); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if(changetype) p.o.type=gmt_projection::OType::NOTDEF; - if(clon.Exist()) - { - bool suc=true; - p.o.clon=clon(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.o.clon.Convert((p.region.xb+p.region.xe)*0.5); - if(clat.Exist()) + + if(clon.Exist() || changetype) p.o.clon=clon; + if(clat.Exist() || changetype) p.o.clat=clat; + // Check conflict in parameters + if( + (azimuth.Exist() && (eqlon.Exist() || eqlat.Exist() || polelon.Exist() || polelat.Exist() ) ) || + ( (eqlon.Exist() || eqlat.Exist()) && (azimuth.Exist() || polelon.Exist() || polelat.Exist() ) ) || + ( (polelon.Exist() || polelat.Exist()) && (azimuth.Exist() || eqlon.Exist() || eqlat.Exist() ) ) + ) { - bool suc=true; - p.o.clat=clat(&suc); - if(!suc) goto fail; // Parsing error + err="Conflict in parameters for oblique Mercator projection, must specify only one variant: 1) azimuth of oblique equator, or 2) longitude and latitude of point on oblique equator, or 3) longitude and latitude of projection pole"; + goto fail; // Insufficient data for this projection } - else if(changetype) p.o.clat.Convert((p.region.yb+p.region.ye)*0.5); // Variant 1 - if(azimuth) + if(azimuth.Exist()) { - bool suc=(gmt_projection::OType::NOTDEF==p.o.type); // If projection subtype already defined, this is an error p.o.type=gmt_projection::OType::A; - p.o.azimuth=azimuth(&suc); - if(!suc) goto fail; // Parsing error + p.o.azimuth=azimuth; } - if(eqlon && eqlat) + // Variant 2 + if(eqlon.Exist() && eqlat.Exist()) { - bool suc=(gmt_projection::OType::NOTDEF==p.o.type); // If projection subtype already defined, this is an error p.o.type=gmt_projection::OType::B; - p.o.eqlon=eqlon(&suc); - p.o.eqlat=eqlat(&suc); - if(!suc) goto fail; // Parsing error + p.o.eqlon=eqlon; + p.o.eqlat=eqlat; } - if(polelon && polelat) + // Variant 3 + if(polelon.Exist() && polelat.Exist()) { - bool suc=(gmt_projection::OType::NOTDEF==p.o.type); // If projection subtype already defined, this is an error p.o.type=gmt_projection::OType::C; - p.o.polelon=polelon(&suc); - p.o.polelat=polelat(&suc); - if(!suc) goto fail; // Parsing error + p.o.polelon=polelon; + p.o.polelat=polelat; } - if(gmt_projection::OType::NOTDEF==p.o.type) goto fail; // Insufficient data for this projection - break; - } - case(gmt_projection::CASSINI): // c Parameters: longitude (clon, default is center of region) and latitude (clat, default is center of region) of central point. - { - Base2Coord clon(input,"clon"), clat(input,"clat"); - if(clon.Exist()) + // Special processing of update case + if(!changetype) { - bool suc=true; - p.c.clon=clon(&suc); - if(!suc) goto fail; // Parsing error + if(eqlon.Exist() && !eqlat.Exist()) + { + if(gmt_projection::OType::B!=p.o.type) {err="Insufficient parameters for oblique Mercator projection, must specify latitude of point on oblique equator"; goto fail;} + else p.o.eqlon=eqlon; + } + if(!eqlon.Exist() && eqlat.Exist()) + { + if(gmt_projection::OType::B!=p.o.type) {err="Insufficient parameters for oblique Mercator projection, must specify longitude of point on oblique equator"; goto fail;} + else p.o.eqlat=eqlat; + } + if(polelon.Exist() && !polelat.Exist()) + { + if(gmt_projection::OType::C!=p.o.type) {err="Insufficient parameters for oblique Mercator projection, must specify latitude of projection pole"; goto fail;} + else p.o.polelon=polelon; + } + if(!polelon.Exist() && polelat.Exist()) + { + if(gmt_projection::OType::C!=p.o.type) {err="Insufficient parameters for oblique Mercator projection, must specify longitude of projection pole"; goto fail;} + else p.o.polelat=polelat; + } } - else if(changetype) p.c.clon.Convert((p.region.xb+p.region.xe)*0.5); - if(clat.Exist()) + if(gmt_projection::OType::NOTDEF==p.o.type) { - bool suc=true; - p.c.clat=clat(&suc); - if(!suc) goto fail; // Parsing error + err="Insufficient parameters for oblique Mercator projection, must specify azimuth of oblique equator, or longitude and latitude of point on oblique equator, or longitude and latitude of projection pole"; + goto fail; // Insufficient data for this projection } - else if(changetype) p.c.clat.Convert((p.region.yb+p.region.ye)*0.5); + break; + } + case(gmt_projection::CASSINI): // c Parameters: longitude (clon, default is center of region) and latitude (clat, default is center of region) of central point. + { + {ParseNamedParameters apar(input,clon,clat); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if(clon.Exist() || changetype) p.c.clon =clon; + if(clat.Exist() || changetype) p.c.clat =clat; break; } case(gmt_projection::CYL_EQA): // y Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region) { - Base2Coord cmer(input,"cmer"), stpar(input,"stpar"); - if(cmer.Exist()) - { - bool suc=true; - p.y.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.y.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.y.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.y.stpar.Convert((p.region.yb+p.region.ye)*0.5); + {ParseNamedParameters apar(input,cmer,stpar); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if( cmer.Exist() || changetype) p.y.cmer =cmer; + if(stpar.Exist() || changetype) p.y.stpar=stpar; break; } case(gmt_projection::MILLER): // j Parameters: central meridian (cmer, default is center of region) { - Base2Coord cmer(input,"cmer"); - if(cmer.Exist()) - { - bool suc=true; - p.j.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.j.cmer.Convert((p.region.xb+p.region.xe)*0.5); + {ParseNamedParameters apar(input,cmer); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if(cmer.Exist() || changetype) p.j.cmer=cmer; break; } case(gmt_projection::CYL_STERE): // cyl_stere Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region) { - Base2Coord cmer(input,"cmer"), stpar(input,"stpar"); - if(cmer.Exist()) - { - bool suc=true; - p.cyl_stere.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.cyl_stere.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.cyl_stere.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else if(changetype) p.cyl_stere.stpar.Convert((p.region.yb+p.region.ye)*0.5); + {ParseNamedParameters apar(input,cmer,stpar); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters + if( cmer.Exist() || changetype) p.cyl_stere.cmer =cmer; + if(stpar.Exist() || changetype) p.cyl_stere.stpar=stpar; break; } - default: goto fail; // Unknown projection + default: {err="Code error, unknown projection"; goto fail;} // Unknown projection } - // Try to find width parameter - if(!upd) p.width=p.default_width; + + // Width and height manipulations + if(width.Exist() && height.Exist() && gmt_projection::XY!=p.proj) {err="For geographic projections only one of width or height can be specified"; goto fail;} + if(!upd) p.width=width; { - BaseM2Nonneg w(input,"width","w"),h(input,"height","h"); - bool suc=true; - if(w.Exist()) // width is present + if(width.Exist()) // width is present { - p.width=w(&suc); - if(!suc) goto fail; // Parameter width exists, but can't be converted to double - if(!ProjectionRealSize(p)) goto fail; // Something go wrong with determining real dimensions + p.width=width; + if(!ProjectionRealSize(p)) goto failrealsize; // Something go wrong with determining real dimensions } - else if(h.Exist()) // width is not present, but height is present + else if(height.Exist()) // width is not present, but height is present { - double hval=h(&suc); - if(!suc) goto fail; // Parameter height exists, but can't be converted to double - if(gmt_projection::XY==p.proj) p.width=hval; // For decart projection we use height as width if width is not specified - if(!ProjectionRealSize(p,hval)) goto fail; // Something go wrong with determining real dimensions + if(gmt_projection::XY==p.proj) p.width=height; // For decart projection we use height as width if width is not specified + if(!ProjectionRealSize(p,height)) goto failrealsize; } else // No width, no height, using default or old width - if(!ProjectionRealSize(p)) goto fail; // Something go wrong with determining real dimensions + if(!ProjectionRealSize(p)) goto failrealsize; // Something go wrong with determining real dimensions } return p; // All parameters setted + failrealsize: + err="Can't determine real size of projection "+p.Value(); + goto fail; } case4: - // Case 4 - if(size>=3) + { - // First argument, try to set type of projection - { - Base2String type(input,0); - bool suc=true; - std::string typestr; - typestr=type(&suc); - if(!suc) goto fail; // No type - no projection - if(!p.SetType(typestr)) goto fail; // Unknown type - no projection - } - // Second argument, set up width - { - Base2Double w(input,1); - bool suc=true; - p.width=w(&suc); - if(!suc) goto fail; // Conversion failed, no width - } - // Third argument, set up region - { - Base2Region reg(input,2); - bool suc=true; - p.region=reg(&suc); - if(!suc) goto fail; // Conversion failed, no region - } + RPosPar type("projection type"); + RPosPar width("width"); + RPosPar region("region"); + + {ParsePositionalParameters params(input,0,3,type,width,region); if(!params) {err=params.Error(); goto fail;}} // Fail to parse by variant 4 + + if(!p.SetType(type,err)) goto fail; // Incorrect projection type + p.width=width; + p.region=region; // Projection specific parameters switch(p.proj) { case(gmt_projection::XY): // x Parameter 4 is height (by default equal width) { - Base2Double height(input,3); - if(height.Exist()) - { - bool suc=true; - p.x.height=height(&suc); - if(!suc) goto fail; // Parsing error - } - else p.x.height=p.width; - if(size>4) goto fail; // Unknown parameter(s) + OPosPar height("height",p.width); + {ParsePositionalParameters params(input,3,input->Size(),height); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.x.height=height; break; } case(gmt_projection::CYL_EQU): // q Parameters: 4 is central meridian (default is center of region), 5 is standart parallel (default is center of region) { - Base2Coord cmer(input,3), stpar(input,4); - if(cmer.Exist()) - { - bool suc=true; - p.q.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else p.q.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.q.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else p.q.stpar.Convert((p.region.yb+p.region.ye)*0.5); - if(size>5) goto fail; // Unknown parameter(s) + OPosPar cmer("central meridian",(p.region.xb+p.region.xe)*0.5); + OPosPar stpar("standart parallel",(p.region.yb+p.region.ye)*0.5); + {ParsePositionalParameters params(input,3,input->Size(),cmer,stpar); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.q.cmer=cmer; p.q.stpar=stpar; break; } case(gmt_projection::MERCATOR): // m Parameters: 4 is central meridian (default is center of region), 5 is standart parallel (default is center of region) { - Base2Coord cmer(input,3), stpar(input,4); - if(cmer.Exist()) - { - bool suc=true; - p.m.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else p.m.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.m.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else p.m.stpar.Convert((p.region.yb+p.region.ye)*0.5); - if(size>5) goto fail; // Unknown parameter(s) + OPosPar cmer("central meridian",(p.region.xb+p.region.xe)*0.5); + OPosPar stpar("standart parallel",(p.region.yb+p.region.ye)*0.5); + {ParsePositionalParameters params(input,3,input->Size(),cmer,stpar); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.m.cmer=cmer; p.m.stpar=stpar; break; } case(gmt_projection::TRANSMERCATOR): // t Parameters: 4 is central meridian (default is center of region), 5 is latitude of origin (default is 0.0), 6 is scale factor (default is 1.0) { - Base2Coord cmer(input,3), orlat(input,4); - Base2Double scale(input,5); - if(cmer.Exist()) - { - bool suc=true; - p.t.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else p.t.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(orlat.Exist()) - { - bool suc=true; - p.t.orlat=orlat(&suc); - if(!suc) goto fail; // Parsing error - } - else p.t.orlat.Convert(0.0); - if(scale.Exist()) - { - bool suc=true; - p.t.scale=scale(&suc); - if(!suc) goto fail; // Parsing error - } - else p.t.scale=1.0; - if(size>6) goto fail; // Unknown parameter(s) + OPosPar cmer("central meridian",(p.region.xb+p.region.xe)*0.5); + OPosPar orlat("latitude of origin",0.0); + OPosPar scale("scale",1.0); + {ParsePositionalParameters params(input,3,input->Size(),cmer,orlat,scale); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.t.cmer=cmer; p.t.orlat=orlat; p.t.scale=scale; break; } case(gmt_projection::OBLIQMERCATOR): // o There is no default values for this projection. Parameters: 4 is subtype ("a" or "azimuth", "b" or "equator", "c" or "pole"), 5 is longitude of projection center, 6 is latitude of projection center. Other parameters may form one of three combinations. 1) 7 is azimuth of the oblique equator. 2) Longitude and latitude of second point on oblique equator (7, 8). 3) Longitude and latitude of projection pole (7, 8). { - if(size<4) goto fail; // Insufficient data for this projection - OBType stype(input->At(3)); - if(!stype) goto fail; // Incorrect parameter type - std::string subtype=stype->Value(); - tolower(subtype); - Base2Coord clon(input,4), clat(input,5); - Base2Coord azimuth(input,6), eqlon(input,6), eqlat(input,7), polelon(input,6), polelat(input,7); + RPosPar pstype("subtype"); + RPosPar clon("longitude of center"); + RPosPar clat("latitude of center"); + + {ParsePositionalParameters params(input,3,6,pstype,clon,clat); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + TemplateComparator a("azimuth"),b("(b|equator)"),c("(c|pole)"); + std::string stype=pstype; + tolower(stype); + + p.o.clon=clon; p.o.clat=clat; p.o.type=gmt_projection::OType::NOTDEF; - { - bool suc=true; - p.o.clon=clon(&suc); - p.o.clat=clat(&suc); - if(!suc) goto fail; // Parsing error - } + // Variant 1 - if("a"==subtype || "azimuth"==subtype) + if(a.Compare(stype)) { + RPosPar azimuth("azimuth"); + {ParsePositionalParameters params(input,6,input->Size(),azimuth); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters p.o.type=gmt_projection::OType::A; - bool suc=true; - p.o.azimuth=azimuth(&suc); - if(!suc) goto fail; // Parsing error - if(size>7) goto fail; // Unknown parameter(s) + p.o.azimuth=azimuth; } - if("b"==subtype || "equator"==subtype) + if(b.Compare(stype)) { + RPosPar eqlon("longitude of equator"); + RPosPar eqlat("latitude of equator"); + {ParsePositionalParameters params(input,6,input->Size(),eqlon,eqlat); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters p.o.type=gmt_projection::OType::B; - bool suc=true; - p.o.eqlon=eqlon(&suc); - p.o.eqlat=eqlat(&suc); - if(!suc) goto fail; // Parsing error - if(size>8) goto fail; // Unknown parameter(s) + p.o.eqlon=eqlon; + p.o.eqlat=eqlat; } - if("c"==subtype || "pole"==subtype) + if(c.Compare(stype)) { + RPosPar polelon("longitude of pole"); + RPosPar polelat("latitude of pole"); + {ParsePositionalParameters params(input,6,input->Size(),polelon,polelat); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters p.o.type=gmt_projection::OType::C; - bool suc=true; - p.o.polelon=polelon(&suc); - p.o.polelat=polelat(&suc); - if(!suc) goto fail; // Parsing error - if(size>8) goto fail; // Unknown parameter(s) + p.o.polelon=polelon; + p.o.polelat=polelat; } - if(gmt_projection::OType::NOTDEF==p.o.type) goto fail; // Insufficient data for this projection + if(gmt_projection::OType::NOTDEF==p.o.type) {err="String "+pstype.Value()+" is invalid subtype for oblique Mercator projection. The valid subtypes are azimuth, equator or pole"; goto fail;} break; } case(gmt_projection::CASSINI): // c Parameters: longitude (4, default is center of region) and latitude (5, default is center of region) of central point. { - Base2Coord clon(input,3), clat(input,4); - if(clon.Exist()) - { - bool suc=true; - p.c.clon=clon(&suc); - if(!suc) goto fail; // Parsing error - } - else p.c.clon.Convert((p.region.xb+p.region.xe)*0.5); - if(clat.Exist()) - { - bool suc=true; - p.c.clat=clat(&suc); - if(!suc) goto fail; // Parsing error - } - else p.c.clat.Convert((p.region.yb+p.region.ye)*0.5); - if(size>5) goto fail; // Unknown parameter(s) + OPosPar clon("longitude of center",(p.region.xb+p.region.xe)*0.5); + OPosPar clat("latitude of center",(p.region.yb+p.region.ye)*0.5); + {ParsePositionalParameters params(input,3,input->Size(),clon,clat); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.c.clon=clon; p.c.clat=clat; break; } case(gmt_projection::CYL_EQA): // y Parameters: central meridian (4, default is center of region), standart parallel (5, default is center of region) { - Base2Coord cmer(input,3), stpar(input,4); - if(cmer.Exist()) - { - bool suc=true; - p.y.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else p.y.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.y.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else p.y.stpar.Convert((p.region.yb+p.region.ye)*0.5); - if(size>5) goto fail; // Unknown parameter(s) + OPosPar cmer("central meridian",(p.region.xb+p.region.xe)*0.5); + OPosPar stpar("standart parallel",(p.region.yb+p.region.ye)*0.5); + {ParsePositionalParameters params(input,3,input->Size(),cmer,stpar); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.y.cmer=cmer; p.y.stpar=stpar; break; } case(gmt_projection::MILLER): // j Parameters: central meridian (4, default is center of region) { - Base2Coord cmer(input,3); - if(cmer.Exist()) - { - bool suc=true; - p.j.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else p.j.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(size>4) goto fail; // Unknown parameter(s) + OPosPar cmer("central meridian",(p.region.xb+p.region.xe)*0.5); + {ParsePositionalParameters params(input,3,input->Size(),cmer); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.j.cmer=cmer; break; } case(gmt_projection::CYL_STERE): // cyl_stere Parameters: central meridian (3, default is center of region), standart parallel (4, default is center of region) { - Base2Coord cmer(input,3), stpar(input,4); - if(cmer.Exist()) - { - bool suc=true; - p.cyl_stere.cmer=cmer(&suc); - if(!suc) goto fail; // Parsing error - } - else p.cyl_stere.cmer.Convert((p.region.xb+p.region.xe)*0.5); - if(stpar.Exist()) - { - bool suc=true; - p.cyl_stere.stpar=stpar(&suc); - if(!suc) goto fail; // Parsing error - } - else p.cyl_stere.stpar.Convert((p.region.yb+p.region.ye)*0.5); - if(size>5) goto fail; // Unknown parameter(s) + OPosPar cmer("central meridian",(p.region.xb+p.region.xe)*0.5); + OPosPar stpar("standart parallel",(p.region.yb+p.region.ye)*0.5); + {ParsePositionalParameters params(input,3,input->Size(),cmer,stpar); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters + p.cyl_stere.cmer=cmer; p.cyl_stere.stpar=stpar; break; } default: goto fail; // Unknown projection } if(ProjectionRealSize(p)) return p; + err="Can't determine real size of projection "+p.Value(); } fail: