OpenLayers 知识总结2

OpenLayers 是一个强大的开源 JavaScript 库,用于在网页上显示地图和地理数据。它支持多种地图源(如瓦片地图、矢量地图等),并且提供了丰富的 API 来操作地图、绘制要素、添加交互等。

一、点要素绘制

 1.基本概念

 点要素是地图上最基本的要素之一,通常用于标记某个特定的位置。OpenLayers 提供了 Feature 和 Point 类来创建和显示点要素。

import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Style from 'ol/style/Style';
import Icon from 'ol/style/Icon';

// 创建地图实例
const map = new Map({
  target: 'map', // 地图容器的ID
  view: new View({
    center: [114.25, 30.59], // 地图中心点坐标
    zoom: 6, // 初始缩放级别
    projection: 'EPSG:4326', // 坐标系
  }),
  layers: [
    // 添加瓦片图层
    new TileLayer({
      source: new XYZ({
        url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
      }),
    }),
  ],
});

// 创建一个点要素
const pointFeature = new Feature({
  geometry: new Point([114.25, 30.59]), // 点的坐标
});

// 设置点要素的样式
pointFeature.setStyle(
  new Style({
    image: new Icon({
      src: 'icon.png', // 图标路径
      scale: 0.5, // 图标缩放比例
    }),
  })
);

// 创建矢量数据源,并将点要素添加到数据源中
const vectorSource = new VectorSource({
  features: [pointFeature],
});

// 创建矢量图层,并将数据源添加到图层中
const vectorLayer = new VectorLayer({
  source: vectorSource,
});

// 将矢量图层添加到地图中
map.addLayer(vectorLayer);

2.拓展

  • 自定义图标:可以使用 ol/style/Icon 来加载自定义图标。通过Style类的各种属性来自定义点要素的样式,如Icon样式可用于设置自定义图标。例如:

iconFeature.setStyle(
  new Style({
    image: new Icon({
      anchor: [0.5, 1],
      src: 'your-icon-url.png'
    })
  })
);
  • 动态添加点:可以通过监听地图的点击事件,动态添加点要素。

 二、线要素绘制

 1.基本概念

 线要素用于表示地图上的路径或边界。OpenLayers 提供了 LineString 类来创建线要素。线要素用于连接多个点,形成线段。通过定义LineString几何形状来确定线的路径。

import LineString from 'ol/geom/LineString';
import Stroke from 'ol/style/Stroke';

// 创建一个线要素
const lineFeature = new Feature({
  geometry: new LineString([
    [114.25, 30.59], // 起点坐标
    [116.46, 39.92], // 终点坐标
  ]),
});

// 设置线要素的样式
lineFeature.setStyle(
  new Style({
    stroke: new Stroke({
      color: 'red', // 线的颜色
      width: 2, // 线的宽度
    }),
  })
);

// 创建矢量数据源,并将线要素添加到数据源中
const vectorSource = new VectorSource({
  features: [lineFeature],
});

// 创建矢量图层,并将数据源添加到图层中
const vectorLayer = new VectorLayer({
  source: vectorSource,
});

// 将矢量图层添加到地图中
map.addLayer(vectorLayer);

2.拓展

  • 动态绘制线:可以通过监听地图的点击事件,动态绘制线要素。

  • 样式自定义:可以通过 Stroke 类自定义线的颜色、宽度等样式。

 Stroke样式类有更多属性可用于定制线的外观,如dash属性用于设置虚线样式。例如:

lineFeature.setStyle(
  new Style({
    stroke: new Stroke({
      color: "red",
      width: 8,
      dash: [10, 5] // 虚线样式,10像素线段,5像素间隔
    })
  })
);

 3.自由绘图(Freehand Drawing)

 功能:允许用户自由绘制线条。

 代码示例

draw = new Draw({
  type: "LineString",
  source: drawLayer.getSource(),
  freehand: true, // 启用自由绘制模式
});
  • 参数 freehand:值为 true 时禁用吸附,允许任意路径绘制。

 三、面要素绘制

1.基本概念

 面要素用于表示地图上的区域,如国家、城市等。OpenLayers 提供了 Polygon 类来创建面要素。

import Polygon from 'ol/geom/Polygon';
import Fill from 'ol/style/Fill';

// 创建一个面要素
const polygonFeature = new Feature({
  geometry: new Polygon([
    [
      [114.25, 30.59], // 顶点1
      [116.46, 30.59], // 顶点2
      [116.46, 39.92], // 顶点3
      [114.25, 39.92], // 顶点4
      [114.25, 30.59], // 闭合
    ],
  ]),
});

// 设置面要素的样式
polygonFeature.setStyle(
  new Style({
    fill: new Fill({
      color: 'rgba(255, 0, 0, 0.6)', // 填充颜色
    }),
    stroke: new Stroke({
      color: 'green', // 边框颜色
      width: 2, // 边框宽度
    }),
  })
);

// 创建矢量数据源,并将面要素添加到数据源中
const vectorSource = new VectorSource({
  features: [polygonFeature],
});

// 创建矢量图层,并将数据源添加到图层中
const vectorLayer = new VectorLayer({
  source: vectorSource,
});

// 将矢量图层添加到地图中
map.addLayer(vectorLayer);

2.拓展

 通过定义CirclePolygon等几何形状来确定面的范围

// 绘制圆形面要素
const circleFeature = new Feature({
  geometry: new Circle([114.25, 30.59], 1),
});
circleFeature.setStyle(
  new Style({
    fill: new Fill({
      color: "yellow",
    }),
  })
);
const vectorSource = new VectorSource({
  features: [circleFeature],
});
const vectorLayer = new VectorLayer({
  source: vectorSource,
});
map.addLayer(vectorLayer);

 四、Overlay

1.基本概念

 Overlay 用于在地图上显示额外的内容,如图片、HTML 元素等。它通常用于显示弹出窗口、标记等。

import Overlay from 'ol/Overlay';

// 创建一个 DOM 元素作为 Overlay 的内容
const dom = document.createElement('div');
dom.innerHTML = '<p>北京</p>'; // Overlay 的内容
dom.style.backgroundColor = 'white'; // 背景颜色
dom.style.padding = '5px'; // 内边距

// 创建 Overlay 实例
const overlay = new Overlay({
  element: dom, // Overlay 的内容
  position: [116.4075, 39.9042], // Overlay 的位置
  positioning: 'center-center', // 定位方式
});

// 将 Overlay 添加到地图中
map.addOverlay(overlay);
const dom = document.createElement("img");
dom.src = "/icon.png";
dom.onload = function () {
  const overlay = new Overlay({
    element: dom,
    position: [114.25, 30.59],
    positioning: "center-center",
  });
  map.addOverlay(overlay);
};

2.拓展

  • 动态更新 Overlay:可以通过 setPosition 方法动态更新 Overlay 的位置。

  • HTML 内容:可以在 Overlay 中添加复杂的 HTML 内容。

  • Overlaypositioning属性有多种取值,可根据需求调整 DOM 元素在地图上的位置。例如:

const overlay = new Overlay({
  element: dom,
  position: [114.25, 30.59],
  positioning: "top-left" // 将图片定位在地图坐标点的左上角
});

 五、Select 交互

 1.基本概念

Select 交互允许用户选择地图上的要素。可以通过点击或悬停来选择要素,通过设置conditionfilter来控制选择条件。 

import Select from 'ol/interaction/Select';
import { pointerMove } from 'ol/events/condition';

// 创建 Select 交互实例
const select = new Select({
  condition: pointerMove, // 触发条件:鼠标悬停
});

// 将 Select 交互添加到地图中
map.addInteraction(select);

// 监听 Select 交互的选中事件
select.on('select', function (e) {
  const selectedFeature = e.selected[0]; // 获取选中的要素
  if (selectedFeature) {
    // 设置选中要素的样式
    selectedFeature.setStyle(
      new Style({
        fill: new Fill({
          color: 'rgba(0, 255, 0, 0.6)', // 填充颜色
        }),
      })
    );
  }
});
const select = new Select({
  condition: pointerMove,
  filter: function (feature, layer) {
    return layer === vectorLayer;
  },
});
map.addInteraction(select);
select.on("select", function (e) {
  const f = e.selected[0];
  f.setStyle(
    new Style({
      fill: new Fill({
        color: "rgba(0, 255, 0, 0.6)",
      }),
    })
  );
});

2.拓展

可以通过Selectmulti属性来设置是否支持多选,默认false

  • 多选:可以通过配置 multi: true 来支持多选。

  • 自定义样式:可以为选中的要素设置自定义样式。

