[Kstars-devel] KDE/kdeedu/kstars/kstars

James Bowlin bowlin at mindspring.com
Sun Aug 19 09:20:16 CEST 2007


SVN commit 701764 by jbowlin:

Am now giving reasonable (but not always perfect) progress percentages
when reading and re-reading stars.dat.  The percentages should now end
near 100% even if we are not reading in the entire stars.dat file.

The new data file starlnum.idx has the line numbers of roughly 90
different star magnitudes which enables the more reasonable
percentages.  If the stars.dat file changes then starlnum.idx should
be regenerated via:

   $ ./mag-linenum.pl stars.dat > starlnum.idx

Have stopped the one draw cycle delay before re-reading star data
because the skymap is getting erased anyway.

Tracked down a several second delay after reading the star data to a
faulty implementation of QTextStream::pos().  This function can take
7 or 8 seconds to complete!  I have a feeling they go back and re-read
the entire file.  I implemented a trivial work-around by simply
keeping track of the file position myself inside our read loop:

    m_lastFilePos += line.length() + 1;

Also did some minor code clean up in StarComponent and KSFileReader.

CCMAIL:kstars-devel at kde.org


 M  +1 -0      data/CMakeLists.txt  
 AM            data/mag-linenum.pl  
 A             data/starlnum.idx  
 M  +7 -10     ksfilereader.cpp  
 M  +3 -6      ksfilereader.h  
 M  +1 -1      skycomponents/constellationboundarylines.cpp  
 M  +1 -1      skycomponents/deepskycomponent.cpp  
 M  +85 -62    skycomponents/starcomponent.cpp  
 M  +10 -5     skycomponents/starcomponent.h  


--- trunk/KDE/kdeedu/kstars/kstars/data/CMakeLists.txt #701763:701764
@@ -3,6 +3,7 @@
 install( FILES kstars.png geomap.png 
     Cities.dat
     stars.dat
+	starlnum.idx
     ngcic.dat
     clines.dat
     cnames.dat
** trunk/KDE/kdeedu/kstars/kstars/data/mag-linenum.pl #property svn:executable
   + *
--- trunk/KDE/kdeedu/kstars/kstars/ksfilereader.cpp #701763:701764
@@ -39,7 +39,6 @@
 {
     QIODevice* device = (QIODevice*) & file;
     QTextStream::setDevice( device );
-	m_curLine = 0;
     m_targetLine = MAXUINT;
 }
 
@@ -55,19 +54,16 @@
 
 void KSFileReader::setProgress( QString label, 
                                 unsigned int totalLines, 
-                                unsigned int numUpdates,
-                                unsigned int firstNumUpdates)
+                                unsigned int numUpdates )
 {
-    if ( firstNumUpdates == 0 ) firstNumUpdates = numUpdates;
-
     m_label = label;
-    m_totalLines = totalLines;
-    m_targetLine = m_totalLines / firstNumUpdates;
+    m_totalLines = totalLines; 
+	if ( m_totalLines < 1 ) m_totalLines = 1;
+    m_targetLine = m_totalLines / 100;
     m_targetIncrement = m_totalLines / numUpdates;
 
     connect( this, SIGNAL( progressText( const QString & ) ), 
 	    KStarsData::Instance(), SIGNAL( progressText( const QString & ) ) );
-
 }
 
 void KSFileReader::showProgress()
@@ -78,8 +74,9 @@
     else
         m_targetLine += m_targetIncrement;
 
-    int percent = 1 + (m_curLine * 100) / m_totalLines;
-
+    int percent = int(.5 + (m_curLine * 100.0) / m_totalLines);
+	//printf("%8d %8d %3d\n", m_curLine, m_totalLines, percent );
+	if ( percent > 100 ) percent = 100;
     emit progressText( QString("%1 (%2%)").arg( m_label ).arg( percent ) );
     qApp->processEvents();
 }
