1 votos

¿Utilizando el catalejo de OpenLayers 3?

Me gustaría utilizar el ejemplo del catalejo de OpenLayers 3 dentro de mi proyecto.

El problema es cuando quiero usar la selección para la capa, que estará dentro del círculo del catalejo. No consigo que funcione, no sé cómo actualizarlo en cada selección del usuario correctamente.

¿Alguien más experto puede ayudarme?

Aquí está mi chanchullo con el que funciona parcialmente: http://jsfiddle.net/dkcz/8a3pdavv/

4voto

Ant Puntos 121

Aquí hay un ejemplo que logra lo que quieres (creo): http://jsfiddle.net/tschaub/Lkgx0qaa/

He creado un mapa con tres capas, sólo la primera (llamada roads ) es visible:

var roads = new ol.layer.Tile({
  source: new ol.source.BingMaps({key: key, imagerySet: 'Road'})
});

var clipped = {
  imagery: new ol.layer.Tile({
    source: new ol.source.BingMaps({key: key, imagerySet: 'Aerial'}),
    visible: false
  }),
  labeled: new ol.layer.Tile({
    source: new ol.source.BingMaps({key: key, imagerySet: 'AerialWithLabels'}),
    visible: false
  })
};

var map = new ol.Map({
  layers: [roads, clipped.imagery, clipped.labeled],
  target: 'map',
  view: new ol.View({
    center: ol.proj.transform([-109, 46.5], 'EPSG:4326', 'EPSG:3857'),
    zoom: 6
  })
});

El imagery y labeled Las capas se van a activar/desactivar con entradas de radio. Cuando se marca una entrada de radio, la capa se hace visible (con layer.setVisible(true) ), y los oyentes se registran para precompose y postcompse eventos (con layer.on(...) ).

Además, cualquier capa elegida previamente se hará invisible (con layer.setVisible(false) ), y los oyentes no se registrarán (con layer.un(...) ).

La función que maneja este evento de cambio de radio tiene el siguiente aspecto:

var chosen;
function onRadioChange(event) {
  if (chosen) {
    chosen.un('precompose', onPreCompose);
    chosen.un('postcompose', onPostCompose);
    chosen.setVisible(false);
  }
  chosen = clipped[event.target.value];
  chosen.on('precompose', onPreCompose);
  chosen.on('postcompose', onPostCompose);
  chosen.setVisible(true);
}

Esa es realmente la esencia de la solución. El resto sigue más o menos lo que se ha alojado ejemplo de layer-spy.html .

Para completar la información, voy a volcar el resto a continuación.

// get the pixel position with every move
var mousePosition = null;
map.on('pointermove', function(event) {
  mousePosition = event.pixel
  map.render();
});

// before rendering the layer, do some clipping
function onPreCompose(event) {
  var ctx = event.context;
  var pixelRatio = event.frameState.pixelRatio;
  ctx.save();
  ctx.beginPath();
  if (mousePosition) {
    // only show a circle around the mouse
    ctx.arc(mousePosition[0] * pixelRatio, mousePosition[1] * pixelRatio,
        75 * pixelRatio, 0, 2 * Math.PI);
    ctx.lineWidth = 5 * pixelRatio;
    ctx.strokeStyle = 'rgba(0,0,0,0.5)';
    ctx.stroke();
  }
  ctx.clip();
}

// after rendering the layer, restore the canvas context
function onPostCompose(event) {
  var ctx = event.context;
  ctx.restore();
}

// listen for change events on radio inputs
var inputs = document.querySelectorAll('input[type="radio"]');
for (var i = 0, ii = inputs.length; i < ii; ++i) {
  inputs[i].addEventListener('change', onRadioChange);
}

// kick things off with the first checked radio input
onRadioChange({target: document.querySelector('input[type="radio"]:checked')});

1voto

Mike Puntos 11

He intentado todo con mis (lamentablemente limitados) conocimientos de JavaScript para establecer el clip dinámicamente en la capa seleccionada. No he conseguido guardar y restaurar todo el contexto del lienzo, ni el de la capa. He intentado desvincular el evento de la capa, sin suerte. Tampoco strUser.un(evt, func) o evt.stopPropagation() se ha resuelto. Por ello, consideré que la capa recortada era irrecuperable y se me ocurrió un truco para resolver este problema.

He creado 3 capas recortadas junto con las 3 originales, y luego las he quitado y añadido sistemáticamente según la elección del usuario.

Entrada HTML:

<select onChange="change(this.value)" id="mySelect">
    <option label="roads" value="roads" selected></option>
    <option label="imagery" value="imagery"></option>
    <option label="osm" value="osm" selected></option>