const select = new Select({
  condition: pointerMove,
  filter: function (feature, layer) {
    return layer === vectorLayer;
  },
  multi: true // 支持多选
});

六、Draw 绘图

 1.基本概念

Draw交互允许用户在地图上绘制几何图形,如点、线、面等,通过设置type属性确定绘制类型。 

import Draw from 'ol/interaction/Draw';

// 创建 Draw 交互实例
const draw = new Draw({
  type: 'LineString', // 绘制类型:线
  source: vectorSource, // 绘制的要素将添加到该数据源中
});

// 将 Draw 交互添加到地图中
map.addInteraction(draw);

// 监听 Draw 交互的绘制结束事件
draw.on('drawend', function (e) {
  const feature = e.feature; // 获取绘制的要素
  // 设置绘制要素的样式
  feature.setStyle(
    new Style({
      stroke: new Stroke({
        color: 'blue', // 线的颜色
        width: 3, // 线的宽度
      }),
    })
  );
});

 2.拓展

  • 动态绘制:用户可以在地图上动态绘制几何对象。

  • 事件监听:可以通过监听 drawstartdrawend 事件实现绘制前后的逻辑。

七、聚合图层 Cluster

1. 概念与作用

 聚合图层Cluster是 OpenLayers 中的一个功能,用于将多个距离较近的要素合并为一个聚合要素进行显示。在处理大量密集分布的点要素时,若每个要素都单独显示,会使地图显得杂乱无章,影响加载性能和用户体验。通过Cluster聚合,可以将距离在指定范围内的要素合并,以一个聚合点的形式呈现,提高地图的可读性和性能。

 2.使用方法

 创建聚合数据源

首先需要创建一个普通的矢量数据源(如VectorSource),用于存储原始的要素。然后将该数据源作为参数传入Cluster构造函数,同时指定聚合的距离阈值。例如: 

import Cluster from 'ol/source/Cluster.js'

const iconSource = new VectorSource({
  features: []
});
const iconClusterSource = new Cluster({
  distance: 100,
  source: iconSource
});

应用于图层

 创建VectorLayer图层时,将聚合数据源iconClusterSource作为其数据源。这样,图层就会显示聚合后的要素。

const iconLayer = new VectorLayer({
  source: iconClusterSource,
  // 样式处理
  style: function(features) {
    let length = features.get('features').length;
    let style = new Style();
    if (length === 1) {
      // 未聚合,显示单个要素图标
      style.setImage(
        new Icon({
          src: features.get('features')[0].get('icon')
        })
      );
    } else {
      // 聚合,显示聚合圆和数量
      style.setImage(
        new CircleStyle({
          radius: 15,
          stroke: new Stroke({
            color: '#fff'
          }),
          fill: new Fill({
            color: 'skyblue'
          })
        })
      );
      style.setText(
        new Text({
          text: length.toString(),
          fill: new Fill({
            color: '#fff'
          })
        })
      );
    }
    return style;
  }
});

3.拓展

  • 参数 distance:控制聚合的敏感度,值越小越容易聚合。

  • 动态样式:通过 style 函数根据聚合状态切换图标和文本。

 八、getFeaturesAtPixel

 1.概念与作用

 getFeaturesAtPixel是 OpenLayers 地图实例的一个方法,用于获取地图上指定像素位置的要素。在实现地图交互功能,如点击地图获取要素信息、判断点击位置是否在某个要素上时,该方法非常有用。通过它可以获取到鼠标点击或其他操作位置对应的地图要素,进而进行后续的处理,如显示要素详情、进行要素选择等操作。

2. 使用方法

 在地图的事件监听函数中调用getFeaturesAtPixel方法,传入事件中的像素位置参数。例如,在地图的click事件监听函数中:

map.on('click', function(e) {
  const pixel = e.pixel;
  const features = map.getFeaturesAtPixel(pixel);
  if (features.length > 0 && features[0].get('name')) {
    const center = features[0].get('center');
    const name = features[0].get('name');
    // 创建并显示popup
    popup = new Overlay({
      element: document.getElementById('popup')
    });
    popup.setPosition(center);
    popupContent.value = `
      <p>当前城市是: ${name}</p>
      <p>经度: ${center[0]}</p>
      <p>纬度: ${center[1]}</p>
    `;
    map.addOverlay(popup);
  } else {
    if (popup) {
      popup.setPosition(undefined);
    }
  }
});