--- trunk/KDE/kdeedu/kstars/kstars/ksfilereader.h #701763:701764
@@ -109,15 +109,12 @@
 
         /* @short Prepares this instance to emit progress reports on how much
          * of the file has been read (in percent).
-         * @param totalLines the total number of lines in the file
+         * @param totalLines the number of lines to be read
          * @param numUpdates the number of progress reports to send
-         * @param firstNumUpdates set to 100 to get the first report at 1%
-         *        or set to 20 to get the first report at 5% etc.
          */
         void setProgress( QString label,
-                          unsigned int totalLines,
-                          unsigned int numUpdates=10,
-                          unsigned int firstNumUpdates=0);
+                          unsigned int lastLine,
+                          unsigned int numUpdates=10 );
 
         /* @short emits progress reports when required and updates bookkeeping
          * for when to send the next report.  This might seem slow at first
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/constellationboundarylines.cpp #701763:701764
@@ -87,7 +87,7 @@
 	KSFileReader fileReader;
     if ( ! fileReader.open( fname ) ) return;
 
-    fileReader.setProgress( i18n("Loading Consellation Boundaries"), 13124, 10, 100 );
+    fileReader.setProgress( i18n("Loading Consellation Boundaries"), 13124, 10 );
 
     lastRa = lastDec = -1000.0;
 
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/deepskycomponent.cpp #701763:701764
@@ -62,7 +62,7 @@
     KSFileReader fileReader;
     if ( ! fileReader.open( "ngcic.dat" ) ) return; 
 
-    fileReader.setProgress( i18n("Loading NGC/IC objects"), 13444, 5, 100);
+    fileReader.setProgress( i18n("Loading NGC/IC objects"), 13444, 10 );
 
     while ( fileReader.hasMoreLines() ) {
         QString line, con, ss, name, name2, longname;
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/starcomponent.cpp #701763:701764
@@ -49,9 +49,11 @@
     m_highPMStars.append( new HighPMStarList( 304.0 ) );
     m_reindexInterval = StarObject::reindexInterval( 304.0 );
 
-    lastFilePos = 0;
+    m_lastFilePos  = 0;
+    m_lastLineNum  = 0;
 	m_zoomMagLimit = 0.0;
 	m_reloadSplash = m_reindexSplash = 0;
+	m_validLineNums = false;
 }
 
 StarComponent::~StarComponent()
@@ -69,6 +71,7 @@
 	m_ColorIntensity = data->colorScheme()->starColorIntensity();
 	m_Data = data;
 
+	readLineNumbers();
 	readData( Options::magLimitDrawStar() );
 }
 
@@ -97,8 +100,7 @@
 
 void StarComponent::reindexAll( KSNumbers *num )
 {
-	/***
-	if ( ! m_reindexSplash ) {
+	if (  0 && ! m_reindexSplash ) {
 		m_reindexSplash = new KStarsSplash(0, 
 				i18n("Please wait while re-indexing stars ...") );
 		QObject::connect( KStarsData::Instance(), 
@@ -109,7 +111,6 @@
 		m_reindexSplash->raise();
 		return;
 	}
-	***/
 
     printf("Re-indexing Stars to year %4.1f...\n",
 			2000.0 + num->julianCenturies() * 100.0);
@@ -146,27 +147,25 @@
 	float magLimit =  Options::magLimitDrawStar();
 	SkyMap* map = SkyMap::Instance();
 	if ( ( map->isSlewing() && Options::hideOnSlew() && Options::hideStars()) ||
-		 m_FaintMagnitude >= magLimit ) 
+			m_FaintMagnitude >= magLimit ) 
 		return;
 
-	// First show a splash screen but don't load any data so we can present
-	// a pretty face.  Then load data the next time through and finally erase
-	// the splash screen.
+	// bail out if there are no more lines to read
+	if ( m_lastLineNum >= m_lineNumber[ MAX_LINENUMBER_MAG ] )
+		return;
 
-	if ( ! m_reloadSplash ) {
-		m_reloadSplash = new KStarsSplash(0, 
-				i18n("Please wait while loading faint stars ...") );
-		QObject::connect( KStarsData::Instance(), 
-				SIGNAL( progressText( QString ) ),
-				m_reloadSplash, SLOT( setMessage( QString ) ) );
+	m_reloadSplash = new KStarsSplash( 0, 
+			i18n("Please wait while loading faint stars ...") );
 
-		m_reloadSplash->show();
-		m_reloadSplash->raise();
-		return;
-	}
-	printf("reading data ...\n");
+	QObject::connect( KStarsData::Instance(), 
+			SIGNAL( progressText( QString ) ),
+			m_reloadSplash, SLOT( setMessage( QString ) ) );
+
+	m_reloadSplash->show();
+	m_reloadSplash->raise();
+	//printf("reading data ...\n");
    	readData( magLimit );
-	printf("Done!\n");
+	//printf("done\n");
 	delete m_reloadSplash;
 	m_reloadSplash = 0;
 }
