Страница 1 из 1

Layer.OSM избавиться от "пустых" тайлов

Добавлено: 25 окт 2012, 15:25
Tink
Здравствуйте!
Столкнулся с такой проблемой. Подключаю OSM слой, то есть растровый. Хочу сразу заметить что данные получаются со стороннего сервера на который я ни как повлиять не могу (сервер - kosmosnimki.ru). Так вот, данные в этом слое занимают примерно одну область. В результате включения видимости этого слоя я вижу что за пределами этого района тайлы не пришли, то есть сервер не отдал их вообще. Но в пределах района тайлы нормально отдаются.

Вопрос: как избавиться от "пустых" тайлов, то есть которые сервер не отдает?
Возможно можно как-то ограничить область на которую накладывается слой, что бы не видеть этих тайлов которые сервер не отдал?

Значит слой создавать так:

Код: Выделить всё

losm = new OpenLayers.Layer.OSM(
        "Слой с одной областью (Московская или Новосибирская или ещё какая - не важно)", 
        "http://maps.kosmosnimki.ru" + /*myParams*/ + "?" + /*ключи*/ + "x=${x}&y=${y}&z=${z}",
        {
            visibility: false,
            isBaseLayer: false
        }
    );
Не катит!!! :(

:idea: Аналогично коду из темы "Циклическое отображение карты OpenLayers", я сделал так:

Код: Выделить всё

OpenLayers.Layer.OSMKosmosnimki = OpenLayers.Class(OpenLayers.Layer.OSM, {
    name: "Kosmosnimki",
    url: [
        "http://maps.kosmosnimki.ru/TileService.ashx/map${mapkey}/apikey${apikey}?Request=GetTile&LayerName=${layerkey}&x=${x}&y=${y}&z=${z}"
    ],
    attribution: "<a href=\"http://kosmosnimki.ru/\">kosmosnimki.ru</a>",
    isBaseLayer: false,
    apikey: null,
    mapkey: null,
    layerkey: null,
    extent: null,
    getURL: function (bounds) {
        var res = this.getServerResolution();
        var onXYZ = !this.extent
            || (
                (
                    (this.extent.left >= bounds.left && (this.extent.right <= bounds.right || (this.extent.left <= bounds.right && this.extent.right >= bounds.right)))
                    ||
                    (this.extent.right <= bounds.right && (this.extent.left >= bounds.left || (this.extent.right >= bounds.left && this.extent.left <= bounds.left)))
                    ||
                    (this.extent.left < bounds.left && this.extent.right > bounds.right)
                )
                &&
                (
                    (this.extent.bottom >= bounds.bottom && (this.extent.top <= bounds.top || (this.extent.bottom <= bounds.top && this.extent.top >= bounds.top)))
                    ||
                    (this.extent.top <= bounds.top && (this.extent.bottom >= bounds.bottom || (this.extent.top >= bounds.bottom && this.extent.bottom <= bounds.bottom)))
                    ||
                    (this.extent.top > bounds.top && this.extent.bottom < bounds.bottom)
                )
               );
        if (onXYZ) {
            var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
            var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
            var z = this.getServerZoom();

            if (this.wrapDateLine) {
                var limit = Math.pow(2, z);
                x = ((x % limit) + limit) % limit;
            };

            var xyz = {'mapkey': this.mapkey, 'apikey': this.apikey,'layerkey': this.layerkey, 'x': x, 'y': y, 'z': z};
            var url = this.url;
            if (OpenLayers.Util.isArray(url)) {
                var s = '' + xyz.x + xyz.y + xyz.z;
                url = this.selectUrl(s, url);
            };
            return OpenLayers.String.format(url, xyz);
        } else {
            return "/images/tile404.png"
        };
    },
    CLASS_NAME: "OpenLayers.Layer.OSMKosmosnimki"
});
И все бы ничего, да некоторые растровые слои повернуты, то есть по сути прямоугольник повернут, и если взять максимумы и минимумы его координат и рассчитать по прямоугольник, то он не будет совпадать с тем что отдает сервер! Сервер отказывается отдавать пустые тайлы входящие в рассчитанный прямоугольник, но не содержащие данных!

:arrow: Отсюда делаю вывод, что мало просто запрашивать у сервера только тайлы покрывающие заданную область (а остальные заменять на заранее подготовленным полностью пустым прозрачным изображением), потому что сервер не отдает тайлы в которых нет фрагментов растра - проблема в том что они все таки попадают в прямоугольную область (minx, miny, maxx, maxy). А значит приведенного выше кода недостаточно! Он хорош тем что тайлы которые сервер заведомо не отдаст я уже не запрашиваю. :)
:idea: Думаю нужно ещё как-то обработать ошибку получения изображения... :(

Вопрос в том как отловить эту ошибку в заданном слое и заменить тайл, при запросе которого произошла ошибка, на прозрачное изображение :?: