<commit_before>goog.provide('og.gmx.VectorLayer');

goog.require('og.ajax');
goog.require('og.utils');
goog.require('og.inheritance');
goog.require('og.layer.Layer');

goog.require('og.gmx.CheckVersion');
goog.require('og.gmx.VectorTileCreator');
goog.require('og.gmx.TileData');
goog.require('og.gmx.Item');
goog.require('og.gmx.Material');
goog.require('og.QueueArray');

/**
 * TODO: description
 * @class
 * @param {String} name - Layer user name.
 * @param {Object} options:
 * @extends {og.layer.Layer}
 */
og.gmx.VectorLayer = function (name, options) {
    options = options || {};

    og.inheritance.base(this, name, options);

    this.isVector = true;

    this.hostUrl = options.hostUrl || "//maps.kosmosnimki.ru/";

    this._initialized = false;

    this._layerId = options.layerId;

    this._tileSenderUrlTemplate = '//maps.kosmosnimki.ru/TileSender.ashx?WrapStyle=None&ModeKey=tile&r=j&ftc=osm&srs=3857&LayerName={id}&z={z}&x={x}&y={y}&v={v}';

    this._gmxProperties = null;

    this._beginDate = options.beginDate || null;
    this._endDate = options.endDate || null;

    this._itemCache = {};

    this._tileDataCache = {};

    this._tileVersions = {};

    this._itemZIndexCounter = 0;

    this._filterCallback = null;

    this._filteredItems = {};

    this._styleCallback = null;

    this._styledItems = {};

    this._updatedItemArr = [];
    this._updatedItems = {};

    this._style = options.style || {};
    this._style.fillColor = og.utils.createColorRGBA(this._style.fillColor, new og.math.Vector4(0.19, 0.62, 0.85, 0.57));
    this._style.lineColor = og.utils.createColorRGBA(this._style.lineColor, new og.math.Vector4(0.19, 0.62, 0.85, 1));
    this._style.strokeColor = og.utils.createColorRGBA(this._style.strokeColor, new og.math.Vector4(1, 1, 1, 0.95));
    this._style.lineWidth = this._style.lineWidth || 5;
    this._style.strokeWidth = this._style.strokeWidth || 0;

    this.events.registerNames(og.gmx.VectorLayer.EVENT_NAMES);

    /**
     * Current loading tiles couter.
     * @protected
     * @type {number}
     */
    this._counter = 0;

    /**
     * Tile pending queue that waiting for loading.
     * @protected
     * @type {Array.<og.planetSegment.Material>}
     */
    this._pendingsQueue = new og.QueueArray();
};

og.inheritance.extend(og.gmx.VectorLayer, og.layer.Layer);

og.gmx.VectorLayer.EVENT_NAMES = [
    "draw",

    /**
     * Triggered when current tile image has loaded before rendereing.
     * @event og.gmx.VectorLayer#load
     */
    "load",

    /**
     * Triggered when all tiles have loaded or loading has stopped.
     * @event og.gmx.VectorLayer#loadend
     */
    "loadend"
];

/**
 * Vector layer {@link og.gmx.VectorLayer} object factory.
 * @static
 * @param {String} name - Layer name.
 * @param {Object} options - Layer options.
 * @returns {og.gmx.VectorLayer} Returns vector layer.
 */
og.gmx.vectorLayer = function (name, options) {
    return new og.gmx.VectorLayer(name, options);
};

og.gmx.VectorLayer.prototype._bindPicking = function () {
    this._pickingColor.clear();
};

og.gmx.VectorLayer.prototype.createMaterial = function (segment) {
    return new og.gmx.Material(segment, this);
};

/**
 * Adds layer to the planet.
 * @public
 * @param {og.scene.RenderNode} planet - Planet scene.
 * @return {og.gmx.VectorLayer} - Returns og.gmx.VectorLayer instance.
 */
og.gmx.VectorLayer.prototype.addTo = function (planet) {

    //Bind checkVersion to the planet
    if (!planet._gmxCheckVersion) {
        planet._gmxCheckVersion = new og.gmx.CheckVersion(planet);
    }

    //Bind gmxVectorTileCreator to the planet
    if (!planet._gmxVectorTileCreator) {
        planet._gmxVectorTileCreator = new og.gmx.VectorTileCreator(planet);
    }

    this._assignPlanet(planet);

    if (this._visibility && !this._initialized) {
        this._initialize();
    }

    return this;
};

