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

OpenLayers: создание векторного слоя из локального файла

Добавлено: 08 окт 2010, 08:43
Denis Rykov
Попытался локально воспроизвести http://openlayers.org/dev/examples/kml-track.html
Скачал тот же kml, подправил путь, но вектор всё равно не отображается.

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

    var mercator = new OpenLayers.Projection("EPSG:900913");
    var geographic = new OpenLayers.Projection("EPSG:4326");

    map = new OpenLayers.Map({
        div: "map-id",
        projection: mercator,
        layers: [
            new OpenLayers.Layer.OSM(),
            new OpenLayers.Layer.Vector("Aircraft Locations", {
                projection: geographic,
                strategies: [new OpenLayers.Strategy.Fixed()],
                protocol: new OpenLayers.Protocol.HTTP({
                    url: "data/kml-track.kml",
                    format: new OpenLayers.Format.KML({
                        extractTracks: true,
                        trackAttributes: ["speed"]
                    })
                }),
                styleMap: new OpenLayers.StyleMap({
                    "default": new OpenLayers.Style({
                        graphicName: "circle",
                        pointRadius: 2,
                        fillOpacity: 0.5,
                        fillColor: "#ffcc66",
                        strokeColor: "#666633",
                        strokeWidth: 1,
                    })
                })
            })
        ],
        center: new OpenLayers.LonLat(-93.2735, 44.8349).transform(geographic, mercator),
        zoom: 8
    });

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 08 окт 2010, 10:31
Denis Rykov
Вопрос более конкретный, почему такой вариант работает:

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

new OpenLayers.Layer.GML("OpenLayers KML","./data/1.kml",
             {projection: geographic,format: OpenLayers.Format.KML})
А такой нет:

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

new OpenLayers.Layer.Vector("Aircraft Locations", {
                projection: geographic,
                strategies: [new OpenLayers.Strategy.Fixed()],
                protocol: new OpenLayers.Protocol.HTTP({
                    url: "./data/1.kml",
                    format: new OpenLayers.Format.KML()
                })
            })
В документации написано, что OpenLayers.Layer.GML
Deprecated. To be removed in 3.0. Instead use OpenLayers.Layer.Vector with Protocol.HTTP and Strategy.Fixed
но почему-то такой способ не заводится.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 01 ноя 2010, 10:36
Denis Rykov
Разобрался в чем дело. Если этот скрипт скопировать на хост, с которым идёт общение по http, то все работает, а если запускать на локальной машине - нет. Можно ли впринципе заставить такой способ работать на локальной машине без web сервера? А то как сказано в документации OpenLayers. Layer.GML Deprecated, остаётся только доступ через OpenLayers.Protocol.HTTP.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 01 ноя 2010, 10:51
Mavka
1. Разговор шел, кажется, про KML?
2. Ссылки на источник были локальными - "./data/1.kml", а не на "хосте, с которым идёт общение по http".

P.S. В примере, кстати, показано то о чем я предполагал в разговоре про GeoJSON. Могли бы тогда мне указать.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 01 ноя 2010, 11:17
Denis Rykov
Mavka писал(а):1. Разговор шел, кажется, про KML?
Да, но как показано в примерах для добавления слоя KML нужно использовать OpenLayers.Layer.GML, а так как OpenLayers.Layer.GML deprecated, то я пытаюсь использовать новый способ, но локально он не работает.
Mavka писал(а):2. Ссылки на источник были локальными - "./data/1.kml", а не на "хосте, с которым идёт общение по http".
Да. Собственно в том и вопрос, можно ли как-то подключить слой, используя локальные ссылки?

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 01 ноя 2010, 12:32
Mavka
Ааа... понятно. А если так (я не проверял):

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

lay_vector = new OpenLayers.Layer.Vector("Слоя KML");
OpenLayers.Request.GET({
    url: './data/1.kml',
    success: function(e) {
        doc = e.responseText;
        parser = new OpenLayers.Format.KML();
        lay_vector.addFeatures(parser.read(doc));
    }
}); 

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 01 ноя 2010, 15:29
Denis Rykov
Воот! Это как раз о чём я справшивал. Спасибо!
А если у меня map в другой проекции нежели layer_vector, то как можно трансформировать объекты? Может как-то их можно трансформировать на-лету при выполнении addFeatures или уже после? Нашёл метод OpenLayers.Projection.transform, но кажется он работает только для точек.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 01 ноя 2010, 15:46
Mavka
Он работает с любой геометрией - Reprojecting Geometries.
И, там же, вариант с автоматикой - Reprojecting Vector Data.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 02 ноя 2010, 09:14
Denis Rykov
Как следует из материала по приведенным выше ссылкам, при добавлении объектов на карту через метод addFeatures их нужно предварительно перепроецировать, иначе, даже если будет выставлена проекция на уровне слоя - данные перепроецированы не будут. Для этого в свойствах формата определяем входную ('externalProjection') и выходную ('internalProjection') проекции:

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

