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

version» Context lines:

pike.git/lib/modules/Geography.pmod/Position.pike:23:   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(string lat, string long)   //! @decl void create(string both)   //! - //! Constructor for this class. If feeded with strings, + //! 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(int|float|string _lat,void|int|float|string _long, void|float _alt) + void create(void|int|float|string _lat, +  void|int|float|string _long, void|float _alt)   { -  +  if(zero_type(_lat)) return;    if (stringp(_lat))    {    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;
pike.git/lib/modules/Geography.pmod/Position.pike:86:      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("%.5g°%s",what,directions); +  return sprintf("%.3f°%s",what,directions);    case 3: -  return sprintf("%d°%d'%.3g\"%s", +  return sprintf("%d°%d'%.1f\"%s",    (int)floor(what),(int)floor(60*(what-floor(what))),    3600*(what-floor(60*what)/60),    directions);    default: -  return sprintf("%d°%.5g'%s", +  return sprintf("%d°%.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:276:    if(ellipsoids[er])    [er,pr] = ellipsoids[er];    else    return 0;    }    equatorial_radius = er;    polar_radius = pr;    return 1;   }    +  + // --- UTM code +    // The following code for UTM conversion is base on code by   // Chuck Gantz and equations from USGS Bulletin 1532.      //! Returns the UTM zone number for the current longitude, with   //! correction for the Svalbard deviations.   int UTM_zone_number() {    int zone = (int)((long + 180)/6) + 1;       if( lat >= 56.0 && lat < 64.0 && long >= 3.0 && long < 12.0 )    zone = 32;
pike.git/lib/modules/Geography.pmod/Position.pike:399:       lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrime)*D*D*D*D/24    +(61+90*T1+298*C1+45*T1*T1-252*eccPrime-3*C1*C1)*D*D*D*D*D*D/720);    lat = lat * 180/Math.pi;       long = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrime+24*T1*T1)    *D*D*D*D*D/120)/cos(phi1Rad);    long = LongOrigin + long * 180/Math.pi;   }    +  + // --- GEOREF code +    //! Gives the full GEOREF position for the current position, e.g. "LDJA0511".   string GEOREF() {    int x_square = (int)((180+long)/15);    int y_square = (int)((90+lat)/15);    int x_sub = (int)(180+long - x_square*15);    int y_sub = (int)(90+lat - y_square*15);       string pos = ("ABCDEFGHJKLMNPQRSTUVWXZY"/1)[ x_square ] +    ("ABCDEFGHJKLM"/1)[ y_square ] +    ("ABCDEFGHJKLMNPQ"/1)[ x_sub ] +    ("ABCDEFGHJKLMNPQ"/1)[ y_sub ];       return sprintf("%s%02d%02d", pos,    (int)floor(60*(long-floor(long))),    (int)floor(60*(lat-floor(lat))));   }    -  + // FIXME: set_from_GEOREF +  +  + // --- RT 38 code +  + #define DEG2RAD(DEG) ((Math.pi/180.0)*(DEG)) + #define RAD2DEG(RAD) ((RAD)*(180.0/Math.pi)) +  + protected constant rt38_y0 = 1500000; + protected constant rt38_lng0 = DEG2RAD(15.80827778); + protected constant rt38_k0a = 6366742.5194; + protected constant rt38_beta1 = 0.00083522527; + protected constant rt38_beta2 = 0.000000756302; + protected constant rt38_beta3 = 0.000000001193; + protected constant rt38_delta1 = 0.000835225613; + protected constant rt38_delta2 = 0.000000058706; + protected constant rt38_delta3 = 0.000000000166; +  + //! + array(float) RT38() + { +  float rlat=DEG2RAD(lat); +  float rlong=DEG2RAD(long); +  +  float rlat2 = rlat - sin(rlat) * cos(rlat) +  * DEG2RAD(1376.68809 +  + 7.64689 * pow(sin(rlat),2) +  + 0.053 * pow(sin(rlat),4) +  + 0.0004 * pow(sin(rlat),6)) /3600; +  float ksi = atan2(tan(rlat2) , cos(rlong - rt38_lng0)); +  float eta = atanh(cos(rlat2) * sin(rlong - rt38_lng0)); +  float x = rt38_k0a * (ksi + rt38_beta1 * sin(2 * ksi) +  * cosh(2 * eta) + rt38_beta2 +  * sin(4 * ksi) * cosh(4 * eta) +  + rt38_beta3 * sin(6 * ksi) * cosh(6 * eta)); +  float y = rt38_y0 + rt38_k0a * (eta + rt38_beta1 * cos(2 * ksi) +  * sinh(2 * eta) + rt38_beta2 * cos(4 * ksi) +  * sinh(4 * eta) + rt38_beta3 * cos(6 * ksi) +  * sinh(6 * eta)); +  return ({x, y}); + } +  + //! Sets the longitude and lattitude from the given + //! RT38 coordinates. + void set_from_RT38(int|float|string x_n,int|float|string y_e) + { +  if (stringp(x_n)) x_n=(float)((x_n+"0000000000")[..6]); +  if (stringp(y_e)) y_e=(float)((y_e+"0000000000")[..6]); +  +  float ksi = x_n / rt38_k0a; +  float eta = (y_e - rt38_y0) / rt38_k0a; +  float ksi2 = ksi - rt38_delta1 * sin(2 * ksi) * cosh(2 * eta) +  - rt38_delta2 * sin(4 * ksi) * cosh(4 * eta) +  - rt38_delta3 * sin(6 * ksi) * cosh(6 * eta); +  float eta2 = eta - rt38_delta1 * cos(2 * ksi) * sinh(2 * eta) +  - rt38_delta2 * cos(4 * ksi) * sinh(4 * eta) +  - rt38_delta3 * cos(6 * ksi) * sinh(6 * eta); +  float rlat2 = asin(sin(ksi2) / cosh(eta2)); +  float rlong = atan2(sinh(eta2) , cos(ksi2)) + rt38_lng0; +  float rlat = rlat2 + sin(rlat2) * cos(rlat2) +  * DEG2RAD(1385.93836 - 10.89576 * pow(sin(rlat2),2) +  + 0.11751 * pow(sin(rlat2),4) +  - 0.00139 * pow(sin(rlat2),6)) / 3600; +  +  lat = RAD2DEG(rlat); +  long = RAD2DEG(rlong); + } +  +  + // --- Height releated code +    // Ten by Ten Degree WGS-84 Geoid Heights from -180 to +170 Degrees of Longitude.   // Defense Mapping Agency. 12 Jan 1987. GPS UE Relevant WGS-84 Data Base Package.   constant height_values = ({    ({ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 }), // 90 deg N    ({ 3,1,-2,-3,-3,-3,-1,3,1,5,9,11,19,27,31,34,33,34,33,34,28,23,17,13,9,4,4,1,-2,-2,0,2,3,2,1,1 }),    ({ 2,2,1,-1,-3,-7,-14,-24,-27,-25,-19,3,24,37,47,60,61,58,51,43,29,20,12,5,-2,-10,-14,-12,-10,-14,-12,-6,-2,3,6,4 }),    ({ 2,9,17,10,13,1,-14,-30,-39,-46,-42,-21,6,29,49,65,60,57,47,41,21,18,14,7,-3,-22,-29,-32,-32,-26,-15,-2,13,17,19,6 }),    ({ -8,8,8,1,-11,-19,-16,-18,-22,-35,-40,-26,-12,24,45,63,62,59,47,48,42,28,12,-10,-19,-33,-43,-42,-43,-29,-2,17,23,22,6,2 }),    ({ -12,-10,-13,-20,-31,-34,-21,-16,-26,-34,-33,-35,-26,2,33,59,52,51,52,48,35,40,33,-9,-28,-39,-48,-59,-50,-28,3,23,37,18,-1,-11 }),    ({ -7,-5,-8,-15,-28,-40,-42,-29,-22,-26,-32,-51,-40,-17,17,31,34,44,36,28,29,17,12,-20,-15,-40,-33,-34,-34,-28,7,29,43,20,4,-6 }),
pike.git/lib/modules/Geography.pmod/Position.pike:471:      //! Returns the current position as Earth Centered Earth Fixed   //! Cartesian Coordinates.   //! @returns   //! ({ X, Y, Z })   array(float) ECEF() {       float N = equatorial_radius /    sqrt(1-eccentricity_squared()*sin(lat)*sin(lat));    -  float X = (N + alt)*cos(lat)*cos(long); -  float Y = (N + alt)*cos(lat)*sin(long); -  float Z = (N*(1-eccentricity_squared())+alt) * sin(lat); +  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)   {    if (to[..4]=="array")    return ({lat,long});
pike.git/lib/modules/Geography.pmod/Position.pike:500:      //!   int __hash()   {    return (int)(lat*3600000+long*3600000);   }      //!   int `==(object pos)   { -  return (pos->lat==lat && pos->long==long); +  return (objectp(pos) && pos->lat==lat && pos->long==long);   }      //!   int `<(object pos)   {    if (pos->lat>lat) return 1;    else if (pos->lat==lat && pos->long>long) return 1;    return 0;   }   
pike.git/lib/modules/Geography.pmod/Position.pike:522:   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)   { -  switch(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)   { -  case 't': return "Geography.Position"; -  case 'O': return "Position("+latitude()+", "+longitude()+")"; +  return sqrt(`+(@map(Array.sum_arrays( +  `-,ECEF(),p->ECEF()), +  lambda(float f) { return f*f; })));   } -  return 0; - } +  + // encoder + array(float) _encode() { return ({lat,long,alt}); } + void _decode(array(float) v) { create(@v); }