在上述代码中,当点击地图时,获取点击位置的像素pixel,然后使用map.getFeaturesAtPixel(pixel)获取该像素位置的要素数组features。如果要素数组不为空且要素包含name属性,说明点击到了包含城市信息的要素,进而获取要素的名称和中心坐标,用于显示城市信息弹窗。若未点击到符合条件的要素,则隐藏已显示的弹窗。

 九、forEachFeatureAtPixel

 1.功能

遍历指定像素位置的所有要素,并对每个要素执行指定的回调函数。这和 getFeaturesAtPixel 获取要素数组不同,它更侧重于对每个要素做处理。 

2.使用示例

map.forEachFeatureAtPixel(pixel, function(feature, layer) {
    // 对每个要素进行处理
    console.log('要素ID:', feature.getId());
    console.log('所属图层:', layer.get('name'));
    return false; // 如果返回true,则停止遍历
});
  • 与 getFeaturesAtPixel 对比getFeaturesAtPixel 是获取像素位置的要素数组,而 forEachFeatureAtPixel 是对这些要素逐个执行回调函数,前者适用于获取要素列表做后续统一处理,后者适合对每个要素分别操作。

 十、getFeaturesInExtent

1.功能 

 获取指定范围(Extent)内的所有要素。Extent 是一个表示地图范围的数组 [minX, minY, maxX, maxY]

 2.使用示例

const extent = [minX, minY, maxX, maxY];
const features = source.getFeaturesInExtent(extent);
features.forEach(function(feature) {
    console.log('范围内要素:', feature);
});

getFeaturesInExtent 针对一个矩形范围,当你需要获取某个区域内的要素时,使用 getFeaturesInExtent 更合适。

 十一、getFeatures

1. 功能

 获取数据源中的所有要素。这个方法不依赖像素位置或范围,直接从数据源获取全部要素集合。

 2.使用示例

const source = new VectorSource();
// 假设已经向source中添加了要素
const allFeatures = source.getFeatures();
allFeatures.forEach(function(feature) {
    console.log('数据源中的要素:', feature);
});

 getFeatures 是获取数据源中的全部要素,使用场景上,当你需要处理整个数据源的要素时使用 getFeatures

 十二、hitTolerance 参数

 1.功能

 在使用 getFeaturesAtPixelforEachFeatureAtPixel 等方法时,可以通过 hitTolerance 参数来扩大或缩小要素检测的范围。该参数指定了以像素为单位的容差范围。

2.使用示例

const pixel = [x, y];
const hitTolerance = 5; // 容差为5像素
const features = map.getFeaturesAtPixel(pixel, { hitTolerance: hitTolerance });

 hitTolerance 是对 getFeaturesAtPixel 等方法的一个补充,它可以让检测要素的范围更灵活,避免因鼠标点击位置的细微偏差而无法选中要素。

 十三、 OpenLayers 里的change事件

1.change:resolution 事件概述

1). 事件触发条件

 当 OpenLayers 地图视图的分辨率发生变化时,会触发 change:resolution 事件。分辨率的变化通常是由于用户进行地图缩放操作(如使用鼠标滚轮缩放、点击缩放按钮等)引起的。

 2).事件监听方式

 可以通过监听地图视图的 change:resolution 事件来执行特定的操作。例如:

map.getView().on('change:resolution', function () {
    // 在这里编写分辨率变化时要执行的代码
});

 3). 分辨率与缩放级别

  • 分辨率和缩放级别的关系:在 OpenLayers 中,分辨率和缩放级别是紧密相关的。分辨率表示地图上一个像素所代表的实际地理距离,而缩放级别则是对地图缩放程度的一种抽象表示。一般来说,缩放级别越高,分辨率越低(即一个像素代表的实际距离越小),地图显示越详细;缩放级别越低,分辨率越高,地图显示越宏观。
  • 获取分辨率和缩放级别:可以通过地图视图的方法来获取当前的分辨率和缩放级别。例如:
const view = map.getView();
const resolution = view.getResolution(); // 获取当前分辨率
const zoom = view.getZoom(); // 获取当前缩放级别

 4). change:resolution 事件的应用场景

  • 图层显示控制:根据不同的分辨率(或缩放级别)来控制地图图层的显示与隐藏。例如,当缩放级别大于 10 时,隐藏 cityLayer 和 drawLayer;当缩放级别小于等于 10 时,显示这两个图层。