@@ -181,12 +180,12 @@
 
 	bool checkSlewing = ( map->isSlewing() && Options::hideOnSlew() );
     bool hideLabels =  ( map->isSlewing() && Options::hideLabels() ) ||
-		                ! ( Options::showStarMagnitudes() || Options::showStarNames() );
+			! ( Options::showStarMagnitudes() || Options::showStarNames() );
 
     //shortcuts to inform whether to draw different objects
 	bool hideFaintStars( checkSlewing && Options::hideStars() );
 	float maglim = Options::magLimitDrawStar();
-
+	double hideStarsMag = Options::magLimitHideStar();
 	rereadData();
 
     reindex( ks->data()->updateNum() );
@@ -206,10 +205,8 @@
 	float sizeFactor = 6.0 + (lgz - lgmin);
  
 	double labelMagLim = Options::magLimitDrawStarInfo();
-	//labelMagLim += ( 7.9 - labelMagLim ) * ( lgz - lgmin) / (lgmax - lgmin );
 	labelMagLim += ( 16.0 - labelMagLim ) * ( lgz - lgmin) / (lgmax - lgmin );
 	if ( labelMagLim > 8.0 ) labelMagLim = 8.0;
-	//printf("labelMagLim = %.1f\n", labelMagLim );
 
 	//Set the brush
 	QColor fillColor( Qt::white );
@@ -223,7 +220,7 @@
 		//Strictly speaking, we don't need to do this every time, but once per 
 		//draw loop isn't too expensive.
 		StarObject::updateColors( (! Options::useAntialias() || 
-			map->isSlewing()), ks->data()->colorScheme()->starColorIntensity() );
+				map->isSlewing()), ks->data()->colorScheme()->starColorIntensity() );
 
     double zoom = Options::zoomFactor();
 
@@ -243,8 +240,8 @@
             float mag = curStar->mag();
 
 		    // break loop if maglim is reached
-		    if ( mag > maglim || 
-                 ( hideFaintStars && curStar->mag() > Options::magLimitHideStar() ) ) break;
+		    if ( mag > maglim || ( hideFaintStars && curStar->mag() > hideStarsMag ) )
+				break;
 
 		    if ( ! map->checkVisibility( curStar ) ) continue;
 		    
@@ -257,9 +254,7 @@
 			curStar->draw( psky, o.x(), o.y(), size, (starColorMode()==0), 
 					       starColorIntensity(), true, scale );
 
-            if ( hideLabels ) continue;
-            if ( mag > labelMagLim ) continue;
-            //if ( checkSlewing || ! (Options::showStarMagnitudes() || Options::showStarNames()) ) continue;
+            if ( hideLabels || mag > labelMagLim ) continue;
 
             float offset = scale * (6. + 0.5*( 5.0 - mag ) + 0.01*( zoom/500. ) );
 			QString sName = curStar->nameLabel( drawName, drawMag );
@@ -269,41 +264,78 @@
 }
 
  