Creación de capas:

var roads = new ol.layer.Tile({
      source: new ol.source.MapQuest({layer: 'sat'})
  });
  var roads_clipped = new ol.layer.Tile({
      source: new ol.source.MapQuest({layer: 'sat'})
  });

  var imagery = new ol.layer.Tile({
      source: new ol.source.Stamen({
        layer: 'watercolor'
      })
    });
      var imagery_clipped = new ol.layer.Tile({
      source: new ol.source.Stamen({
        layer: 'watercolor'
      })
    });

  var osm = new ol.layer.Tile({
      source: new ol.source.OSM(),
      visible: true
  });
  var osm_clipped = new ol.layer.Tile({
      source: new ol.source.OSM(),
      visible: true
  });

  var map = new ol.Map({
      layers: [roads, imagery, osm_clipped],
      target: 'map',
      view: new ol.View({
          center: ol.proj.transform([-109, 46.5], 'EPSG:4326', 'EPSG:3857'),
          zoom: 6
      })
  });

Tenga en cuenta que, he añadido la versión recortada del osm en lugar de la versión normal, para inicializar el catalejo.

Eventos (posición del ratón y recorte):

  var mousePosition = null;
  $(map.getViewport()).on('mousemove', function (evt) {
      mousePosition = map.getEventPixel(evt.originalEvent);
      map.render();
  }).on('mouseout', function () {
      mousePosition = null;
      map.render();
  });

  osm_clipped.on('precompose', function(event) {
      var ctx = event.context;
      var pixelRatio = event.frameState.pixelRatio;
      ctx.save();
      ctx.beginPath();
      if (mousePosition) {
          // only show a circle around the mouse
          ctx.arc(mousePosition[0] * pixelRatio, mousePosition[1] * pixelRatio,
          radius * pixelRatio, 0, 2 * Math.PI);
          ctx.lineWidth = 5 * pixelRatio;
          ctx.strokeStyle = 'rgba(0,0,0,0.5)';
          ctx.stroke();
      }
      ctx.clip();
  });

  // after rendering the layer, restore the canvas context
  osm_clipped.on('postcompose', function(event) {
      var ctx = event.context;
      ctx.restore();
  });

  imagery_clipped.on('precompose', function(event) {
      var ctx = event.context;
      var pixelRatio = event.frameState.pixelRatio;
      ctx.save();
      ctx.beginPath();
      if (mousePosition) {
          ctx.arc(mousePosition[0] * pixelRatio, mousePosition[1] * pixelRatio,
          radius * pixelRatio, 0, 2 * Math.PI);
          ctx.lineWidth = 5 * pixelRatio;
          ctx.strokeStyle = 'rgba(0,0,0,0.5)';
          ctx.stroke();
      }
      ctx.clip();
  });

  imagery_clipped.on('postcompose', function(event) {
      var ctx = event.context;
      ctx.restore();
  });

  roads_clipped.on('precompose', function(event) {
      var ctx = event.context;
      var pixelRatio = event.frameState.pixelRatio;
      ctx.save();
      ctx.beginPath();
      if (mousePosition) {
          ctx.arc(mousePosition[0] * pixelRatio, mousePosition[1] * pixelRatio,
          radius * pixelRatio, 0, 2 * Math.PI);
          ctx.lineWidth = 5 * pixelRatio;
          ctx.strokeStyle = 'rgba(0,0,0,0.5)';
          ctx.stroke();
      }
      ctx.clip();
  });

  roads_clipped.on('postcompose', function(event) {
      var ctx = event.context;
      ctx.restore();
  });

Variable global para almacenar la última capa recortada:

var strUser = document.getElementById('mySelect').value;

Cambia de función:

function change(e) {
    map.removeLayer(eval(strUser + '_clipped'));  //remove the last added clipped layer
    map.getLayers().getArray().splice(0,0,eval(strUser));  //add the normal version of it to the bottom of the stack
    strUser = e;  //get the new selection
    map.removeLayer(eval(strUser));  //remove the normal version of the new selection
    map.addLayer(eval(strUser + '_clipped'));  //add the clipped version
};

También hay que tener en cuenta que se puede evaluar una cadena como variable con eval() , si la variable existe con el mismo nombre que la cadena. Asegúrese de que el <option> coinciden con los nombres de las variables de las capas.

Pista: uno de los principales desarrolladores de OL, @ erilem se puede encontrar en este sitio. Tal vez él puede proporcionar una solución adecuada, si usted le pide amablemente con el enlace a esta pregunta.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X