var format = new OpenLayers.Format.KML({
  'internalProjection': new OpenLayers.Projection("EPSG:900913"),
  'externalProjection': new OpenLayers.Projection("EPSG:4326")
}) 
Проверено - работает.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 02 ноя 2010, 14:34
Denis Rykov
Переименовал тему.
Еще добавлю, что вместо OpenLayers.Request.GET можно использовать OpenLayers.loadURL. Пример:

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

OpenLayers.loadURL('data/1.kml', null, null, function(e){
        lay_vector.addFeatures(new OpenLayers.Format.KML({'internalProjection': rectangle,'externalProjection': geographic}).read(e.responseText));
    }); 

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 10 дек 2010, 20:33
Denis Rykov
А может кто-нибудь внятно объяснить, почему здесь в первом случае нет нужды создавать объект OpenLayers.Format.KML, а во втором мы пишем new OpenLayers.Format.KML()?

UPD. Понял, просмотрев исходники, в первом случае объект формата создаётся автоматически.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 03 фев 2011, 22:15
Denis Rykov
2Mavka

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

lay_vector = new OpenLayers.Layer.Vector("Слоя KML");
OpenLayers.Request.GET({
    url: './data/1.kml',
    success: function(e) {
        doc = e.responseText;
        parser = new OpenLayers.Format.KML();
        lay_vector.addFeatures(parser.read(doc));
    }
});
Если после этого кода выполнить map.addLayer(lay_vector), то как это будет выглядеть на карте. Ведь Request.GET выполняется асинхронно, соответственно и фичи будут добавлены только по окончании загрузки файла с данными. То есть не понятно, что будет на карте до того, как отработает success и после.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 04 фев 2011, 00:43
Mavka
Сейчас я не могу проверить код, но предполагал что слой будет пустой.
А что не так работает?

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 04 фев 2011, 07:14
Denis Rykov
То есть слой будет пустой, а при отработке addFeatures он автоматом перерисуется и объекты появятся на карте? Проблема в том, что мне нужно делать зум на слой, но если он не содержит объектов, тогда очевидно будет ошибка. Чтобы все было понятно, что к чему попытаюсь объяснить ситуацию. Есть слои, данные в которых в десятичных градусах. Часть из них изначально с отключенной видимостью. Добавляются так:

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

reg02 = new OpenLayers.Layer.GML("layer","02.geojson",defaultProperty);
Поскольку в defaultProperty есть элемент visibility:false, то слои эти изначально не только невидимые, но они и не загружены (судя по firebug OL обращается к файлу только когда включается видимость слоя). При включении слоя он подгружается и OL перепроецирует его в проекцию, указанную в объекте map. Все хорошо, но потребовалось использовать для разных слоёв разную проекцию, то есть не ту, что указана в map, а для каждого свою. Как это можно сделать? Видится как минимум такой вариант, но мне кажется могут возникнуть грабли. Перед тем как добавить слои на карту (в момент создания объекта map) создаем слои таким образом:

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

reg02 = new OpenLayers.Layer.Vector("layer",defaultProperty);
OpenLayers.loadURL('02.geojson',null,null, function(e) {02.addFeatures(format135lon.read(e.responseText))});
где format135lon - формат с нужными internalProjection и externalProjection. В этом случае не происходит автоматическое перепроецирование данных в объект map. Но проблемы видится как минимум 2, одна вытекает из другой: если таким образом у меня грузится несколько слоев, то при включении видимости одного из них я не могу гарантировать, что он уже загружен и в принципе не знаю сколько времени он будет грузится, так как параллельно с ним фоном грузятся и другие слои (хотя нам по сути этого не надо), и вторая - так как слой не загружен то я не могу вызвать метод зум ту dataExtent. Вообщем пока совсем не понятно, как поступить в такой ситуации.

Re: OpenLayers: создание векторного слоя из локального файла

Добавлено: 04 фев 2011, 13:14
Denis Rykov
Решил вопрос. Создаю слой:

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

layer = new OpenLayers.Layer.Vector("Layer",{metadata: url:'data.geojson',fo:'PFO'},visibility:false});
Затем добавляю его на карту. А прежде чем включить и сделать на него зум выполняю такую функцию:

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

function loadLayer(layer){
    if (!layer.features.length){
        if (layer.metadata.fo == 'DVFO') {
            layerProject = proj135
        }
        else if ((layer.metadata.fo == 'URFO') || (layer.metadata.fo == 'SFO')) {
            layerProject = proj105
        }
        else {
            layerProject = proj45
        }
        OpenLayers.Request.GET({
            url: layer.metadata.url,
            async: false,
            success: function(e) {
                layer.addFeatures(new OpenLayers.Format.GeoJSON({'internalProjection': layerProject,'externalProjection': geographic}).read(e.responseText))
            }
        })
    }
}