-void StarComponent::readData( float newMagnitude ) {
+void StarComponent::readLineNumbers()
+{
+	KSFileReader fileReader;
+    if ( ! fileReader.open( "starlnum.idx" ) ) return;
+
+	while ( fileReader.hasMoreLines() ) {
+		QString line = fileReader.readLine();
+		if ( line.at(0) == '#' ) continue;  // ignore comments
+		int mag = line.mid( 0, 2 ).toInt();
+		int lineNumber = line.mid( 3 ).toInt();
+		if ( mag < 0 || mag > MAX_LINENUMBER_MAG ) {
+			fprintf(stderr, "Waring: mag %d, out of range\n", mag );
+			continue;
+		}
+		m_lineNumber[ mag ] = lineNumber;
+	}
+	m_validLineNums = true;
+}
+
+int StarComponent::lineNumber( float magF )
+{
+	if ( ! m_validLineNums ) return -1;
+
+	int mag = int( magF * 10.0 );
+	if ( mag < 0 ) mag = 0;
+	if ( mag > MAX_LINENUMBER_MAG ) mag = MAX_LINENUMBER_MAG;
+	return m_lineNumber[ mag ];
+}
+
+void StarComponent::readData( float newMagnitude )
+{
 	// only load star data if the new magnitude is fainter than we've seen so far
 	if ( newMagnitude <= m_FaintMagnitude ) return;
+    float currentMag = m_FaintMagnitude;
     m_FaintMagnitude = newMagnitude;  // store new highest magnitude level
-   
-    //int filePos = lastFilePos;
-
+  
+	// prepare to index stars to this date
     m_skyMesh->setKSNumbers( &m_reindexNum );
-    //printf("Indexing stars for year %.1f\n",  
-    //        2000.0 + m_reindexNum.julianCenturies() * 100.0 );
 
-    float currentMag = -5.0;
-
 	KSFileReader fileReader;
     if ( ! fileReader.open( "stars.dat" ) ) return;
 
-    //if ( lastFilePos == 0 ) {
-        fileReader.setProgress( i18n("Loading stars"), 125994, 100 );
-    //}
+	int totalLines = lineNumber( newMagnitude );
+	totalLines -= lineNumber( currentMag );
+	int updates;
+	if ( totalLines > 50000 ) 
+		updates = 100;
+	else if ( totalLines > 20000 ) 
+		updates =  50;
+	else if ( totalLines > 10000 )
+		updates =  10;
+	else
+		updates =   5;
 
-    if (lastFilePos > 0 ) fileReader.seek( lastFilePos );
+	// only show progress with valid line numbers
+	if ( m_validLineNums ) 
+		fileReader.setProgress( i18n("Loading stars"), totalLines, updates );
 
-    //bool first(true);
+    if (m_lastFilePos > 0 ) fileReader.seek( m_lastFilePos );
+
 	while ( fileReader.hasMoreLines() ) {
 		QString line = fileReader.readLine();
 
-        //if ( first) { kDebug() << line << endl; first = false; }
+		// DIY because QTextStream::pos() can take many seconds!
+		m_lastFilePos += line.length() + 1;
 
         if ( line.isEmpty() ) continue;       // ignore blank lines
-		if ( line.left(1) == "#" ) continue;  // ignore comments
-			// check star magnitude
-        currentMag = line.mid( 46,5 ).toFloat();
+		if ( line.at(0) == '#' ) continue;    // ignore comments
+
+        StarObject* star = processStar( line );
+		currentMag = star->mag();	
         
-        StarObject* star = processStar( line );
-
 	    objectList().append( star );
         Trixel trixel = m_skyMesh->indexStar( star );
         m_starIndex->at( trixel )->append( star );
@@ -314,22 +346,13 @@
             if ( list->append( trixel, star, pm ) ) break;
         }
 
-        if ( currentMag > m_FaintMagnitude ) {   // Done!
-            lastFilePos = fileReader.pos();
+		fileReader.showProgress();
+
+        if ( currentMag > m_FaintMagnitude )   // Done!
             break; 
-        }
-
-        fileReader.showProgress();
     }
 
-	//Options::setMagLimitDrawStar( newMagnitude );       -jbb
-    //if ( lastFilePos == 0 ) emitProgressText( i18n("Loading stars done.") );
-
-    //for (int j = 0; j < m_highPMStars.size(); j++ ) {
-    //    m_highPMStars.at( j )->stats();
-    //}
-
-    //printf("star catalog reindexInterval = %6.1f years\n", 100.0 * m_reindexInterval );
+	m_lastLineNum += fileReader.lineNumber();
 }
 
 
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/starcomponent.h #701763:701764
@@ -26,8 +26,6 @@
 *@version 0.1
 */
 
-#define NHIPFILES 127
-
 #include "listcomponent.h"
 #include "kstarsdatetime.h"
 #include "ksnumbers.h"
@@ -42,9 +40,10 @@
 class SkyMesh;
 class StarObject;
 class SkyLabeler;
-
 class KStarsSplash;
 
+#define MAX_LINENUMBER_MAG 90
+
 //typedef QVector< StarList* > StarIndex;
 
 class StarComponent: public ListComponent
@@ -110,6 +109,8 @@
 		 */
 		void rereadData();
 
+		void readLineNumbers();
+		int lineNumber( float mag );
 
 	private:
         SkyMesh*       m_skyMesh;
@@ -118,14 +119,18 @@
         KSNumbers      m_reindexNum;
         double         m_reindexInterval;
 
+		int            m_lineNumber[ MAX_LINENUMBER_MAG + 1 ];
+        qint64         m_lastFilePos;
+        int            m_lastLineNum;
+		bool           m_validLineNums;
+
         QVector<HighPMStarList*> m_highPMStars;
         
-        qint64 lastFilePos;
-
         QHash<QString, SkyObject*> m_genName;
 
         void reindexAll( KSNumbers *num );
 
+
 	/** 
 		*Parse a line from a stars data file, construct a StarObject from the data,
 		*and add it to the StarComponent.


More information about the Kstars-devel mailing list