Index: trunk/BNC/src/bncantex.cpp
===================================================================
--- trunk/BNC/src/bncantex.cpp	(revision 11047)
+++ trunk/BNC/src/bncantex.cpp	(revision 11066)
@@ -68,4 +68,12 @@
   }
   _maps.clear();
+  QMapIterator<QString, QVector<t_antMap*> > itSat(_satMaps);
+  while (itSat.hasNext()) {
+    itSat.next();
+    for (int ii = 0; ii < itSat.value().size(); ii++) {
+      delete itSat.value()[ii];
+    }
+  }
+  _satMaps.clear();
 }
 
@@ -141,4 +149,5 @@
 t_irc bncAntex::readFile(const QString& fileName) {
 
+  _fileName = fileName;
   QFile inFile(fileName);
   inFile.open(QIODevice::ReadOnly | QIODevice::Text);
@@ -176,8 +185,13 @@
           _satBlocks[newAntMap->antName].append(satBlock);
         }
-        if (_maps.contains(newAntMap->antName)) {
-          delete _maps[newAntMap->antName];
-        }
-        _maps[newAntMap->antName] = newAntMap;
+        if (newAntMap->isSat) {
+          _satMaps[newAntMap->antName].append(newAntMap);
+        }
+        else {
+          if (_maps.contains(newAntMap->antName)) {
+            delete _maps[newAntMap->antName];
+          }
+          _maps[newAntMap->antName] = newAntMap;
+        }
         newAntMap = 0;
       }
@@ -199,4 +213,5 @@
             line.indexOf("NavIC") == 0 ){
           newAntMap->antName = line.mid(20,3);
+          newAntMap->isSat   = true;
           if (line.indexOf("BLOCK I") == 0) {
             // Extract GPS block type: "BLOCK IIF   " → "IIF"
@@ -789,10 +804,11 @@
   }
 
-  QMap<QString, t_antMap*>::const_iterator it = _maps.find(prn.mid(0,3));
-  if (it != _maps.end()) {
-    t_antMap* map = it.value();
+  bncTime epoch;
+  epoch.setmjd(Mjd);
+  const t_antMap* map = satMap(prn, epoch);
+  if (map) {
     if (map->frqMap.find(frqType) != map->frqMap.end()) {
 
-      double* neu = map->frqMap[frqType]->neu;
+      const double* neu = map->frqMap[frqType]->neu;
 
       // Unit Vectors sz, sy, sx
@@ -879,12 +895,12 @@
 ////////////////////////////////////////////////////////////////////////////
 double bncAntex::satCorr(const QString& prn, t_frequency::type frqType,
-                         double elTx, double azTx, bool& found) const {
-
-  if (_maps.find(prn.mid(0,3)) == _maps.end()) {
+                         double elTx, double azTx, bool& found,
+                         const bncTime& epoch) const {
+
+  const t_antMap* map = satMap(prn, epoch);
+  if (!map) {
     found = false;
     return 0.0;
   };
-
-  t_antMap* map = _maps[prn.mid(0,3)];
 
   if (map->frqMap.find(frqType) == map->frqMap.end()) {
@@ -964,4 +980,66 @@
 }
 
+// Satellite antenna entry valid at the given epoch (the last entry of the
+// PRN if the epoch is not valid), 0 if there is none
+////////////////////////////////////////////////////////////////////////////
+const bncAntex::t_antMap* bncAntex::satMap(const QString& prn, const bncTime& epoch) const {
+  QMap<QString, QVector<t_antMap*> >::const_iterator it = _satMaps.find(prn.mid(0,3));
+  if (it == _satMaps.end() || it.value().isEmpty()) {
+    return 0;
+  }
+  const QVector<t_antMap*>& maps = it.value();
+  if (!epoch.valid()) {
+    return maps.last();
+  }
+  for (int ii = maps.size() - 1; ii >= 0; ii--) {
+    const t_antMap* map = maps[ii];
+    if ((!map->validFrom.valid() || !(epoch < map->validFrom)) &&
+        (!map->validTo.valid()   || epoch < map->validTo)) {
+      return map;
+    }
+  }
+  return 0;
+}
+
+// File name, number of satellite entries and the latest satellite entry,
+// which identifies the version of the file
+////////////////////////////////////////////////////////////////////////////
+QString bncAntex::info() const {
+  int     numSat = 0;
+  bncTime latest;
+  QString latestPrn;
+  QMapIterator<QString, QVector<t_antMap*> > it(_satMaps);
+  while (it.hasNext()) {
+    it.next();
+    for (int ii = 0; ii < it.value().size(); ii++) {
+      const t_antMap* map = it.value()[ii];
+      ++numSat;
+      if (map->validFrom.valid() && (!latest.valid() || latest < map->validFrom)) {
+        latest    = map->validFrom;
+        latestPrn = it.key();
+      }
+    }
+  }
+  QString str = QString("ANTEX file %1: %2 receiver and %3 satellite antenna entries")
+                .arg(_fileName).arg(_maps.size()).arg(numSat);
+  if (latest.valid()) {
+    str += QString(", latest satellite entry %1 valid from %2").arg(latestPrn)
+           .arg(QString::fromStdString(latest.datestr()));
+  }
+  return str;
+}
+
+// True if a missing satellite antenna entry has to be reported (at most once
+// per hour and PRN)
+////////////////////////////////////////////////////////////////////////////
+bool bncAntex::warnNoSatEntry(const QString& prn, const bncTime& epoch) const {
+  bncTime& warned = _noSatEntryWarned[prn.mid(0,3)];
+  if (!warned.valid() || !epoch.valid() || epoch - warned >= 3600.0) {
+    warned = epoch;
+    return true;
+  }
+  return false;
+}
+
 // Satellite block type valid at the given epoch
 ////////////////////////////////////////////////////////////////////////////
