Browse Source

Gmt module: Conversion function for GMTProjection now using new parameter reading scheme and error reporting.

gmtdatadir
Michael Uleysky 8 years ago
parent
commit
59dfac220a
  1. 558
      modules/gmt/modgmt_func.h

558
modules/gmt/modgmt_func.h

@ -323,18 +323,15 @@ template<>
class Convert2Struct<struct gmt_projection, ObjectList> class Convert2Struct<struct gmt_projection, ObjectList>
{ {
public: 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<double,false,PMin<0> > BaseM2Nonneg;
struct gmt_projection p; 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; bool suc=true;
p=proj(&suc); p=proj.Convert(input->At(0),&suc,err);
if(!suc) goto fail; // Conversion failed if(!suc) goto fail; // Conversion failed
return p; return p;
} }
@ -343,502 +340,321 @@ class Convert2Struct<struct gmt_projection, ObjectList>
{ {
bool upd; bool upd;
bool changetype=false; 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 ONFPar<Base2Proj,ObjectGMTProjection> proj("projection");
{ ONFPar<Base2Region,ObjectGMTRegion> region("region");
BaseM2String type(input,"t","type","projtype"); ONPar<Base2StringD> type("[projection][( |_)]t[ype]","mercator");
ONPar<Base2NonNegD> 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
upd=proj.Exist();
if(upd) p=proj;
if(!(type.Exist() || upd)) goto case4; // No named parameter, not update mode, go to case 4 if(!(type.Exist() || upd)) goto case4; // No named parameter, not update mode, go to case 4
// Check on redundant parameters
// Check projection type
if(type.Exist()) if(type.Exist())
{ {
std::string typestr=type(&suc); if(!p.SetType(type,err)) goto fail; // Incorrect projection type
if(!suc) goto fail; // Wrong parameter type
if(!p.SetType(typestr)) goto fail; // Incorrect projection type
changetype=true; changetype=true;
} }
}
// We need the region // Region required in new mode
{ if(!(region.Exist() || upd)) {err="Region must be specified"; goto fail;}
BaseMT2Region region(input,"r","region"); if(region.Exist()) p.region=region;
if(!(region.Exist() || upd)) goto fail; // Region must be defined in "new" mode
if(region.Exist()) p.region=region(&suc); ONPar<Base2CoordD> 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);
if(!suc) goto fail; // Conversion failed ONPar<Base2CoordD> clon("(l[ongitude][( |_)][of( |_)]center|c[enter][( |_)]longitude)",(p.region.xb+p.region.xe)*0.5);
} ONPar<Base2CoordD> clat("(l[atitude][( |_)][of( |_)]center|c[enter][( |_)]latitude)",(p.region.yb+p.region.ye)*0.5);
// Get parameters of projection // Get parameters of projection
switch(p.proj) switch(p.proj)
{ {
case(gmt_projection::XY): // x Parameter height (by default equal width) case(gmt_projection::XY): // x Parameter height (by default equal width)
{ {
BaseM2Nonneg height(input,"height","h"); // Width is processing later
if(height.Exist()) if(height.Exist()) p.x.height=height;
{ else if(changetype) p.x.height=width; // By default, height equal width
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
}
}
break; 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"); {ParseNamedParameters apar(input,cmer,stpar); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters
if(cmer.Exist()) if( cmer.Exist() || changetype) p.q.cmer =cmer;
{ if(stpar.Exist() || changetype) p.q.stpar=stpar;
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);
break; break;
} }
case(gmt_projection::MERCATOR): // m Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region) 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"); {ParseNamedParameters apar(input,cmer,stpar); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters
if(cmer.Exist()) if( cmer.Exist() || changetype) p.m.cmer =cmer;
{ if(stpar.Exist() || changetype) p.m.stpar=stpar;
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);
break; 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) 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"); ONPar<Base2NonNegD> scale("scale",1.0);
Base2Double scale(input,"scale"); ONPar<Base2CoordD> orlat("(l[atitude][( |_)][of( |_)]origin|o[rigin][( |_)]latitude)",0.0);
if(cmer.Exist()) {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;
bool suc=true; if(orlat.Exist() || changetype) p.t.orlat=orlat;
p.t.cmer=cmer(&suc); if(scale.Exist() || changetype) p.t.scale=scale;
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;
break; 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). 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"); ONPar<Base2Coord> eqlon("(l[ongitude][( |_)][of( |_)]equator|e[quator][( |_)]longitude)"), eqlat("(l[atitude][( |_)][of( |_)]equator|e[quator][( |_)]latitude)");
Base2Coord azimuth(input,"azimuth"), eqlon(input,"eqlon"), eqlat(input,"eqlat"), polelon(input,"polelon"), polelat(input,"polelat"); ONPar<Base2Coord> polelon("(l[ongitude][( |_)][of( |_)]pole|p[ole][( |_)]longitude)"), polelat("(l[atitude][( |_)][of( |_)]pole|p[ole][( |_)]latitude)");
ONPar<Base2Coord> 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(changetype) p.o.type=gmt_projection::OType::NOTDEF;
if(clon.Exist())
{ if(clon.Exist() || changetype) p.o.clon=clon;
bool suc=true; if(clat.Exist() || changetype) p.o.clat=clat;
p.o.clon=clon(&suc); // Check conflict in parameters
if(!suc) goto fail; // Parsing error if(
} (azimuth.Exist() && (eqlon.Exist() || eqlat.Exist() || polelon.Exist() || polelat.Exist() ) ) ||
else if(changetype) p.o.clon.Convert((p.region.xb+p.region.xe)*0.5); ( (eqlon.Exist() || eqlat.Exist()) && (azimuth.Exist() || polelon.Exist() || polelat.Exist() ) ) ||
if(clat.Exist()) ( (polelon.Exist() || polelat.Exist()) && (azimuth.Exist() || eqlon.Exist() || eqlat.Exist() ) )
)
{ {
bool suc=true; 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";
p.o.clat=clat(&suc); goto fail; // Insufficient data for this projection
if(!suc) goto fail; // Parsing error
} }
else if(changetype) p.o.clat.Convert((p.region.yb+p.region.ye)*0.5);
// Variant 1 // 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.type=gmt_projection::OType::A;
p.o.azimuth=azimuth(&suc); p.o.azimuth=azimuth;
if(!suc) goto fail; // Parsing error
} }
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.type=gmt_projection::OType::B;
p.o.eqlon=eqlon(&suc); p.o.eqlon=eqlon;
p.o.eqlat=eqlat(&suc); p.o.eqlat=eqlat;
if(!suc) goto fail; // Parsing error
} }
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.type=gmt_projection::OType::C;
p.o.polelon=polelon(&suc); p.o.polelon=polelon;
p.o.polelat=polelat(&suc); p.o.polelat=polelat;
if(!suc) goto fail; // Parsing error
}
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. // Special processing of update case
if(!changetype)
{ {
Base2Coord clon(input,"clon"), clat(input,"clat"); if(eqlon.Exist() && !eqlat.Exist())
if(clon.Exist())
{ {
bool suc=true; 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;}
p.c.clon=clon(&suc); else p.o.eqlon=eqlon;
if(!suc) goto fail; // Parsing error
} }
else if(changetype) p.c.clon.Convert((p.region.xb+p.region.xe)*0.5); if(!eqlon.Exist() && eqlat.Exist())
if(clat.Exist())
{ {
bool suc=true; 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;}
p.c.clat=clat(&suc); else p.o.eqlat=eqlat;
if(!suc) goto fail; // Parsing error
}
else if(changetype) p.c.clat.Convert((p.region.yb+p.region.ye)*0.5);
break;
} }
case(gmt_projection::CYL_EQA): // y Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region) if(polelon.Exist() && !polelat.Exist())
{
Base2Coord cmer(input,"cmer"), stpar(input,"stpar");
if(cmer.Exist())
{ {
bool suc=true; if(gmt_projection::OType::C!=p.o.type) {err="Insufficient parameters for oblique Mercator projection, must specify latitude of projection pole"; goto fail;}
p.y.cmer=cmer(&suc); else p.o.polelon=polelon;
if(!suc) goto fail; // Parsing error
} }
else if(changetype) p.y.cmer.Convert((p.region.xb+p.region.xe)*0.5); if(!polelon.Exist() && polelat.Exist())
if(stpar.Exist())
{ {
bool suc=true; if(gmt_projection::OType::C!=p.o.type) {err="Insufficient parameters for oblique Mercator projection, must specify longitude of projection pole"; goto fail;}
p.y.stpar=stpar(&suc); else p.o.polelat=polelat;
if(!suc) goto fail; // Parsing error
} }
else if(changetype) p.y.stpar.Convert((p.region.yb+p.region.ye)*0.5);
break;
} }
case(gmt_projection::MILLER): // j Parameters: central meridian (cmer, default is center of region) if(gmt_projection::OType::NOTDEF==p.o.type)
{ {
Base2Coord cmer(input,"cmer"); 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";
if(cmer.Exist()) goto fail; // Insufficient data for this projection
{
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);
break; 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) 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 cmer(input,"cmer"), stpar(input,"stpar"); {ParseNamedParameters apar(input,clon,clat); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters
if(cmer.Exist()) 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)
{ {
bool suc=true; {ParseNamedParameters apar(input,cmer,stpar); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters
p.cyl_stere.cmer=cmer(&suc); if( cmer.Exist() || changetype) p.y.cmer =cmer;
if(!suc) goto fail; // Parsing error if(stpar.Exist() || changetype) p.y.stpar=stpar;
break;
} }
else if(changetype) p.cyl_stere.cmer.Convert((p.region.xb+p.region.xe)*0.5); case(gmt_projection::MILLER): // j Parameters: central meridian (cmer, default is center of region)
if(stpar.Exist())
{ {
bool suc=true; {ParseNamedParameters apar(input,cmer); if(!apar) {err=apar.Error(); goto fail;}} // Fail to parse additional parameters
p.cyl_stere.stpar=stpar(&suc); if(cmer.Exist() || changetype) p.j.cmer=cmer;
if(!suc) goto fail; // Parsing error break;
} }
else if(changetype) p.cyl_stere.stpar.Convert((p.region.yb+p.region.ye)*0.5); case(gmt_projection::CYL_STERE): // cyl_stere Parameters: central meridian (cmer, default is center of region), standart parallel (stpar, default is center of region)
{
{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; 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"); if(width.Exist()) // width is present
bool suc=true;
if(w.Exist()) // width is present
{ {
p.width=w(&suc); p.width=width;
if(!suc) goto fail; // Parameter width exists, but can't be converted to double if(!ProjectionRealSize(p)) goto failrealsize; // Something go wrong with determining real dimensions
if(!ProjectionRealSize(p)) goto fail; // 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(gmt_projection::XY==p.proj) p.width=height; // For decart projection we use height as width if width is not specified
if(!suc) goto fail; // Parameter height exists, but can't be converted to double if(!ProjectionRealSize(p,height)) goto failrealsize;
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
} }
else // No width, no height, using default or old width 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 return p; // All parameters setted
failrealsize:
err="Can't determine real size of projection "+p.Value();
goto fail;
} }
case4: case4:
// Case 4 // 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); RPosPar<Base2String> type("projection type");
bool suc=true; RPosPar<Base2NonNeg> width("width");
p.region=reg(&suc); RPosPar<Base2Region> region("region");
if(!suc) goto fail; // Conversion failed, no 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 // Projection specific parameters
switch(p.proj) switch(p.proj)
{ {
case(gmt_projection::XY): // x Parameter 4 is height (by default equal width) case(gmt_projection::XY): // x Parameter 4 is height (by default equal width)
{ {
Base2Double height(input,3); OPosPar<Base2NonNegD> height("height",p.width);
if(height.Exist()) {ParsePositionalParameters params(input,3,input->Size(),height); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters
{ p.x.height=height;
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)
break; 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) 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); OPosPar<Base2CoordD> cmer("central meridian",(p.region.xb+p.region.xe)*0.5);
if(cmer.Exist()) OPosPar<Base2CoordD> 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
bool suc=true; p.q.cmer=cmer; p.q.stpar=stpar;
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)
break; 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) 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); OPosPar<Base2CoordD> cmer("central meridian",(p.region.xb+p.region.xe)*0.5);
if(cmer.Exist()) OPosPar<Base2CoordD> 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
bool suc=true; p.m.cmer=cmer; p.m.stpar=stpar;
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)
break; 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) 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); OPosPar<Base2CoordD> cmer("central meridian",(p.region.xb+p.region.xe)*0.5);
Base2Double scale(input,5); OPosPar<Base2CoordD> orlat("latitude of origin",0.0);
if(cmer.Exist()) OPosPar<Base2NonNegD> 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
bool suc=true; p.t.cmer=cmer; p.t.orlat=orlat; p.t.scale=scale;
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)
break; 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). 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 RPosPar<Base2String> pstype("subtype");
OBType<ObjectString> stype(input->At(3)); RPosPar<Base2Coord> clon("longitude of center");
if(!stype) goto fail; // Incorrect parameter type RPosPar<Base2Coord> clat("latitude of center");
std::string subtype=stype->Value();
tolower(subtype); {ParsePositionalParameters params(input,3,6,pstype,clon,clat); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters
Base2Coord clon(input,4), clat(input,5); TemplateComparator a("azimuth"),b("(b|equator)"),c("(c|pole)");
Base2Coord azimuth(input,6), eqlon(input,6), eqlat(input,7), polelon(input,6), polelat(input,7); std::string stype=pstype;
tolower(stype);
p.o.clon=clon; p.o.clat=clat;
p.o.type=gmt_projection::OType::NOTDEF; 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 // Variant 1
if("a"==subtype || "azimuth"==subtype) if(a.Compare(stype))
{ {
RPosPar<Base2Coord> 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; p.o.type=gmt_projection::OType::A;
bool suc=true; p.o.azimuth=azimuth;
p.o.azimuth=azimuth(&suc);
if(!suc) goto fail; // Parsing error
if(size>7) goto fail; // Unknown parameter(s)
} }
if("b"==subtype || "equator"==subtype) if(b.Compare(stype))
{ {
RPosPar<Base2Coord> eqlon("longitude of equator");
RPosPar<Base2Coord> 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; p.o.type=gmt_projection::OType::B;
bool suc=true; p.o.eqlon=eqlon;
p.o.eqlon=eqlon(&suc); p.o.eqlat=eqlat;
p.o.eqlat=eqlat(&suc);
if(!suc) goto fail; // Parsing error
if(size>8) goto fail; // Unknown parameter(s)
} }
if("c"==subtype || "pole"==subtype) if(c.Compare(stype))
{ {
RPosPar<Base2Coord> polelon("longitude of pole");
RPosPar<Base2Coord> 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; p.o.type=gmt_projection::OType::C;
bool suc=true; p.o.polelon=polelon;
p.o.polelon=polelon(&suc); p.o.polelat=polelat;
p.o.polelat=polelat(&suc);
if(!suc) goto fail; // Parsing error
if(size>8) goto fail; // Unknown parameter(s)
} }
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; 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. 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); OPosPar<Base2CoordD> clon("longitude of center",(p.region.xb+p.region.xe)*0.5);
if(clon.Exist()) OPosPar<Base2CoordD> 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
bool suc=true; p.c.clon=clon; p.c.clat=clat;
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)
break; break;
} }
case(gmt_projection::CYL_EQA): // y Parameters: central meridian (4, default is center of region), standart parallel (5, default is center of region) 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); OPosPar<Base2CoordD> cmer("central meridian",(p.region.xb+p.region.xe)*0.5);
if(cmer.Exist()) OPosPar<Base2CoordD> 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
bool suc=true; p.y.cmer=cmer; p.y.stpar=stpar;
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)
break; break;
} }
case(gmt_projection::MILLER): // j Parameters: central meridian (4, default is center of region) case(gmt_projection::MILLER): // j Parameters: central meridian (4, default is center of region)
{ {
Base2Coord cmer(input,3); OPosPar<Base2CoordD> cmer("central meridian",(p.region.xb+p.region.xe)*0.5);
if(cmer.Exist()) {ParsePositionalParameters params(input,3,input->Size(),cmer); if(!params) {err=params.Error(); goto fail;}} // Fail to parse additional parameters
{ p.j.cmer=cmer;
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)
break; 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) 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); OPosPar<Base2CoordD> cmer("central meridian",(p.region.xb+p.region.xe)*0.5);
if(cmer.Exist()) OPosPar<Base2CoordD> 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
bool suc=true; p.cyl_stere.cmer=cmer; p.cyl_stere.stpar=stpar;
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)
break; break;
} }
default: goto fail; // Unknown projection default: goto fail; // Unknown projection
} }
if(ProjectionRealSize(p)) return p; if(ProjectionRealSize(p)) return p;
err="Can't determine real size of projection "+p.Value();
} }
fail: fail:

Loading…
Cancel
Save