og.gmx.VectorLayer.getLayerInfo = function (hostUrl, layerId, proceedCallback, errorCallback) {
    og.ajax.request(hostUrl + "/rest/ver1/layers/" + layerId + "/info", {
        'type': "GET",
        'responseType': "json",
        'data': {
            'WrapStyle': "None"
        },
        'success': function (data) {
            proceedCallback && proceedCallback(data);
        },
        'error': function (err) {
            errorCallback && errorCallback(err);
        }
    });
};

og.gmx.VectorLayer.dateToEpoch = function (date) {
    var time = date.getTime();
    return time - time % 86400000;
};

og.gmx.VectorLayer.prototype._initialize = function () {

    this._initialized = true;

    var p = this._planet;
    var that = this;

    og.gmx.VectorLayer.getLayerInfo(this.hostUrl, this._layerId, function (data) {
        that._gmxProperties = data.properties;
        if (data.properties.Temporal) {
            var d = new Date();
            var currEpoch = og.gmx.VectorLayer.dateToEpoch(d);
            that._beginDate = that._beginDate || new Date(currEpoch);
            that._endDate = that._endDate || new Date(d.setTime(currEpoch + 24 * 60 * 60 * 1000));
        }
        that.setExtent(og.Geometry.getExtent(data.geometry));
        p._gmxCheckVersion.update();
    });
};

/**
 * Sets layer visibility.
 * @public
 * @virtual
 * @param {boolean} visibility - Layer visibility.
 */
og.gmx.VectorLayer.prototype.setVisibility = function (visibility) {

    og.layer.Layer.prototype.setVisibility.call(this, visibility);

    if (this._visibility && !this._initialized) {
        this._initialize();
    }
};

og.gmx.VectorLayer.prototype._checkVersionSuccess = function (prop) {
    var to = prop.tilesOrder,
        ts = prop.tiles;
    var toSize = to.length;

    var _X = to.indexOf("X"),
        _Y = to.indexOf("Y"),
        _Z = to.indexOf("Z"),
        _V = to.indexOf("V");

    var tv = this._tileVersions;
    for (var i = 0; i < ts.length; i += toSize) {
        var x = ts[i + _X],
            y = ts[i + _Y],
            z = ts[i + _Z],
            v = ts[i + _V];
        var tileIndex = og.layer.getTileIndex(x, y, z);
        if (tv[tileIndex] !== v) {
            this._tileVersions[tileIndex] = v;
            this._getTile(x, y, z, v);
        }
    }
};

og.gmx.VectorLayer.prototype.setFilter = function (filterCallback) {
    this._filterCallback = filterCallback;
    this.updateFilter();
};

og.gmx.VectorLayer.prototype.removeFilter = function () {
    this._filterCallback = null;
    this.updateFilter();
};

og.gmx.VectorLayer.prototype.getItemVisibility = function (item) {
    if (!this._filterCallback) {
        return true;
    }
    var visibility = this._filteredItems[item.id];
    if (visibility == null) {
        visibility = this._filteredItems[item.id] = this._filterCallback[item.id](item);
    }
    return visibility;
};

og.gmx.VectorLayer.prototype.updateFilter = function () {
    this._filteredItems = {};
    //...TODO
};

og.gmx.VectorLayer.prototype.setStyleHook = function (styleCallback) {
    this._styleCallback = styleCallback;
    this.updateStyle();
};

og.gmx.VectorLayer.prototype.getItemStyle = function (item) {
    if (!this._styleCallback) {
        return item._style;
    }
    var style = this._styledItems[item.id];
    if (style == null) {
        style = this._styledItems[item.id] = this._styleCallback[item.id](item);
    }
    return style;
};

og.gmx.VectorLayer.prototype.updateStyle = function () {
    this._styledItems = {};
    //...TODO
};

og.gmx.VectorLayer.__requestsCounter = 0;
og.gmx.VectorLayer.MAX_REQUESTS = 8;

og.gmx.VectorLayer.prototype._getTile = function (x, y, z, v) {
    if (og.gmx.VectorLayer.__requestsCounter >= og.gmx.VectorLayer.MAX_REQUESTS && this._counter) {
        this._pendingsQueue.push({
            'id': this._layerId,
            'x': x.toString(), 'y': y.toString(), 'z': z.toString(),
            'v': v.toString()
        });
    } else {
        this._exec({
            'id': this._layerId,
            'x': x.toString(), 'y': y.toString(), 'z': z.toString(),
            'v': v.toString()
        });
    }
};

