Index: trunk/BNC/Example_Configs/Input/BNC_IGS20.CRD
===================================================================
--- trunk/BNC/Example_Configs/Input/BNC_IGS20.CRD	(revision 11026)
+++ trunk/BNC/Example_Configs/Input/BNC_IGS20.CRD	(revision 11027)
@@ -10,4 +10,10 @@
 # - antenna, and 
 # - receiver
+# 
+# insteed of XYZ optional supported is  
+# - geodetic Latitude/Longitude/Height through the keywords LAT: LON: H: 
+#   in D,M,S, which are comma-separated Degrees, Minutes and decimal Seconds, 
+#   the sign of Degrees carries the hemisphere, negative meaning South or West), and
+#   height is the ellipsoidal height in meters, e.g.: LAT:49,8,39.12 LON:12,52,44.09 H:666.02
 ################################################################################################
 # Reference System: IGS20 (IGS0OPSSNX_1994002_2026185_00U_CRD.SNX)
@@ -20,4 +26,6 @@
 PARK00AUS0 -4554255.23564276  2816652.46115249 -3454059.72019472 EPOCH:2020.0 VEL:-0.0360614781690518,-0.00224882614802764,0.0466110997530548  0.0000  0.0000  0.0250 LEIAR25         NONE SEPT POLARX5TR
 BRUX00BEL0  4027881.37719374  306998.748539549  4919499.01582683 EPOCH:2020.0 VEL:-0.0136005676831508,0.0167589259554315,0.0103501502632278  0.0010  0.0000  0.4689 JAVRINGANT_DM   SCIS SEPT POLARX5TR
+"0688" LAT:52,24,27.03277 LON:9,48,5.44970 H:123.7785 EPOCH:2026.5   0.0000   0.0000   0.053
+
 # RINEX
 FFMJ01DEU  4053455.66002983  617729.911377446  4869395.86849437 EPOCH:2020.0 VEL:-0.0148149200700258,0.0173394525889122,0.00993903277554994   0.0000  0.0000  0.0450 LEIAR25.R3      LEIT JAVAD TRE_3S DELTA
@@ -32,5 +40,5 @@
 
 ################################################################################################
-# Howto extract the correct values from a cumulative SINEX file to fill BNCs  coordinates file #
+# Howto extract the correct values from a cumulative SINEX file to fill BNCs coordinates file  
 ################################################################################################
 # Two different "epochs" are in play in a cumulative SINEX file
Index: trunk/BNC/src/bnchelp.html
===================================================================
--- trunk/BNC/src/bnchelp.html	(revision 11026)
+++ trunk/BNC/src/bnchelp.html	(revision 11027)
@@ -6088,4 +6088,19 @@
       station's ITRF velocity is unknown;
       in that case the a priori coordinate is used unchanged, as before.
+    </li>
+    <br>
+    <li>Instead of a Cartesian XYZ coordinate, the a priori coordinate may alternatively be specified as a geodetic
+      Latitude/Longitude/Height through the keyword tokens
+      <span style="font-family:Monospace">LAT:&lt;D,M,S&gt;</span>,
+      <span style="font-family:Monospace">LON:&lt;D,M,S&gt;</span> and
+      <span style="font-family:Monospace">H:&lt;height&gt;</span> (in any order, in place of the 'X Y Z' fields).
+      <span style="font-family:Monospace">D,M,S</span> are comma-separated Degrees, Minutes and decimal Seconds (the
+      sign of Degrees carries the hemisphere, negative meaning South or West), and
+      <span style="font-family:Monospace">&lt;height&gt;</span> is the ellipsoidal height in meters, e.g.:
+      <pre><p style="font-family:Monospace">LAT:49,8,39.12 LON:12,52,44.09 H:666.02</p></pre>
+      BNC converts this internally to a Cartesian XYZ coordinate. 'EPOCH:' and 'VEL:' may be combined with
+      'LAT:'/'LON:'/'H:' the same way as with a Cartesian coordinate — in particular, 'EPOCH:' may be given on its
+      own, without 'VEL:', if only the coordinate's reference epoch is known but its velocity is not; in that case no
+      propagation is performed and the a priori coordinate is used as given.
     </li>
     <br>
Index: trunk/BNC/src/bncutils.cpp
===================================================================
--- trunk/BNC/src/bncutils.cpp	(revision 11026)
+++ trunk/BNC/src/bncutils.cpp	(revision 11027)
@@ -392,4 +392,24 @@
 }
 
+// Ellipsoidal Coordinates -> Rectangular Coordinates
+////////////////////////////////////////////////////////////////////////////
+void ell2xyz(const double* Ell, double* XYZ) {
+
+  const double bell = t_CST::aell*(1.0-1.0/t_CST::fInv) ;
+  const double e2   = (t_CST::aell*t_CST::aell-bell*bell)/(t_CST::aell*t_CST::aell) ;
+
+  double sinPhi = sin(Ell[0]);
+  double cosPhi = cos(Ell[0]);
+  double sinLam = sin(Ell[1]);
+  double cosLam = cos(Ell[1]);
+  double hh     = Ell[2];
+
+  double nn = t_CST::aell/sqrt(1.0-e2*sinPhi*sinPhi) ;
+
+  XYZ[0] = (nn+hh) * cosPhi * cosLam;
+  XYZ[1] = (nn+hh) * cosPhi * sinLam;
+  XYZ[2] = (nn*(1.0-e2)+hh) * sinPhi;
+}
+
 // Rectangular Coordinates -> Ellipsoidal Coordinates
 ////////////////////////////////////////////////////////////////////////////