map.getView().on('change:resolution', function () {
    const zoom = this.getZoom();
    if (zoom > 10) {
        cityLayer.setVisible(false);
        drawLayer.setVisible(false);
    } else {
        cityLayer.setVisible(true);
        drawLayer.setVisible(true);
    }
});
  • 样式调整:根据分辨率的变化调整地图要素的样式。例如,在不同的缩放级别下,显示不同大小或样式的图标。
  • 数据加载与卸载:根据分辨率的变化动态加载或卸载地图数据。例如,在高缩放级别下加载更详细的数据,在低缩放级别下卸载部分数据以提高性能。

5). 相关的 OpenLayers 方法和属性

  • getResolution():用于获取地图视图当前的分辨率。
  • getZoom():用于获取地图视图当前的缩放级别。
  • setResolution():用于设置地图视图的分辨率。
  • setZoom():用于设置地图视图的缩放级别。
  • on():用于监听地图视图的事件,如 change:resolution 事件。
  • un():用于取消对地图视图事件的监听。

 6). 注意事项

  • 性能考虑:在 change:resolution 事件处理函数中执行的操作应尽量简洁高效,避免执行过于复杂或耗时的操作,以免影响地图的响应性能。
  • 事件绑定与解绑:如果在某些情况下需要动态绑定或解绑 change:resolution 事件,应注意使用 on() 和 un() 方法进行正确的操作,避免内存泄漏或不必要的事件触发。

2.change (BaseEvent)

  • 事件描述:它属于通用的变更事件。当对象的修订计数器增加时,就会触发此事件。修订计数器可用于追踪对象的状态变更,每一次对象的关键属性或状态改变,计数器就会增加。
  • 应用场景:在需要对对象状态进行统一监控时,可使用该事件。比如,当需要知晓地图的某个组件状态是否发生变化,不管具体是哪些属性改变,只要状态改变就触发相应操作,就可以监听这个事件。
  • 示例代码
const map = new Map({
    // 地图配置
});
map.on('change', function(event) {
    console.log('地图状态已变更', event);
});

3.change:center (ObjectEvent)

  • 事件描述:当地图视图的中心点发生改变时,此事件会被触发。地图中心点的改变通常是因为用户拖动地图、调用 setCenter 方法或者其他引起地图中心位置移动的操作。
  • 应用场景:适合在需要根据地图中心点变化做出响应的场景中使用。例如,根据新的中心点位置加载周边的数据,或者更新与地图中心相关的信息展示。
  • 示例代码
const view = map.getView();
view.on('change:center', function(event) {
    const newCenter = event.target.getCenter();
    console.log('地图中心点已变更为:', newCenter);
});

 4.change:rotation (ObjectEvent)

  • 事件描述:当地图视图的旋转角度发生变化时,该事件会被触发。地图的旋转操作可以通过特定的交互方式或调用 setRotation 方法来实现。
  • 应用场景:在需要根据地图旋转角度进行相应处理的场景中使用。例如,当地图旋转时,更新某些元素的显示方向,或者重新计算与地图方向相关的数据。
  • 示例代码
const view = map.getView();
view.on('change:rotation', function(event) {
    const newRotation = event.target.getRotation();
    console.log('地图旋转角度已变更为:', newRotation);
});

5.error (BaseEvent)

  • 事件描述:这是一个通用的错误事件。当发生错误时,例如数据加载失败、网络请求出错等,就会触发该事件。
  • 应用场景:用于捕获和处理地图操作过程中出现的各种错误。可以在事件处理函数中进行错误提示、记录日志或者采取其他错误恢复措施。
  • 示例代码
const layer = new TileLayer({
    source: new XYZ({
        url: 'your_tile_url'
    })
});
layer.on('error', function(event) {
    console.error('图层加载出错:', event);
});

6.propertychange (ObjectEvent)

  • 事件描述:当对象的某个属性发生变化时,会触发该事件。它可以用于监控对象属性的动态变化,无论属性是通过何种方式被修改的。
  • 应用场景:适用于需要对对象属性变化进行精细监控的场景。例如,当某个地图组件的特定属性改变时,执行相应的更新操作。
  • 示例代码