og.gmx.VectorLayer.prototype._exec = function (t) {

    var url = og.utils.stringTemplate(this._tileSenderUrlTemplate, t);

    og.gmx.VectorLayer.__requestsCounter++;
    this._counter++;

    var that = this;
    var r = og.ajax.request(url, {
        'type': "GET",
        'responseType': "text",
        'success': function (dataStr) {
            og.gmx.VectorLayer.__requestsCounter--;
            that._counter--;

            var data = JSON.parse(dataStr.substring(dataStr.indexOf('{'), dataStr.lastIndexOf('}') + 1));
            that._handleTileData(t.x, t.y, t.z, t.v, data);

            var e = that.events.load;
            if (e.handlers.length) {
                that.events.dispatch(e, data);
            }

            that._dequeueRequest();
        },
        'error': function (err) {
            og.gmx.VectorLayer.__requestsCounter--;
            that._counter--;

            console.log(err);

            that._dequeueRequest();
        }
    });
};

og.gmx.VectorLayer.prototype._dequeueRequest = function () {
    if (this._pendingsQueue.length) {
        if (og.gmx.VectorLayer.__requestsCounter < og.gmx.VectorLayer.MAX_REQUESTS) {
            var t = this._whilePendings();
            if (t)
                this._exec.call(this, t);
        }
    } else if (this._counter === 0) {
        var e = this.events.loadend;
        if (e.handlers.length) {
            this.events.dispatch(e);
        }
    }
};

og.gmx.VectorLayer.prototype._whilePendings = function () {
    while (this._pendingsQueue.length) {
        return this._pendingsQueue.pop();
        // if (pmat.segment.node) {
        //     if (pmat.segment.ready && pmat.segment.node.getState() === og.quadTree.RENDERING) {
        //         return t;
        //     }
        // }
    }
};


og.gmx.VectorLayer.prototype.addItem = function (item) {
    if (!item._layer) {
        this._itemCache[item.id] = item;
        item._layer = this;
        if (this._planet) {
            this._planet.renderer.assignPickingColor(item);
        }
    }
};

