~jstys-z/helioviewer.org/client5

« back to all changes in this revision

Viewing changes to api/src/Database/ImgIndex.php

Preparing to merge in my branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
3
/**
 
4
 * ImgIndex Class definition
 
5
 *
 
6
 * PHP version 5
 
7
 *
 
8
 * @category Database
 
9
 * @package  Helioviewer
 
10
 * @author   Keith Hughitt <keith.hughitt@nasa.gov>
 
11
 * @author   Patrick Schmiedel <patrick.schmiedel@gmx.net>
 
12
 * @license  http://www.mozilla.org/MPL/MPL-1.1.html Mozilla Public License 1.1
 
13
 * @link     http://launchpad.net/helioviewer.org
 
14
 */
 
15
/**
 
16
 * Provides methods for interacting with a JPEG 2000 archive.
 
17
 *
 
18
 * @category Database
 
19
 * @package  Helioviewer
 
20
 * @author   Keith Hughitt <keith.hughitt@nasa.gov>
 
21
 * @author   Patrick Schmiedel <patrick.schmiedel@gmx.net>
 
22
 * @license  http://www.mozilla.org/MPL/MPL-1.1.html Mozilla Public License 1.1
 
23
 * @link     http://launchpad.net/helioviewer.org
 
24
 */
 
25
class Database_ImgIndex
 
