<commit_before>/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2016                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TEMPORAL_TILE_PROVIDER___H__
#define __OPENSPACE_MODULE_GLOBEBROWSING___TEMPORAL_TILE_PROVIDER___H__

#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>

#include <openspace/util/time.h>
#include <openspace/util/timerange.h>

#include <memory>
#include <string>
#include <unordered_map>

struct CPLXMLNode;

namespace openspace {
namespace globebrowsing {

/**
 * Interface for stringifying OpenSpace Time instances.
 *
 * Once OpenSpace has a proper Time format class, this should be handled by that instead
 * of here.    
 */
struct TimeFormat {
    /**
     * Stringifies a OpenSpace time instance
     * \param t The time to be stringifyed
     * \returns A string description of the provided time
     */
    virtual std::string stringify(const Time& t) const = 0;
};

/**
 * Stringifies OpenSpace to the format "YYYY-MM-DD".
 * Example: 2016-09-08
 */
struct YYYY_MM_DD : public TimeFormat {
    virtual std::string stringify(const Time& t) const;
};

/**
 * Stringifies OpenSpace to the format "YYYY-MM-DDThh:mm:ssZ"
 * Example: 2016-09-08T23:05:05Z
 */
struct YYYY_MM_DDThhColonmmColonssZ : public TimeFormat {
    virtual std::string stringify(const Time& t) const;
};
    
/**
 * Stringifies OpenSpace to the format "YYYY-MM-DDThh:mm:ssZ"
 * Example: 2016-09-08T23:05:05Z
 */
struct YYYY_MM_DDThh_mm_ssZ : public TimeFormat {
    virtual std::string stringify(const Time& t) const;
};

/**
 * Static factory class for providing different TimeFormats.
 * A time format stringifier is retrieved by a name of the format.
 * See implementation of <code>init()</code> to see what time 
 * id formats are supported.
 */
struct TimeIdProviderFactory {
    /**
     * Maps a name of a format to an implementation of a TimeFormat.
     * Calling this method will also initialize the TimeIdProviderFactory
     * if it hasn't been.
     *
     * See implementation of <code>init()</code> for supported time formats.
     *
     * \param format - name of TimeFormat, eg "YYYY-MM-DDThh:mm:ssZ".
     * \returns a concrete TimeFormat used to stringify instances of Time 
     */
    static TimeFormat* getProvider(const std::string& format);

    /**
     * Registers all supported TimeFormats.
     */
    static void init();

    static std::unordered_map<std::string, std::unique_ptr<TimeFormat>> _timeIdProviderMap;
    static bool initialized;
};

/**
 * Used to quantize time to descrete values. 
 */
struct TimeQuantizer {
    TimeQuantizer() {}
    TimeQuantizer(const Time& start, const Time& end, double resolution);
    TimeQuantizer(const Time& start, const Time& end, const std::string& resolutionStr);

    /**
     * Takes a time resulition string and parses it into a double 
     * value representing the time resolution as seconds.
     *
     * Example: parseTimeResolutionStr("1d");
     * 
     * \param resoltutionStr with the format {number}{unit}
     *        where supported units are: 
     *        (s)econds, (m)inutes, (h)ours, (d)ays, (y)ears
     *
     * \returns the time resolution in seconds
     */
    static double parseTimeResolutionStr(const std::string& resoltutionStr);

    /**
     * Quantizes a OpenSpace Time into descrete values.
     * If the provided Time t is outside the time range, it will
     * be clamped to the the time range.
     *
     * \param t Time instance, which will be quantized
     * \param clamp Whether or not time should be clamped if not t is in the time range
     * \returns wether or not time was quantized
     */
    bool quantize(Time& t, bool clamp) const;

private:
    TimeRange _timerange;
    double _resolution;
};

/**
 * Provide <code>Tile</code>s from web map services that have temporal resolution.
 *
 * TemporalTileProviders are instantiated using a ghoul::Dictionary,
 * and must define a filepath to a Openspace Temporal dataset description file. 
 * This is an xml-file that defines the same meta data as the GDAL wms description
 * (http://www.gdal.org/frmt_wms.html), but augmented with some 
 * extra tags describing the temporal properties of the dataset. See 
 * <code>TemporalTileProvider::TemporalXMLTags</code>
 * 
 */
class TemporalTileProvider : public TileProvider {
public:
    /**
     * Dictionary constructor. Must provide KeyFilePath as defined in .cpp file.
     */
    TemporalTileProvider(const ghoul::Dictionary& dictionary);

    // These methods implements the TileProvider interface

    virtual Tile getTile(const TileIndex& tileIndex);
    virtual Tile getDefaultTile();
    virtual Tile::Status getTileStatus(const TileIndex& tileIndex);
    virtual TileDepthTransform depthTransform();
    virtual void update();
    virtual void reset();
    virtual int maxLevel();


    typedef std::string TimeKey;

    std::shared_ptr<TileProvider> getTileProvider(Time t = Time::ref());
    std::shared_ptr<TileProvider> getTileProvider(TimeKey timekey);

private:
    /**
     * A placeholder string that must be provided in the WMS template url. This 
     * placeholder will be replaced by quantized date-time strings during run time
     * in order to access the datasets for different instances of time.
     */
    static const char* URL_TIME_PLACEHOLDER;