og.gmx.VectorLayer.prototype._handleTileData = function (x, y, z, v, data) {
    var items = data.values,
        style = this._style;

    for (var i = 0; i < items.length; i++) {

        var item = items[i],
            gmxId = item[0];

        var cacheItem = this._itemCache[gmxId];
<commit_msg>Let it stay<commit_after>goog.provide('og.gmx.VectorLayer');

goog.require('og.ajax');
goog.require('og.utils');
goog.require('og.inheritance');
goog.require('og.layer.Layer');

goog.require('og.gmx.CheckVersion');
goog.require('og.gmx.VectorTileCreator');
goog.require('og.gmx.TileData');
goog.require('og.gmx.Item');
goog.require('og.gmx.Material');
goog.require('og.QueueArray');

/**
 * TODO: description
 * @class
 * @param {String} name - Layer user name.
 * @param {Object} options:
 * @extends {og.layer.Layer}
 */
og.gmx.VectorLayer = function (name, options) {
    options = options || {};

    og.inheritance.base(this, name, options);

    this.isVector = true;

    this.hostUrl = options.hostUrl || "//maps.kosmosnimki.ru/";

    this._initialized = false;

    this._layerId = options.layerId;

    this._tileSenderUrlTemplate = '//maps.kosmosnimki.ru/TileSender.ashx?WrapStyle=None&ModeKey=tile&r=j&ftc=osm&srs=3857&LayerName={id}&z={z}&x={x}&y={y}&v={v}';

    this._gmxProperties = null;

    this._beginDate = options.beginDate || null;
    this._endDate = options.endDate || null;

    this._itemCache = {};

    this._tileDataCache = {};

    this._tileVersions = {};

    this._itemZIndexCounter = 0;

    this._filterCallback = null;

    this._filteredItems = {};

    this._styleCallback = null;

    this._styledItems = {};

    this._updatedItemArr = [];
    this._updatedItems = {};

    this._style = options.style || {};
    this._style.fillColor = og.utils.createColorRGBA(this._style.fillColor, new og.math.Vector4(0.19, 0.62, 0.85, 0.57));
    this._style.lineColor = og.utils.createColorRGBA(this._style.lineColor, new og.math.Vector4(0.19, 0.62, 0.85, 1));
    this._style.strokeColor = og.utils.createColorRGBA(this._style.strokeColor, new og.math.Vector4(1, 1, 1, 0.95));
    this._style.lineWidth = this._style.lineWidth || 5;
    this._style.strokeWidth = this._style.strokeWidth || 0;

    this.events.registerNames(og.gmx.VectorLayer.EVENT_NAMES);

    /**
     * Current loading tiles couter.
     * @protected
     * @type {number}
     */
    this._counter = 0;

    /**
     * Tile pending queue that waiting for loading.
     * @protected
     * @type {Array.<og.planetSegment.Material>}
     */
    this._pendingsQueue = new og.QueueArray();
};

og.inheritance.extend(og.gmx.VectorLayer, og.layer.Layer);

og.gmx.VectorLayer.EVENT_NAMES = [
    "draw",

    /**
     * Triggered when current tile image has loaded before rendereing.
     * @event og.gmx.VectorLayer#load
     */
    "load",

    /**
     * Triggered when all tiles have loaded or loading has stopped.
     * @event og.gmx.VectorLayer#loadend
     */
    "loadend"
];

/**
 * Vector layer {@link og.gmx.VectorLayer} object factory.
 * @static
 * @param {String} name - Layer name.
 * @param {Object} options - Layer options.
 * @returns {og.gmx.VectorLayer} Returns vector layer.
 */
og.gmx.vectorLayer = function (name, options) {
    return new og.gmx.VectorLayer(name, options);
};

og.gmx.VectorLayer.prototype._bindPicking = function () {
    this._pickingColor.clear();
};

og.gmx.VectorLayer.prototype.createMaterial = function (segment) {
    return new og.gmx.Material(segment, this);
};

/**
 * Adds layer to the planet.
 * @public
 * @param {og.scene.RenderNode} planet - Planet scene.
 * @return {og.gmx.VectorLayer} - Returns og.gmx.VectorLayer instance.
 */
og.gmx.VectorLayer.prototype.addTo = function (planet) {

    //Bind checkVersion to the planet
    if (!planet._gmxCheckVersion) {
        planet._gmxCheckVersion = new og.gmx.CheckVersion(planet);
    }

    //Bind gmxVectorTileCreator to the planet
    if (!planet._gmxVectorTileCreator) {
        planet._gmxVectorTileCreator = new og.gmx.VectorTileCreator(planet);
    }

    this._assignPlanet(planet);

    if (this._visibility && !this._initialized) {
        this._initialize();
    }

    return this;
};

og.gmx.VectorLayer.getLayerInfo = function (hostUrl, layerId, proceedCallback, errorCallback) {
    og.ajax.request(hostUrl + "/rest/ver1/layers/" + layerId + "/info", {
        'type': "GET",
        'responseType': "json",
        'data': {
            'WrapStyle': "None"
        },
        'success': function (data) {
            proceedCallback && proceedCallback(data);
        },
        'error': function (err) {
            errorCallback && errorCallback(err);
        }
    });
};

og.gmx.VectorLayer.dateToEpoch = function (date) {
    var time = date.getTime();
    return time - time % 86400000;
};

og.gmx.VectorLayer.prototype._initialize = function () {

    this._initialized = true;

    var p = this._planet;
    var that = this;

    og.gmx.VectorLayer.getLayerInfo(this.hostUrl, this._layerId, function (data) {
        that._gmxProperties = data.properties;
        if (data.properties.Temporal) {
            var d = new Date();
            var currEpoch = og.gmx.VectorLayer.dateToEpoch(d);
            that._beginDate = that._beginDate || new Date(currEpoch);
            that._endDate = that._endDate || new Date(d.setTime(currEpoch + 24 * 60 * 60 * 1000));
        }
        that.setExtent(og.Geometry.getExtent(data.geometry));
        p._gmxCheckVersion.update();
    });
};

/**
 * Sets layer visibility.
 * @public
 * @virtual
 * @param {boolean} visibility - Layer visibility.
 */
og.gmx.VectorLayer.prototype.setVisibility = function (visibility) {

    og.layer.Layer.prototype.setVisibility.call(this, visibility);

    if (this._visibility && !this._initialized) {
        this._initialize();
    }
};

og.gmx.VectorLayer.prototype._checkVersionSuccess = function (prop) {
    var to = prop.tilesOrder,
        ts = prop.tiles;
    var toSize = to.length;

    var _X = to.indexOf("X"),
        _Y = to.indexOf("Y"),
        _Z = to.indexOf("Z"),
        _V = to.indexOf("V");

    var tv = this._tileVersions;
    for (var i = 0; i < ts.length; i += toSize) {
        var x = ts[i + _X],
            y = ts[i + _Y],
            z = ts[i + _Z],
            v = ts[i + _V];
        var tileIndex = og.layer.getTileIndex(x, y, z);
        if (tv[tileIndex] !== v) {
            this._tileVersions[tileIndex] = v;
            this._getTile({
                'id': this._layerId,
                'x': x.toString(), 'y': y.toString(), 'z': z.toString(),
                'v': v.toString()
            });
        }
    }
};

og.gmx.VectorLayer.prototype.setFilter = function (filterCallback) {
    this._filterCallback = filterCallback;
    this.updateFilter();
};

og.gmx.VectorLayer.prototype.removeFilter = function () {
    this._filterCallback = null;
    this.updateFilter();
};

og.gmx.VectorLayer.prototype.getItemVisibility = function (item) {
    if (!this._filterCallback) {
        return true;
    }
    var visibility = this._filteredItems[item.id];
    if (visibility == null) {
        visibility = this._filteredItems[item.id] = this._filterCallback[item.id](item);
    }
    return visibility;
};

og.gmx.VectorLayer.prototype.updateFilter = function () {
    this._filteredItems = {};
    //...TODO
};

og.gmx.VectorLayer.prototype.setStyleHook = function (styleCallback) {
    this._styleCallback = styleCallback;
    this.updateStyle();
};

og.gmx.VectorLayer.prototype.getItemStyle = function (item) {
    if (!this._styleCallback) {
        return item._style;
    }
    var style = this._styledItems[item.id];
    if (style == null) {
        style = this._styledItems[item.id] = this._styleCallback[item.id](item);
    }
    return style;
};

og.gmx.VectorLayer.prototype.updateStyle = function () {
    this._styledItems = {};
    //...TODO
};

og.gmx.VectorLayer.__requestsCounter = 0;
og.gmx.VectorLayer.MAX_REQUESTS = 50;

og.gmx.VectorLayer.prototype._getTile = function (t) {
    if (og.gmx.VectorLayer.__requestsCounter >= og.gmx.VectorLayer.MAX_REQUESTS && this._counter) {
        this._pendingsQueue.push(t);
    } else {
        this._exec(t);
    }
};

og.gmx.VectorLayer.prototype._exec = function (t) {

    var url = og.utils.stringTemplate(this._tileSenderUrlTemplate, t);

    og.gmx.VectorLayer.__requestsCounter++;
    this._counter++;

    var that = this;
    var r = og.ajax.request(url, {
        'type': "GET",
        'responseType': "text",
        'success': function (dataStr) {
            og.gmx.VectorLayer.__requestsCounter--;
            that._counter--;

            var data = JSON.parse(dataStr.substring(dataStr.indexOf('{'), dataStr.lastIndexOf('}') + 1));
            that._handleTileData(t.x, t.y, t.z, t.v, data);

            var e = that.events.load;
            if (e.handlers.length) {
                that.events.dispatch(e, data);
            }

            that._dequeueRequest();
        },
        'error': function (err) {
            og.gmx.VectorLayer.__requestsCounter--;
            that._counter--;

            console.log(err);

            that._dequeueRequest();
        }
    });
};

og.gmx.VectorLayer.prototype._dequeueRequest = function () {
    if (this._pendingsQueue.length) {
        if (og.gmx.VectorLayer.__requestsCounter < og.gmx.VectorLayer.MAX_REQUESTS) {
            var t = this._whilePendings();
            if (t)
                this._exec.call(this, t);
        }
    } else if (this._counter === 0) {
        var e = this.events.loadend;
        if (e.handlers.length) {
            this.events.dispatch(e);
        }
    }
};

og.gmx.VectorLayer.prototype._whilePendings = function () {
    while (this._pendingsQueue.length) {
        return this._pendingsQueue.pop();
    }
};


og.gmx.VectorLayer.prototype.addItem = function (item) {
    if (!item._layer) {
        this._itemCache[item.id] = item;
        item._layer = this;
        if (this._planet) {
            this._planet.renderer.assignPickingColor(item);
        }
    }
};

og.gmx.VectorLayer.prototype._handleTileData = function (x, y, z, v, data) {
    var items = data.values,
        style = this._style;

    for (var i = 0; i < items.length; i++) {

        var item = items[i],
            gmxId = item[0];

        var cacheItem = this._itemCache[gmxId];

{'fraction_non_alphanumeric': 0.15166316612123285, 'fraction_numerical': 0.006398671420895814, 'mean_word_length': 2.550199410438703, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4923159', 'n_tokens_mistral': 6846, 'n_tokens_neox': 6635, 'n_words': 1198}