/** * Parses a TWL file for data. * * @param string $site * @param string $fileDateTime The file date time in the format YYYYMMDDtHHMMSS * @param resource $fileHandle Te file handle to the file containing the data to be parsed. * @param bool $errorOnBadData If true then bad parsed data will result in an exception. If false the data * will be skipped. * * @throws InvalidOperationException * @throws MyInvalidArgumentException */ protected static final function importTwlFile($site, $fileDateTime, $fileHandle, $errorOnBadData = TRUE) { if (is_null(self::$databaseCredentials)) { throw new InvalidOperationException('Database credentials must be set at the class level to allow this action to take place.'); } /** @var TwlTimeSeries $currentTimeSeries */ $currentTimeSeries = NULL; $whitespacePattern = '/\\s+/'; $twlFile = new TwlFile($site, $fileDateTime); $line = 0; print $twlFile->getSiteName() . '<br>'; print $twlFile->getFileDateTime() . '<br>'; while (!feof($fileHandle)) { $line++; $twlFileLine = fgets($fileHandle); $twlFileLine = trim($twlFileLine); $twlFileLineData = preg_split($whitespacePattern, $twlFileLine); if ($twlFileLineData[0] == NULL || substr($twlFileLineData[0], 0, 1) == '%') { continue; // Skip the line } if (count($twlFileLineData) != 16) { if ($errorOnBadData) { throw new MyInvalidArgumentException('Import failed. Line ' . $line . ' does not contain sufficient data or is improperly formatted.'); } else { continue; // Skip the line. } } try { $position = new LatLng($twlFileLineData[2], $twlFileLineData[1]); $dataPoint = new TwlDataPoint($twlFileLineData[0], $position, $twlFileLineData[3], $twlFileLineData[4], $twlFileLineData[6], $twlFileLineData[8], $twlFileLineData[7], $twlFileLineData[9], $twlFileLineData[11], $twlFileLineData[10], $twlFileLineData[12], $twlFileLineData[13], $twlFileLineData[14], $twlFileLineData[15]); if (is_null($currentTimeSeries) || !$currentTimeSeries->getPosition()->isEqualTo($position)) { if (isset($currentTimeSeries)) { $currentTimeSeries->sortDataPoints(); } $currentTimeSeries = new TwlTimeSeries($position, $twlFileLineData[5]); $twlFile->addTimeSeries($currentTimeSeries); } $currentTimeSeries->addDataPoint($dataPoint); } catch (Exception $e) { if ($errorOnBadData) { throw new MyInvalidArgumentException('Import failed. Line ' . $line . ' contains invalid data.', $e); } else { continue; } } } $DBH = call_user_func_array('DatabaseHelper::getInstance', self::$databaseCredentials); $error = FALSE; $DBH->beginTransaction(); $fileId = $twlFile->saveFile(); if ($fileId) { TwlTimeSeries::setDatabaseCredentials(self::$databaseCredentials); TwlDataPoint::setDatabaseCredentials(self::$databaseCredentials); foreach ($twlFile->timeSeries as $individualTimeSeries) { if ($timeSeriesId = $individualTimeSeries->saveTimeSeries()) { foreach ($individualTimeSeries as $individualDataPoint) { if (!$individualDataPoint->saveDataPoint($fileId, $timeSeriesId)) { print 'twlDataPoint could not be saved to DB'; $error = TRUE; break 2; } } } else { print $timeSeriesId; print 'twlTimeSeries could not be saved to DB<br>'; $error = TRUE; break; } } $siteLastImportQuery = <<<MYSQL UPDATE sites SET last_import = :importTime WHERE site_id = :selectedSiteId MYSQL; $tempDateTime = new DateTime($fileDateTime, new DateTimeZone('UTC')); $siteLastImportParams = array('importTime' => $tempDateTime->format('Y-m-d H:i:s'), 'selectedSiteId' => Site::getIdByName($site)); DatabaseHelper::query($DBH, $siteLastImportQuery, $siteLastImportParams); } elseif ($fileId === '0') { print 'twlFile already exists in the DB.'; $error = TRUE; } else { print 'twlFile could not be saved to DB'; $error = TRUE; } if ($error) { $DBH->rollBack(); } else { $DBH->commit(); } }
/** * Checks to see if the first data point has a datetime before, after or equal to the second data point. * * @param TwlDataPoint $dataPoint1 The first point to compare. * @param TwlDataPoint $dataPoint2 The second point to compare. * * @return int -1 if DP1<DP2, 0 if DP1=DP2, 1 if DP1>DP2. */ public static final function compareDataPointTime(TwlDataPoint $dataPoint1, TwlDataPoint $dataPoint2) { if ($dataPoint1->getTimestamp() < $dataPoint2->getTimestamp()) { return -1; } elseif ($dataPoint1->getTimestamp() > $dataPoint2->getTimestamp()) { return 1; } else { return 0; } }