const map = new Map({
    // 地图配置
});
map.on('propertychange', function(event) {
    const property = event.key;
    const oldValue = event.oldValue;
    const newValue = event.target.get(property);
    console.log(`地图属性 ${property} 从 ${oldValue} 变更为 ${newValue}`);
});

 十四、地图动画(View Animation)

 1. 基本概念

 地图动画通过在一定时间内逐渐改变地图视图的属性值,实现平滑的过渡效果。常见的动画操作包括平移地图到指定位置、缩放地图到特定级别以及旋转地图到某个角度。

 2. 实现方法

 OpenLayers 中主要通过View对象的animate方法来创建和执行地图动画。animate方法接受一个或多个动画选项对象作为参数,每个选项对象定义了动画的目标属性和动画的持续时间等参数。

 3. 常见动画类型及示例代码

 3.1 平移地图到指定位置

import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';

// 创建地图实例
const map = new Map({
  target: 'map',
  view: new View({
    projection: 'EPSG:4326',
    center: [0, 0],
    zoom: 2
  }),
  layers: [
    new TileLayer({
      source: new XYZ({
        url: 'http://tile.openstreetmap.org/{z}/{x}/{y}.png'
      })
    })
  ]
});

// 定义目标中心位置
const targetCenter = [114.25, 30.59];

// 执行平移动画
map.getView().animate({
  center: targetCenter,
  duration: 2000 // 动画持续时间,单位为毫秒
});

 在上述代码中,通过animate方法将地图视图的中心位置从当前位置平滑地移动到targetCenter,动画持续时间为 2 秒。

 3.2 缩放地图到指定级别

// 定义目标缩放级别
const targetZoom = 8;

// 执行缩放动画
map.getView().animate({
  zoom: targetZoom,
  duration: 1500 // 动画持续时间,单位为毫秒
});

 此代码将地图视图的缩放级别从当前级别平滑地过渡到targetZoom,动画持续时间为 1.5 秒。

 3.3 旋转地图到指定角度

// 定义目标旋转角度(弧度)
const targetRotation = Math.PI / 4;

// 执行旋转动画
map.getView().animate({
  rotation: targetRotation,
  duration: 1000 // 动画持续时间,单位为毫秒
});

 这段代码将地图视图从当前旋转角度平滑地旋转到targetRotation,动画持续时间为 1 秒。

 4. 组合动画

 animate方法还可以接受多个动画选项对象作为参数,从而实现多个动画效果的组合。例如,同时平移和缩放地图:

// 定义目标中心位置和缩放级别
const targetCenter = [114.25, 30.59];
const targetZoom = 8;

// 执行组合动画
map.getView().animate([
  {
    center: targetCenter,
    duration: 2000
  },
  {
    zoom: targetZoom,
    duration: 1500
  }
]);

 5. 动画完成回调

 animate方法可以接受一个回调函数作为第二个参数,该回调函数会在动画完成后执行。例如:

map.getView().animate(
  {
    center: targetCenter,
    duration: 2000
  },
  function () {
    console.log('动画已完成');
  }
);

十五、 要素交互与事件处理

1.功能

通过点击事件获取要素信息并显示弹窗。
代码示例

map.on("click", function (e) {
  const pixel = e.pixel;
  const features = map.getFeaturesAtPixel(pixel); // 获取点击位置的要素
  if (features.length > 0 && features[0].get("name")) {
    const center = features[0].get("center");
    const name = features[0].get("name");
    // 创建弹窗 Overlay
    popup = new Overlay({ element: document.getElementById("popup") });
    popup.setPosition(center);
    popupContent.value = `当前城市: ${name}<br>经度: ${center[0]}<br>纬度: ${center[1]}`;
    map.addOverlay(popup);
  } else {
    popup.setPosition(undefined); // 隐藏弹窗
  }
});

2.拓展

  • getFeaturesAtPixel:精确获取点击位置的要素。

  • 动态弹窗:结合 Overlay 显示实时数据。

十六、外部 API 集成

1. 功能

调用高德地图 API 获取城市编码和地理坐标。
代码示例

// 获取当前城市信息
const temp = await fetch(`https://restapi.amap.com/v3/ip?key=${GAODEKEY}`);
const res = await temp.json();
city.value = res.city;
adcode.value = res.adcode;