    /**
     * These are tags that TemporalTileProviders must be able to read from the XML
     * file provided in the ghoul::Dictionary used to create this provider. These
     * tags describe the temporal properties of the dataset.
     */
    static const struct TemporalXMLTags {
        /**
         * Tag should contain a ISO8601 time specifying the datasets start time<commit_msg>Jenkins compile fix<commit_after>/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2016                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TEMPORAL_TILE_PROVIDER___H__
#define __OPENSPACE_MODULE_GLOBEBROWSING___TEMPORAL_TILE_PROVIDER___H__

#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>

#include <openspace/util/time.h>
#include <openspace/util/timerange.h>

#include <memory>
#include <string>
#include <unordered_map>

struct CPLXMLNode;

namespace openspace {
namespace globebrowsing {

/**
 * Interface for stringifying OpenSpace Time instances.
 *
 * Once OpenSpace has a proper Time format class, this should be handled by that instead
 * of here.    
 */
struct TimeFormat {
    /**
     * Stringifies a OpenSpace time instance
     * \param t The time to be stringifyed
     * \returns A string description of the provided time
     */
    virtual std::string stringify(const Time& t) const = 0;
};

/**
 * Stringifies OpenSpace to the format "YYYY-MM-DD".
 * Example: 2016-09-08
 */
struct YYYY_MM_DD : public TimeFormat {
    virtual std::string stringify(const Time& t) const;
};

/**
 * Stringifies OpenSpace to the format "YYYY-MM-DDThh:mm:ssZ"
 * Example: 2016-09-08T23:05:05Z
 */
struct YYYY_MM_DDThhColonmmColonssZ : public TimeFormat {
    virtual std::string stringify(const Time& t) const;
};
    
/**
 * Stringifies OpenSpace to the format "YYYY-MM-DDThh:mm:ssZ"
 * Example: 2016-09-08T23:05:05Z
 */
struct YYYY_MM_DDThh_mm_ssZ : public TimeFormat {
    virtual std::string stringify(const Time& t) const;
};

/**
 * Static factory class for providing different TimeFormats.
 * A time format stringifier is retrieved by a name of the format.
 * See implementation of <code>init()</code> to see what time 
 * id formats are supported.
 */
struct TimeIdProviderFactory {
    /**
     * Maps a name of a format to an implementation of a TimeFormat.
     * Calling this method will also initialize the TimeIdProviderFactory
     * if it hasn't been.
     *
     * See implementation of <code>init()</code> for supported time formats.
     *
     * \param format - name of TimeFormat, eg "YYYY-MM-DDThh:mm:ssZ".
     * \returns a concrete TimeFormat used to stringify instances of Time 
     */
    static TimeFormat* getProvider(const std::string& format);

    /**
     * Registers all supported TimeFormats.
     */
    static void init();

    static std::unordered_map<std::string, std::unique_ptr<TimeFormat>> _timeIdProviderMap;
    static bool initialized;
};

/**
 * Used to quantize time to descrete values. 
 */
struct TimeQuantizer {
    TimeQuantizer() {}
    TimeQuantizer(const Time& start, const Time& end, double resolution);
    TimeQuantizer(const Time& start, const Time& end, const std::string& resolutionStr);

    /**
     * Takes a time resulition string and parses it into a double 
     * value representing the time resolution as seconds.
     *
     * Example: parseTimeResolutionStr("1d");
     * 
     * \param resoltutionStr with the format {number}{unit}
     *        where supported units are: 
     *        (s)econds, (m)inutes, (h)ours, (d)ays, (y)ears
     *
     * \returns the time resolution in seconds
     */
    static double parseTimeResolutionStr(const std::string& resoltutionStr);

    /**
     * Quantizes a OpenSpace Time into descrete values.
     * If the provided Time t is outside the time range, it will
     * be clamped to the the time range.
     *
     * \param t Time instance, which will be quantized
     * \param clamp Whether or not time should be clamped if not t is in the time range
     * \returns wether or not time was quantized
     */
    bool quantize(Time& t, bool clamp) const;

private:
    TimeRange _timerange;
    double _resolution;
};

/**
 * Provide <code>Tile</code>s from web map services that have temporal resolution.
 *
 * TemporalTileProviders are instantiated using a ghoul::Dictionary,
 * and must define a filepath to a Openspace Temporal dataset description file. 
 * This is an xml-file that defines the same meta data as the GDAL wms description
 * (http://www.gdal.org/frmt_wms.html), but augmented with some 
 * extra tags describing the temporal properties of the dataset. See 
 * <code>TemporalTileProvider::TemporalXMLTags</code>
 * 
 */
class TemporalTileProvider : public TileProvider {
public:
    /**
     * Dictionary constructor. Must provide KeyFilePath as defined in .cpp file.
     */
    TemporalTileProvider(const ghoul::Dictionary& dictionary);

    // These methods implements the TileProvider interface

    virtual Tile getTile(const TileIndex& tileIndex);
    virtual Tile getDefaultTile();
    virtual Tile::Status getTileStatus(const TileIndex& tileIndex);
    virtual TileDepthTransform depthTransform();
    virtual void update();
    virtual void reset();
    virtual int maxLevel();


    typedef std::string TimeKey;

    std::shared_ptr<TileProvider> getTileProvider(Time t = Time::ref());
    std::shared_ptr<TileProvider> getTileProvider(TimeKey timekey);

private:
    /**
     * A placeholder string that must be provided in the WMS template url. This 
     * placeholder will be replaced by quantized date-time strings during run time
     * in order to access the datasets for different instances of time.
     */
    static const char* URL_TIME_PLACEHOLDER;

    /**
     * These are tags that TemporalTileProviders must be able to read from the XML
     * file provided in the ghoul::Dictionary used to create this provider. These
     * tags describe the temporal properties of the dataset.
     */
    struct TemporalXMLTags {
        /**
         * Tag should contain a ISO8601 time specifying the datasets start time
{'fraction_non_alphanumeric': 0.09609531826717607, 'fraction_numerical': 0.0064754257592436705, 'mean_word_length': 2.414547866460314, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 62, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7486435', 'n_tokens_mistral': 3993, 'n_tokens_neox': 3785, 'n_words': 1485}