pike.git / lib / modules / Geography.pmod / Position.pike

version» Context lines:

pike.git/lib/modules/Geography.pmod/Position.pike:19:   float lat;      //! Longitude (W--E) of the position, in degrees.   //! Positive number is east, negative number is west.   float long;      //! Altitud of the position, in meters. Positive numbers   //! is up. Zero is the shell of the current ellipsoid.   float alt;    - //! @decl void create(float lat, float long, void|float alt) + //! @decl void create(int|float lat, int|float long, void|int|float alt)   //! @decl void create(string lat, string long) - //! @decl void create(string both) + //! @decl void create(string position) + //! @decl void create()   //!   //! Constructor for this class. If fed with strings,   //! it will perform a dwim scan on the strings. If they   //! fails to be understood, there will be an exception.   //! - void create(void|int|float|string _lat, -  void|int|float|string _long, void|float _alt) +  + protected void create()   { -  if(zero_type(_lat)) return; -  if (stringp(_lat)) +  create(0, 0); + } +  + protected variant void create(string pos)   { -  if (zero_type(_long)) -  { -  string tmp; -  if (sscanf(_lat,"%sN %s",tmp,_long)==2) _lat=tmp+"N"; -  else if (sscanf(_lat,"%sS %s",tmp,_long)==2) _lat=tmp+"S"; -  else if (sscanf(_lat,"%sW %s",tmp,_lat)==2) _long=tmp+"W"; -  else if (sscanf(_lat,"%sE %s",tmp,_lat)==2) _long=tmp+"N"; -  else if (sscanf(_lat,"%s %s",tmp,_long)==2) _lat=tmp; +  string tmp, lat, long; +  if (sscanf(pos, "%sN %s", tmp, long)==2) lat=tmp+"N"; +  else if (sscanf(pos, "%sS %s", tmp, long)==2) lat=tmp+"S"; +  else if (sscanf(pos, "%sW %s", tmp, lat)==2) long=tmp+"W"; +  else if (sscanf(pos, "%sE %s", tmp, lat)==2) long=tmp+"N"; +  else if (sscanf(pos, "%s %s", tmp, long)==2) lat=tmp; +  create(lat, long);   } -  _lat=dwim(_lat,"NS"); -  if (stringp(_lat)) -  error("Failed to understand latitude %O\n",lat); -  } -  if (stringp(_long)) +  + protected variant void create(string lat, string long)   { -  _long=dwim(_long,"EW"); -  if (stringp(_long)) -  error("Failed to understand longitude %O\n",long); +  create(dwim(lat,"NS"), dwim(long,"EW"));   } -  lat=(float)_lat; -  long=(float)_long; -  alt=(float)_alt; +  + protected variant void create(int|float lat, int|float long, +  void|int|float alt) + { +  this::lat=(float)lat; +  this::long=(float)long; +  this::alt=(float)alt;    set_ellipsoid("WGS 84");   }    - private float|string dwim(string what,string direction) + private float dwim(string what,string direction)   {    float d,m,s;    string dir=0;    int neg=0; - #define DIV "%*[ \t\r\n'`°\":.]" + #define DIV "%*[ \t\r\n'`\260\":.]"       if (sscanf(what,"-%s",what)) neg=1;       what=upper_case(what);       sscanf(what,"%f"DIV"%f"DIV"%f"DIV"%["+direction+"]",d,m,s,dir)==7 ||    sscanf(what,"%f"DIV"%f"DIV "%["+direction+"]",d,m, dir)==5 ||    sscanf(what,"%f"DIV "%["+direction+"]",d, dir);       if (dir==direction[1..1]) neg=!neg;
pike.git/lib/modules/Geography.pmod/Position.pike:88:      string prettyprint(float what,int n,string directions)   {    if (what<0) what=-what,directions=directions[1..];    else directions=directions[..0];       switch (n)    {    case -1: return sprintf("%.5g",what);    case 1: -  return sprintf("%.3f°%s",what,directions); +  return sprintf("%.3f\260%s",what,directions);    case 3: -  return sprintf("%%d'%.1f\"%s", +  return sprintf("%d\260%d'%.1f\"%s",    (int)floor(what),(int)floor(60*(what-floor(what))),    3600*(what-floor(60*what)/60),    directions);    default: -  return sprintf("%%.3f'%s", +  return sprintf("%d\260%.3f'%s",    (int)floor(what),60*(what-floor(what)),    directions);    }   }      //! @decl string latitude(void|int n)   //! @decl string longitude(void|int n)   //!   //! Returns the nicely formatted latitude or longitude.   //!
pike.git/lib/modules/Geography.pmod/Position.pike:158:    return (equatorial_radius - polar_radius) / equatorial_radius;   }      //! Returns the first eccentricity squared for the   //! selected earth approximation ellipsoid.   float eccentricity_squared() {    float f = flattening();    return 2*f - pow(f,2);   }    + // FIXME: Consider adding models from http://epsg-registry.org/. +    //! A mapping with reference ellipsoids, which can be fed to the   //! UTM converter. The mapping maps the name of the ellipsoid to   //! an array where the first element is a float describing the   //! equatorial radius and the second element is a float describing   //! the polar radius.   //!   constant ellipsoids =    ([ "Airy 1830" : ({ 6377563.396, 6356256.91 }),    "ATS77" : ({ 6378135.0, 6356750.304922 }),    "Australian National" : ({ 6378160.0, 6356774.719 }),
pike.git/lib/modules/Geography.pmod/Position.pike:360:    UTMN += 10000000.0; // 10000000 meter offset for southern hemisphere       return ({ UTME, UTMN });   }      //! Returns the current UTM coordinates position.   //! An example output is   //! "32T 442063.562 5247479.500"   //! where the parts are zone number + zone designator,   //! easting and northing. - string UTM() { -  return sprintf("%d%s %f %f", UTM_zone_number(), UTM_zone_designator(), + string UTM(int precision) { +  return sprintf("%d%s %."+precision+"f %."+precision+"f", +  UTM_zone_number(), UTM_zone_designator(),    @UTM_offset());   }      //! Sets the longitude and lattitude from the given   //! UTM coordinates.   void set_from_UTM(int zone_number, string zone_designator, float UTME, float UTMN) {       float ecc = eccentricity_squared();    float eccPrime = (ecc)/(1-ecc);   
pike.git/lib/modules/Geography.pmod/Position.pike:560:    constant torad=Math.pi/180;    float X = (N + alt)*cos(lat*torad)*cos(long*torad);    float Y = (N + alt)*cos(lat*torad)*sin(long*torad);    float Z = (N*(1-eccentricity_squared())+alt) * sin(lat*torad);       return ({ X, Y, Z });   }      // --- "Technical" methods --------------    - string|array cast(string to) + protected string|array cast(string to)   { -  if (to[..4]=="array") +  switch(to) +  { +  case "array":    return ({lat,long}); -  -  if (to[..5]=="string") +  case "string":    return latitude()+" "+longitude(); -  -  error("can't cast to %O\n",to); +     } -  +  return UNDEFINED; + }      //! - int __hash() + protected int __hash()   {    return (int)(lat*3600000+long*3600000);   }      //! - int `==(object pos) + protected int `==(object pos)   {    return (objectp(pos) && pos->lat==lat && pos->long==long);   }      //! - int `<(object pos) + protected int `<(object pos)   {    if (pos->lat>lat) return 1;    else if (pos->lat==lat && pos->long>long) return 1;    return 0;   }      //! - int `>(object pos) + protected int `>(object pos)   {    if (pos->lat<lat) return 1;    else if (pos->lat==lat && pos->long<long) return 1;    return 0;   }      //! - string _sprintf(int|void t) + protected string _sprintf(int|void t)   {    return t=='O' && sprintf("%O(%s, %s)", this_program,    latitude(), longitude());   }      //! Calculate the euclidian distance between two Geography.Position.   //! Result is in meter. This uses the ECEF function.   float euclidian_distance(this_program p)   {    return sqrt(`+(@map(Array.sum_arrays(    `-,ECEF(),p->ECEF()),    lambda(float f) { return f*f; })));   }      // encoder - array(float) _encode() { return ({lat,long,alt}); } - void _decode(array(float) v) { create(@v); } + array(float) _encode() + { +  return ({ lat, long, alt, polar_radius, equatorial_radius }); + } + void _decode(array(float) v) { +  create(@v[..2]); +  if( sizeof(v)==5 ) +  { +  polar_radius = v[3]; +  equatorial_radius = v[4]; +  } + }