Openlayers6 Examples学习笔记(4)

文章目录

  • turf.js
  • Custom Animation
  • Constrained Extent
  • Filtering features with WebGL
  • Marker Animation(轨迹动画)
  • Flight Animation(飞行轨迹动画)
  • geojson-vt integration
  • WMS GetFeatureInfo (Image Layer)

turf.js

Openlayers6 Examples学习笔记(4)_第1张图片

  1. fetch请求在线数据
  2. 显示turf.js与OpenLayers 集成的示例。turf.js函数along用于在街道上每200米显示一个标记。
  3. 本示例使用的lineDistance函数在高版本turf中已经不再使用,此处,直接通过script标签引入,若npm安装,需要注意版本号。
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import GeoJSON from 'ol/format/GeoJSON';
import {
  Tile as TileLayer,
  Vector as VectorLayer
} from 'ol/layer';
import {
  fromLonLat
} from 'ol/proj';
import {
  OSM,
  Vector as VectorSource
} from 'ol/source';

var source = new VectorSource();
fetch('https://openlayers.org/en/latest/examples/data/geojson/roads-seoul.geojson').then(function (response) {
  return response.json();
}).then(function (json) {
  var format = new GeoJSON();
  var features = format.readFeatures(json);
  var street = features[0];

  // convert to a turf.js feature
  var turfLine = format.writeFeatureObject(street);

  // show a marker every 200 meters
  var distance = 0.2;

  // get the line length in kilometers
  var length = turf.lineDistance(turfLine, 'kilometers');
  for (var i = 1; i <= length / distance; i++) {
    var turfPoint = turf.along(turfLine, i * distance, 'kilometers');

    // convert the generated point to a OpenLayers feature
    var marker = format.readFeature(turfPoint);
    marker.getGeometry().transform('EPSG:4326', 'EPSG:3857');
    source.addFeature(marker);
  }

  street.getGeometry().transform('EPSG:4326', 'EPSG:3857');
  source.addFeature(street);
});
var vectorLayer = new VectorLayer({
  source: source
});

var rasterLayer = new TileLayer({
  source: new OSM()
});

var map = new Map({
  layers: [rasterLayer, vectorLayer],
  target: document.getElementById('map'),
  view: new View({
    center: fromLonLat([126.980366, 37.526540]),
    zoom: 15
  })
});

turf引入的方式:

  1. 通过script标签引入
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
<script>
    var bbox = turf.bbox(features);
</script>
  1. 通过npm引入
    (1)npm安装
// 部分安装
npm install @turf/area @turf/buffer 
// 或者全部安装
npm install @turf/turf

(2)js文件引入

1 import buffer from '@turf/buffer' // 按需引用
2 import area from '@turf/area'
3 import {point, circle, bboxPolygon, booleanPointInPolygon} from '@turf/turf' // 一次引入多个
4 import * as turf from '@turf/turf' // 一次性引入

Custom Animation

Openlayers6 Examples学习笔记(4)_第2张图片

  1. 随机添加点数据
  2. 监听图层的postrender事件,并解除监听
  3. getVectorContext自定义闪烁动画
import 'ol/ol.css';
import Feature from 'ol/Feature';
import Map from 'ol/Map';
import {unByKey} from 'ol/Observable';
import View from 'ol/View';
import {easeOut} from 'ol/easing';
import Point from 'ol/geom/Point';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {fromLonLat} from 'ol/proj';
import {OSM, Vector as VectorSource} from 'ol/source';
import {Circle as CircleStyle, Stroke, Style} from 'ol/style';
import {getVectorContext} from 'ol/render';

var tileLayer = new TileLayer({
  source: new OSM({
    wrapX: false
  })
});

var map = new Map({
  layers: [tileLayer],
  target: 'map',
  view: new View({
    center: [0, 0],
    zoom: 1,
    // 如果false视图受到限制,则只能看到一个世界,并且无法平移边缘。
    // 如果true地图可能在低缩放级别显示多个世界。
    // 仅在projection全局时使用。
    multiWorld: true
  })
});

var source = new VectorSource({
  wrapX: false
});
var vector = new VectorLayer({
  source: source
});
map.addLayer(vector);
// 随机添加要素点
function addRandomFeature() {
  var x = Math.random() * 360 - 180;
  var y = Math.random() * 180 - 90;
  var geom = new Point(fromLonLat([x, y]));
  var feature = new Feature(geom);
  source.addFeature(feature);
}

