Интеграция OpenLayers 3 с Cesium Viewer

Я разрабатываю с использованием Cesium, созданного поверх Cesium.Viewer. В Cesium отсутствуют некоторые функции, поэтому я хочу интегрироваться с OpenLayers. Я хотел бы добавить существующие слои OpenLayers в Cesium.Viewer, как если бы они были «слоями изображений».

Я нашел ol3-cesium, однако это позволяет визуализировать только весь экземпляр карты OpenLayers на Cesium.Scene, который он создает для вас. Cesium.Viewer также создает экземпляр Cesium.Scene, нацеленный на данный элемент DOM.

Как добавить слои OpenLayers в Cesium.Viewer?

Некоторые фрагменты кода для иллюстрации

var olLayer1= new ol.layer.Tile({
  source: new ol.source.MapQuest({layer: 'sat'})
});
var olLayer2= new ol.layer.Vector({
  source : ol.source.Vector();
});

var map = new ol.Map({
  layers: [olLayer1, olLayer2],
  target: 'map',
  view: new ol.View({
  })
});

Существующий просмотрщик цезия

var viewer = new Cesium.Viewer('cesium-map', {});
// viewer setup code

инициализация ol3-cesium - но это не позволяет использовать существующую программу просмотра??

var ol3d = new olcs.OLCesium({map: map}); // map is the ol.Map instance

person Adam    schedule 09.07.2015    source источник


Ответы (2)


Я только что просмотрел код инициализации для OL3-Cesium, и, хотя он по сути представляет собой оболочку поверх Cesium, средства, которые они решили внедрить в среду Cesium, не будут хорошо работать, если вы хотите гибрид Cesium.Viewer и OL3. объект.

Я не уверен в вашем уровне комфорта при изменении библиотек JS, но лично я бы сделал свой собственный класс просмотра ol3 cesium. Что-то вроде этого gist я только что собрал.

Просто предупреждение, я еще не тестировал этот код. Возможно, вам придется внести некоторые дополнительные изменения, если вы получаете ошибки. Может быть причина, по которой разработчики OL3-Cesium решили не использовать виджет или средство просмотра Cesium для инициализации Cesium в своей библиотеке, но я не вижу причин, по которым это не сработало бы.

Вот конструктор, но вы бы хотели, чтобы весь Gist был отдельным файлом в вашей библиотеке ol3-cesium. Поместите его в тот же каталог, что и файл ol3Cesium.js.

отрывок из https://gist.github.com/maikuru/9e650bf88aed84982667

olcs.OLCesiumViewer = function(options) {

    /**
     * @type {!ol.Map}
     * @private
     */
    this.map_ = options.map;

    var fillArea = 'position:absolute;top:0;left:0;width:100%;height:100%;';

    /**
     * @type {!Element}
     * @private
     */
    this.container_ = goog.dom.createDom(goog.dom.TagName.DIV,
            {style: fillArea + 'visibility:hidden;'});

    var targetElement = goog.dom.getElement(options.target || null);
    if (targetElement) {
        goog.dom.appendChild(targetElement, this.container_);
    } else {
        var vp = this.map_.getViewport();
        var oc = goog.dom.getElementByClass('ol-overlaycontainer', vp);
        if (oc) {
            goog.dom.insertSiblingBefore(this.container_, oc);
        }
    }

    /**
     * Whether the Cesium container is placed over the ol map.
     * @type {boolean}
     * @private
     */
    this.isOverMap_ = !goog.isDefAndNotNull(targetElement);

    /**
     * @type {!HTMLCanvasElement}
     * @private
     */
    this.canvas_ = /** @type {!HTMLCanvasElement} */
            (goog.dom.createDom(goog.dom.TagName.CANVAS, {style: fillArea}));
    this.canvas_.oncontextmenu = function() { return false; };
    this.canvas_.onselectstart = function() { return false; };

    goog.dom.appendChild(this.container_, this.canvas_);

    /**
     * @type {boolean}
     * @private
     */
    this.enabled_ = false;

    /**
     * @type {!Array.<ol.interaction.Interaction>}
     * @private
     */
    this.pausedInteractions_ = [];

    /**
     * @type {?ol.layer.Group}
     * @private
     */
    this.hiddenRootGroup_ = null;

    /**
     * @type {!Object.<Cesium.Viewer.Options>}
     * @private
     */
    var cesiumViewerConfig_ = (options.viewer || {}).scene3DOnly = true;

    /**
     * @type {!Cesium.Viewer}
     * @private
     */
    this.viewer_ = new Cesium.Viewer(this.container_, cesiumViewerConfig_);

    /**
     * @type {!Cesium.Scene}
     * @private
     */
    this.scene_ = this.viewer_.scene;

    var sscc = this.scene_.screenSpaceCameraController;
    sscc.inertiaSpin = 0;
    sscc.ineartiaTranslate = 0;
    sscc.inertiaZoom = 0;

    sscc.tiltEventTypes.push({
        'eventType': Cesium.CameraEventType.LEFT_DRAG,
        'modifier': Cesium.KeyboardEventModifier.SHIFT
    });

    sscc.tiltEventTypes.push({
        'eventType': Cesium.CameraEventType.LEFT_DRAG,
        'modifier': Cesium.KeyboardEventModifier.ALT
    });

    sscc.enableLook = false;

    this.scene_.camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z;

    /**
     * @type {!olcs.Camera}
     * @private
     */
    this.camera_ = new olcs.Camera(this.scene_, this.map_);

    /**
     * @type {!Cesium.Globe}
     * @private
     */
    this.globe_ = this.scene_.globe;
    this.scene_.skyAtmosphere = new Cesium.SkyAtmosphere();

    var synchronizers = goog.isDef(options.createSynchronizers) ?
            options.createSynchronizers(this.map_, this.scene_) :
            [
                new olcs.RasterSynchronizer(this.map_, this.scene_),
                new olcs.VectorSynchronizer(this.map_, this.scene_)
            ];

    for (var i = synchronizers.length - 1; i >= 0; --i) {
        synchronizers[i].synchronize();
    }

    if (this.isOverMap_) {
        // if in "stacked mode", hide everything except canvas (including credits)
        var credits = goog.dom.getNextElementSibling(this.canvas_);
        if (goog.isDefAndNotNull(credits)) {
            credits.style.display = 'none';
        }
    }

    this.camera_.readFromView();

    this.cesiumRenderingDelay_ = new goog.async.AnimationDelay(function(time) {
        this.scene_.initializeFrame();
        this.handleResize_();
        this.scene_.render();
        this.enabled_ && this.camera_.checkCameraChange();
        this.cesiumRenderingDelay_.start();
    }, undefined, this);
};
person Mike LP    schedule 10.07.2015

Есть несколько внутренних классов, которые эмулируют слои, используя вызовы Cesium API. Они находятся в документации, поэтому я предполагаю "общедоступный" API.

Слои должны быть добавлены на карту и не могут использоваться изолированно. Это необходимо, так как карта определяет проекцию и т. д.

Например, VectorSynchronizer создает прослушиватели на нижележащих слоях и сохраняет сцену Cesium в синхронизировать...

new olcs.VectorSynchronizer(map, viewer.scene);
person Adam    schedule 09.07.2015