Index: trunk/BNC/src/bncutils.h
===================================================================
--- trunk/BNC/src/bncutils.h	(revision 11026)
+++ trunk/BNC/src/bncutils.h	(revision 11027)
@@ -92,4 +92,5 @@
 t_irc        xyz2geoc(const double* XYZ, double* Geoc);
 
+void         ell2xyz(const double* Ell, double* XYZ);
 void         xyz2neu(const double* Ell, const double* xyz, double* neu);
 
Index: trunk/BNC/src/pppCrdFile.cpp
===================================================================
--- trunk/BNC/src/pppCrdFile.cpp	(revision 11026)
+++ trunk/BNC/src/pppCrdFile.cpp	(revision 11027)
@@ -40,4 +40,5 @@
  * -----------------------------------------------------------------------*/
 
+#include <cmath>
 #include <cstdlib>
 #include <fstream>
@@ -48,4 +49,19 @@
 using namespace std;
 using namespace BNC_PPP;
+
+// Convert a 'D,M,S' (degrees, minutes, seconds) token into decimal degrees;
+// the sign of D carries the hemisphere (negative == South/West).
+//////////////////////////////////////////////////////////////////////////////
+static double dmsToDeg(const string& dms) {
+  string str = dms;
+  for (string::iterator it = str.begin(); it != str.end(); ++it) {
+    if (*it == ',') *it = ' ';
+  }
+  istringstream in(str);
+  double d = 0.0, m = 0.0, s = 0.0;
+  in >> d >> m >> s;
+  double sign = (d < 0.0) ? -1.0 : 1.0;
+  return sign * (fabs(d) + m / 60.0 + s / 3600.0);
+}
 
 //
@@ -81,9 +97,25 @@
     }
 
-    in >> staInfo._xyz(1) >> staInfo._xyz(2) >> staInfo._xyz(3);
+    // The a priori coordinate is given either as plain Cartesian 'X Y Z', or,
+    // if the line's first coordinate token is 'LAT:<D,M,S>', as geodetic
+    // 'LAT:<D,M,S> LON:<D,M,S> H:<height>' (converted to XYZ below).
+    streampos posBeforeCoord = in.tellg();
+    string firstCoordTok;
+    bool geodetic = false;
+    if (in >> firstCoordTok) {
+      geodetic = (firstCoordTok.compare(0, 4, "LAT:") == 0);
+      in.seekg(posBeforeCoord);
+    }
+    if (!geodetic) {
+      in >> staInfo._xyz(1) >> staInfo._xyz(2) >> staInfo._xyz(3);
+    }
 
-    // Optional 'EPOCH:<decimalYear>' and 'VEL:<vx>,<vy>,<vz>' keyword tokens
-    // (ITRF reference epoch and velocity in m/year of the coordinate above),
-    // may appear in any order before the antenna eccentricity / name fields.
+    // Optional keyword tokens, may appear in any order before the antenna
+    // eccentricity / name fields:
+    //  - 'LAT:<D,M,S>', 'LON:<D,M,S>', 'H:<height>'  (geodetic a priori coordinate)
+    //  - 'EPOCH:<decimalYear>'                       (ITRF reference epoch of the coordinate)
+    //  - 'VEL:<vx>,<vy>,<vz>'                         (ITRF velocity [m/year] of the coordinate)
+    double lat = 0.0, lon = 0.0, hgt = 0.0;
+    bool haveLat = false, haveLon = false, haveHgt = false;
     while (!in.eof()) {
       streampos posBeforeToken = in.tellg();
@@ -92,5 +124,17 @@
         break;
       }
-      if (token.compare(0, 6, "EPOCH:") == 0) {
+      if (token.compare(0, 4, "LAT:") == 0) {
+        lat = dmsToDeg(token.substr(4));
+        haveLat = true;
+      }
+      else if (token.compare(0, 4, "LON:") == 0) {
+        lon = dmsToDeg(token.substr(4));
+        haveLon = true;
+      }
+      else if (token.compare(0, 2, "H:") == 0) {
+        hgt = atof(token.substr(2).c_str());
+        haveHgt = true;
+      }
+      else if (token.compare(0, 6, "EPOCH:") == 0) {
         staInfo._epoch = atof(token.substr(6).c_str());
       }
@@ -107,4 +151,13 @@
         break;
       }
+    }
+
+    if (geodetic && haveLat && haveLon && haveHgt) {
+      double Ell[3] = { lat * M_PI / 180.0, lon * M_PI / 180.0, hgt };
+      double XYZ[3];
+      ell2xyz(Ell, XYZ);
+      staInfo._xyz(1) = XYZ[0];
+      staInfo._xyz(2) = XYZ[1];
+      staInfo._xyz(3) = XYZ[2];
     }
 