// 获取城市边界数据
cityLayer = new VectorLayer({
  source: new VectorSource({
    url: `https://geo.datav.aliyun.com/areas_v3/bound/${adcode.value}.json`,
    format: new GeoJSON(),
  }),
});

2.拓展

  • 异步数据加载:结合 async/await 处理 API 请求。

  • 第三方数据源:集成高德地图和阿里云地理数据。

十七、 要素属性管理

 1.功能

通过自定义属性动态控制要素样式。

 代码示例

// 添加充电站点要素
const icon = new Feature({ geometry: new Point(coordinate) });
icon.setProperties({ icon: charge }); // 存储图标路径
iconSource.addFeature(icon);

// 在样式中读取属性
style.setImage(new Icon({ src: features.get("features")[0].get("icon") }));

2.拓展setProperties 

在 OpenLayers 里,setProperties 是一个很实用的方法,它主要用于给要素(Feature)、图层(Layer)、数据源(Source)等对象设置属性。

  • setProperties:存储任意自定义数据(如图标路径、名称等)。setProperties 方法能够批量地为对象设置属性,这些属性可以是自定义的,用来存储和管理与对象相关的额外信息。比如在地图应用中,对于一个表示城市的要素,除了其几何信息外,还可以通过 setProperties 方法为其设置城市名称、人口数量、GDP 等属性。

 1)使用方法

setProperties 方法有两种常见的使用方式,具体取决于传入的参数:

  • 传入一个对象:将一个包含键值对的对象作为参数传入 setProperties 方法,对象的键表示属性名,值表示属性值。这样可以一次性设置多个属性。
object.setProperties({
    property1: value1,
    property2: value2,
    // 可以添加更多的属性
});
  • 传入键值对和一个布尔值:依次传入属性名、属性值和一个布尔值(可选,默认为 true)。布尔值用于指定是否触发属性更改事件。
object.setProperties('propertyName', 'propertyValue', true);

2)示例

为要素设置属性 

import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';

// 创建一个点要素
const pointFeature = new Feature({
    geometry: new Point([114.25, 30.59])
});

// 使用 setProperties 方法设置多个属性
pointFeature.setProperties({
    cityName: '武汉',
    population: 12000000,
    isCapital: true
});

// 获取属性值
const cityName = pointFeature.get('cityName');
console.log('城市名称:', cityName); 

 在这个例子中,我们创建了一个点要素 pointFeature,然后使用 setProperties 方法为其设置了城市名称、人口数量和是否为省会城市等属性。最后,通过 get 方法获取了城市名称属性的值。

3) 在地图交互中使用属性

import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';

const map = new Map({
    target: 'map',
    view: new View({
        projection: 'EPSG:4326',
        center: [114.25, 30.59],
        zoom: 6
    }),
    layers: [
        new TileLayer({
            source: new XYZ({
                url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
            })
        })
    ]
});

const pointFeature = new Feature({
    geometry: new Point([114.25, 30.59])
});
pointFeature.setProperties({
    cityName: '武汉',
    description: '一座历史文化名城'
});

// 监听地图点击事件
map.on('click', function (e) {
    const pixel = e.pixel;
    const features = map.getFeaturesAtPixel(pixel);
    if (features.length > 0) {
        const feature = features[0];
        const cityName = feature.get('cityName');
        const description = feature.get('description');
        console.log(`${cityName}: ${description}`);
    }
});

 此示例中,当用户点击地图上的要素时,会获取要素的属性信息并打印到控制台。

4)注意事项

  • 属性名的唯一性:在设置属性时,要确保属性名的唯一性,避免不同属性使用相同的名称,以免造成混淆。
  • 属性更改事件:当使用 setProperties 方法的第二个布尔参数时,若设置为 false,则不会触发属性更改事件。这在某些情况下可以避免不必要的事件处理,提高性能。但如果后续依赖属性更改事件来执行某些操作,需要谨慎使用。

十八、 图层标识与管理

 功能:通过 className 标识图层以便动态管理。
代码示例

// 添加城市边界图层时设置标识
cityLayer = new VectorLayer({ className: "city-layer" });

// 根据标识查找并移除图层
const _cityLayer = map.getLayers().getArray().filter(
layer => layer.getClassName() === "city-layer"
);

_cityLayer.forEach(layer => map.removeLayer(layer));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super毛毛穗

今天晚饭加什么?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值