var duration = 3000;
function flash(feature) {
  var start = new Date().getTime();
  var listenerKey = tileLayer.on('postrender', animate);

  function animate(event) {
    var vectorContext = getVectorContext(event);
    // 当前渲染帧状态
    var frameState = event.frameState;
    // 克隆闪烁几何要素
    var flashGeom = feature.getGeometry().clone();
    var elapsed = frameState.time - start;
    // console.log(elapsed);
    
    var elapsedRatio = elapsed / duration;
    // radius will be 5 at start and 30 at end.
    // easeOut快速启动,然后慢下来
    var radius = easeOut(elapsedRatio) * 25 + 5;
    var opacity = easeOut(1 - elapsedRatio);

    var style = new Style({
      image: new CircleStyle({
        radius: radius,
        stroke: new Stroke({
          color: 'rgba(255, 0, 0, ' + opacity + ')',
          width: 0.25 + opacity
        })
      })
    });

    vectorContext.setStyle(style);
    vectorContext.drawGeometry(flashGeom);
    if (elapsed > duration) {
      // 解除事件监听
      unByKey(listenerKey);
      return;
    }
    // tell OpenLayers to continue postrender animation
    map.render();
  }
}

// 监听添加要素事件
source.on('addfeature', function(e) {
  flash(e.feature);
});

window.setInterval(addRandomFeature, 1000);

Constrained Extent

通过extent属性设置地图的显示范围。

import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import {defaults as defaultControls} from 'ol/control';
import ZoomSlider from 'ol/control/ZoomSlider';

var view = new View({
  center: [328627.563458, 5921296.662223],
  zoom: 8,
  extent: [-572513.341856, 5211017.966314,
    916327.095083, 6636950.728974]
});

new Map({
  layers: [
    new TileLayer({
      source: new OSM()
    })
  ],
  keyboardEventTarget: document,
  target: 'map',
  view: view,
  controls: defaultControls().extend([new ZoomSlider()])
});

Filtering features with WebGL

Openlayers6 Examples学习笔记(4)_第3张图片
案例链接

Marker Animation(轨迹动画)


案例链接

Flight Animation(飞行轨迹动画)

Openlayers6 Examples学习笔记(4)_第4张图片
案例链接

geojson-vt integration

Openlayers6 Examples学习笔记(4)_第5张图片
案例链接
geojson-vt — GeoJSON矢量切片
一个高效的JavaScript库,用于将GeoJSON数据实时切片为矢量切片,主要用于在浏览器端(无需服务器)实现渲染和与大型地理空间数据集交互。

旨在在Mapbox GL JS中增强 GeoJSON的功能,但在其他可视化平台(例如Leaflet,OpenLayers和d3)以及Node.js服务器应用程序中也很有用。

生成的图块符合矢量图块规范的JSON等效项。为了使数据渲染和交互快速进行,简化了图块,保留了适合每个缩放级别的最小细节级别(简化形状,滤除微小的多边形和折线)。

WMS GetFeatureInfo (Image Layer)

Openlayers6 Examples学习笔记(4)_第6张图片
鼠标点击获取当前位置图层的属性信息

import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import ImageLayer from 'ol/layer/Image';
import ImageWMS from 'ol/source/ImageWMS';

// WMS数据源
var wmsSource = new ImageWMS({
  url: 'https://ahocevar.com/geoserver/wms',
  params: {'LAYERS': 'ne:ne'},
  serverType: 'geoserver',
  // 跨域设置
  crossOrigin: 'anonymous'
});
// WMS图层
var wmsLayer = new ImageLayer({
  source: wmsSource
});

var view = new View({
  center: [0, 0],
  zoom: 1
});

var map = new Map({
  layers: [wmsLayer],
  target: 'map',
  view: view
});

map.on('singleclick', function(evt) {
  document.getElementById('info').innerHTML = '';
  var viewResolution = /** @type {number} */ (view.getResolution());
  // 获取要素信息的url
  // 以text/html的形式返回数据
  var url = wmsSource.getFeatureInfoUrl(
    evt.coordinate, viewResolution, 'EPSG:3857',
    {'INFO_FORMAT': 'text/html'});
  if (url) {
    fetch(url)
      .then(function (response) { return response.text(); })
      .then(function (html) {
        document.getElementById('info').innerHTML = html;
      });
  }
});

map.on('pointermove', function(evt) {
  if (evt.dragging) {
    return;
  }
  var pixel = map.getEventPixel(evt.originalEvent);
  // 遍历图层判断鼠标当前位置是否存在图层
  var hit = map.forEachLayerAtPixel(pixel, function() {
    return true;
  });
  // 如果存在,则改变鼠标样式
  map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});

你可能感兴趣的:(WebGIS)