26
{
 
27
    private $_dbConnection;
 
28
 
 
29
    /**
 
30
     * Creates an ImgIndex instance
 
31
     *
 
32
     * @return void
 
33
     */
 
34
    public function __construct()
 
35
    {
 
36
        include_once 'DbConnection.php';
 
37
        $this->_dbConnection = new Database_DbConnection();
 
38
    }
 
39
 
 
40
    /**
 
41
     * Finds the closest available image to the requested one, and returns information from
 
42
     * database and XML box.
 
43
     *
 
44
     * @param string $date     A UTC date string of the form "2003-10-05T00:00:00Z."
 
45
     * @param int    $sourceId An identifier specifying the image type or source requested.
 
46
     *
 
47
     * @return array Information about the image match including it's location, time, scale, and dimensions.
 
48
     */
 
49
    public function getClosestImage($date, $sourceId)
 
50
    {
 
51
        $img      = $this->getImageFromDatabase($date, $sourceId);
 
52
        $filename = HV_JP2_DIR . $img["filepath"] . "/" .$img["filename"];
 
53
        $xmlBox   = $this->extractJP2MetaInfo($filename);
 
54
 
 
55
        return array_merge($img, $xmlBox);
 
56
    }
 
57
 
 
58
    /**
 
59
     * Queries database and finds the best matching image.
 
60
     *
 
61
     * @param string $date     A UTC date string of the form "2003-10-05T00:00:00Z."
 
62
     * @param int    $sourceId An identifier specifying the image type or source requested.
 
63
     *
 
64
     * @return array Array including the image id, filepath, filename, date, and sourceId.
 
65
     */
 
66
    public function getImageFromDatabase($date, $sourceId)
 
67
    {
 
68
        include_once 'src/Helper/DateTimeConversions.php';
 
69
 
 
70
        $datestr = isoDateToMySQL($date);
 
71
 
 
72
        // Search left and right side of image database B-Tree separately
 
73
        $lhs = sprintf("SELECT id, filepath, filename, date FROM image WHERE sourceId = %d AND date < '%s' ORDER BY date DESC LIMIT 1;", $sourceId, $datestr);
 
74
        $rhs = sprintf("SELECT id, filepath, filename, date FROM image WHERE sourceId = %d AND date >= '%s' ORDER BY date ASC LIMIT 1;", $sourceId, $datestr);
 
75
 
 
76
        //die("$lhs<br><br><span style='color: green;'>$rhs</span><br><br><hr>");
 
77
 
 
78
        $left = mysqli_fetch_array($this->_dbConnection->query($lhs), MYSQL_ASSOC);
 
79
        $right = mysqli_fetch_array($this->_dbConnection->query($rhs), MYSQL_ASSOC);
 
80
 
 
81
        $dateTimestamp = toUnixTimestamp($date);
 
82
 
 
83
        // Select closest match
 
84
        if (abs($dateTimestamp - toUnixTimestamp($left["date"])) < abs($dateTimestamp - toUnixTimestamp($right["date"]))) {
 
85
            $img = $left;
 
86
        } else {
 
87
            $img = $right;
 
88
        }
 
89
 
 
90
        // Check to make sure a match was found
 
91
        if (is_null($img)) {
 
92
            $sql = "SELECT name FROM datasource WHERE id=$sourceId";
 
93
            $result = mysqli_fetch_array($this->_dbConnection->query($sql), MYSQL_ASSOC);
 
94
            $source = $result["name"];
 
95
            throw new Exception("No images of the requested type ($source) were found in the database.");
 
96
        }
 
97
 
 
98
        // Fix types
 
99
        $img["id"]  = (int) $img["id"];
 
100
 
 
101
        return $img;
 
102
    }
 
103
 
 
104
    /**
 
105
     * Returns the number of images in the database for a given source and time range
 
106
     *
 
107
     * @param datetime $start    Query start time
 
108
     * @param datetime $end      Query end time
 
109
     * @param int      $sourceId The sourceId to query
 
110
     *
 
111
     * @return int The number of images in the database within the specified constraints
 
112
     */
 
113
    public function getImageCount($start, $end, $sourceId) {
 
114
        include_once 'src/Helper/DateTimeConversions.php';
 
115
        $startDate = isoDateToMySQL($start);
 
116
        $endDate   = isoDateToMySQL($end);
 
117
 
 
118
        $sql = "SELECT COUNT(*) FROM image WHERE sourceId=$sourceId AND date BETWEEN '$startDate' AND '$endDate'";
 
119
        $result = mysqli_fetch_array($this->_dbConnection->query($sql));
 
120
        return (int) $result[0];
 
121
    }
 
122
 
 
123
    /**
 
124
     * Returns an array containing all images for a given source and time range
 
125
     *
 
126
     * @param datetime $start    Query start time
 
127
     * @param datetime $end      Query end time
 
128
     * @param int      $sourceId The sourceId to query
 
129
     *
 
130
     * @return int The number of images in the database within the specified constraints
 
131
     */
 
132
    public function getImageRange($start, $end, $sourceId) {
 
133
        include_once 'src/Helper/DateTimeConversions.php';
 
134
        $startDate = isoDateToMySQL($start);
 
135
        $endDate   = isoDateToMySQL($end);
 
136
 
 
137
        $images = array();
 
138
        $sql = "SELECT * FROM image WHERE sourceId=$sourceId AND date BETWEEN '$startDate' AND '$endDate'";
 
139
        $result = $this->_dbConnection->query($sql);
 
140
 
 
141
        while ($image = $result->fetch_array(MYSQL_ASSOC)) {
 
142
            array_push($images, $image);
 
143
        }
 
144
        return $images;
 
145
    }
 
146
 
 
147
    /**
 
148
     * Extract necessary meta-information from an image
 
149
     *
 
150
     * @param string $img Location of a JP2 image.
 
151
     *
 
152
     * @return array A subset of the information stored in the jp2 header
 
153
     */
 
154
    public function extractJP2MetaInfo ($img)
 
155
    {
 
156
        include_once "src/Image/JPEG2000/JP2ImageXMLBox.php";
 
157
 
 
158
        try {
 
159
            $xmlBox = new Image_JPEG2000_JP2ImageXMLBox($img);
 
160
 
 
161
            $dimensions = $xmlBox->getImageDimensions();
 
162
            $center     = $xmlBox->getSunCenter();
 
163
 
 
164
            $meta = array(
 
165
                "scale"      => (float) $xmlBox->getImagePlateScale(),
 
166
                "width"      => (int) $dimensions[0],
 
167
                "height"     => (int) $dimensions[1],
 
168
                "rotated"    => (bool) $xmlBox->getImageRotationStatus(),
 
169
                "sunCenterX" => (float) $center[0],
 
170
                "sunCenterY" => (float) $center[1],
 
171
            );
 
172
        } catch (Exception $e) {
 
173
            logErrorMsg($img['filename'] . ": " . $e->getMessage(), true);
 
174
        }
 
175
 
 
176
        return $meta;
 
177
    }
 
178
 
 
179
 
 
180
    /**
 
181
     * Returns the sourceId for a given set of parameters.
 
182
     *
 
183
     * @param string $obs  Observatory
 
184
     * @param string $inst Instrument
 
185
     * @param string $det  Detector
 
186
     * @param string $meas Measurement
 
187
     *
 
188
     * @return int The matched sourceId.
 
189
     */
 
190
    public function getSourceId ($obs, $inst, $det, $meas)
 
191
    {
 
192
        $sql = sprintf(
 
193
            "SELECT
 
194
                datasource.id
 
195
            FROM datasource
 
196
                LEFT JOIN observatory ON datasource.observatoryId = observatory.id
 
197
                LEFT JOIN instrument ON datasource.instrumentId = instrument.id
 
198
                LEFT JOIN detector ON datasource.detectorId = detector.id
 
199
                LEFT JOIN measurement ON datasource.measurementId = measurement.id
 
200
            WHERE
 
201
                observatory.name='%s' AND
 
202
                instrument.name='%s' AND
 
203
                detector.name='%s' AND
 
204
                measurement.name='%s';",
 
205
            mysqli_real_escape_string($this->_dbConnection->link, $obs),
 
206
            mysqli_real_escape_string($this->_dbConnection->link, $inst),
 
207
            mysqli_real_escape_string($this->_dbConnection->link, $det),
 
208
            mysqli_real_escape_string($this->_dbConnection->link, $meas)
 
209
        );
 
210
        $result = $this->_dbConnection->query($sql);
 
211
        $result_array = mysqli_fetch_array($result, MYSQL_ASSOC);
 
212
 
 
213
        return (int) ($result_array["id"]);
 
214
    }
 
215
 
 
216
    /**
 
217
     * Returns a list of the known data sources
 
218
     *
 
219
     * @return array A tree representation of the known data sources
 
220
     */
 
221
    public function getDataSources ()
 
222
    {
 
223
        // Query
 
224
        $sql = "
 
225
            SELECT
 
226
                datasource.name as name,
 
227
                datasource.id as id,
 
228
                datasource.layeringOrder as layeringOrder,
 
229
                observatory.name as observatory,
 
230
                instrument.name as instrument,
 
231
                detector.name as detector,
 
232
                measurement.name as measurement
 
233
            FROM datasource
 
234
                LEFT JOIN observatory ON datasource.observatoryId = observatory.id
 
235
                LEFT JOIN instrument ON datasource.instrumentId = instrument.id
 
236
                LEFT JOIN detector ON datasource.detectorId = detector.id
 
237
                LEFT JOIN measurement ON datasource.measurementId = measurement.id;";
 
238
 
 
239
        // Fetch available data-sources
 
240
        $result = $this->_dbConnection->query($sql);
 
241
 
 
242
        $sources = array();
 
243
 
 
244
        while ($row = $result->fetch_array(MYSQL_ASSOC)) {
 
245
            array_push($sources, $row);
 
246
        }
 
247
 
 
248
        // Convert results into a more easily traversable tree structure
 
249
        $tree = array();
 
250
 
 
251
        foreach ($sources as $source) {
 
252
 
 
253
            // Image parameters
 
254
            $obs  = $source["observatory"];
 
255
            $inst = $source["instrument"];
 
256
            $det  = $source["detector"];
 
257
            $meas = $source["measurement"];
 
258
            $name = $source["name"];
 
259
            $ord  = (int) ($source["layeringOrder"]);
 
260
            $id   = (int) ($source["id"]);
 
261
 
 
262
            // Build tree
 
263
            if (!isset($tree[$obs])) {
 
264
                $tree[$obs] = array();
 
265
            }
 
266
            if (!isset($tree[$obs][$inst])) {
 
267
                $tree[$obs][$inst] = array();
 
268
            }
 
269
            if (!isset($tree[$obs][$inst][$det])) {
 
270
                $tree[$obs][$inst][$det] = array();
 
271
            }
 
272
            $tree[$obs][$inst][$det][$meas] = array("sourceId"=>$id, "name"=>$name, "layeringOrder"=>$ord);
 
273
        }
 
274
 
 
275
        return $tree;
 
276
    }
 
277
 
 
278
    /**
 
279
     * Finds the closest match for a requested image and returns it's location
 
280
     *
 
281
     * @param string $date     A UTC date string of the form "2003-10-05T00:00:00Z."
 
282
     * @param int    $sourceId An identifier specifying the image type or source requested.
 
283
     *
 
284
     * @return string Local filepath for the JP2 image.
 
285
     *
 
286
     */
 
287
    public function getJP2FilePath($date, $sourceId)
 
288
    {
 
289
        $img = $this->getImageFromDatabase($date, $sourceId);
 
290
        return $img["filepath"] . "/" . $img["filename"];
 
291
    }
 
292
}
 
293
?>