当前位置:   article > 正文

openlayers学习记录,持续更新..._openlayers学习笔记

openlayers学习笔记

一、加载地图

以加载天地图为例:

1.1 视图层

  1. <template>
  2. <div id="map" class="map_x"> </div>
  3. </template>

 1.2 逻辑层

1.2.1 引入所需对象

  1. import { Map, View } from 'ol' // 地图实例方法、视图方法
  2. import Tile from 'ol/layer/Tile' // 瓦片渲染方法
  3. import XYZ from 'ol/source/XYZ'

1.2.2 初始化地图方法

  1. const map = ref(null) // 存放地图实例
  2. //*****************************************************
  3. onMounted(() => {
  4. initMap()
  5. })
  6. /**
  7. * 初始化地图
  8. */
  9. function initMap() {
  10. // 引入天地图
  11. let source = new XYZ({
  12. url: 'http://t4.tianditu.com/DataServer?T=ter_w&tk=************************&x={x}&y={y}&l={z}',
  13. })
  14. let tileLayer = new Tile({
  15. title: '天地图',
  16. source: source,
  17. })
  18. // 标注图层(就是我们所看见的行政区名称,道路)
  19. let sourceMark = new XYZ({
  20. url: 'http://t4.tianditu.com/DataServer?T=cta_w&tk=*************************&x={x}&y={y}&l={z}',
  21. })
  22. let tileMark = new Tile({
  23. title: '标注图层',
  24. source: sourceMark,
  25. })
  26. // 地图实例
  27. map.value = new Map({
  28. target: 'map', // 对应页面里 id 为 map 的元素
  29. layers: [tileLayer, tileMark],
  30. view: new View({
  31. // 地图视图
  32. projection: 'EPSG:4326', // 坐标系,有EPSG:4326和EPSG:3857
  33. center: [118.05, 24.61], // 中心坐标
  34. zoom: 12, // 地图缩放级别(打开页面时默认级别)
  35. // minZoom: 10, // 地图缩放最小级别
  36. maxZoom: 18,
  37. }),
  38. })
  39. }

其中tk=后的参数放入天地图开发者控制台中申请的密钥即可。 

1.3 核心要素

XYZ  Tile Map View


二、显示图标 

2.1 逻辑层

2.1.1 引入所需对象

  1. import VectorSource from "ol/source/Vector";
  2. import { Vector as VectorLayer } from "ol/layer";
  3. import Feature from "ol/Feature";
  4. import Style from "ol/style/Style";
  5. import { Point } from "ol/geom";
  6. import Icon from "ol/style/Icon";

2.1.2 显示图标方法

  1. /**
  2. * 新增图标
  3. */
  4. function addIcon() {
  5. removeIcon();
  6. let vectorSource = new VectorSource();
  7. iconLayer.value = new VectorLayer({
  8. source: vectorSource,
  9. });
  10. // 添加图层
  11. map.value.addLayer(iconLayer.value);
  12. // 设置图片位置
  13. iconFeature.value = new Feature({
  14. geometry: new Point([118.05, 24.61]),
  15. });
  16. // 设置图标样式与路径
  17. iconFeature.value.setStyle(
  18. new Style({
  19. image: new Icon({
  20. src: require("@/assets/icon_powerView.svg"),
  21. anchor: [0.5, 0.5], // 设置图标位置
  22. }),
  23. })
  24. );
  25. // 设置图标与地图缩放同步缩放
  26. let style = iconFeature.value.getStyle();
  27. style.getImage().setScale(realZoom.value / 10);
  28. iconFeature.value.setStyle(style);
  29. // 将图片Feature添加到Source
  30. iconLayer.value.getSource().addFeature(iconFeature.value);
  31. }
  32. /**
  33. * 移除图标
  34. */
  35. function removeIcon() {
  36. if (iconLayer.value) {
  37. map.value.removeLayer(iconLayer.value);
  38. iconLayer.value = null;
  39. }
  40. }

其中,使用anchor对图标位置进行设置时需要注意:

默认情况下,位置坐标是按照比例的方式来设置的,范围从0到1,x轴上0表示最左边,1表示最右边,y轴上0表示最上边,1表示最下边。 如代码所示,x设置为0.5可以让图片在x方向上居中,y设置为1可以让图片在y方向上移动到最底端。

补充:当设置图标与地图缩放同步缩放时,需要提前触发地图缩放监听,方法如下 :

  1. /**
  2. * 监听缩放调整图标大小
  3. */
  4. function zoomChange() {
  5. map.value.getView().on("change:resolution", function (res) {
  6. let autoZoom = res.target.values_.zoom;
  7. realZoom.value = autoZoom;
  8. if (iconFeature.value) {
  9. let style = iconFeature.value.getStyle();
  10. style.getImage().setScale(autoZoom / 10);
  11. iconFeature.value.setStyle(style);
  12. }
  13. });
  14. }

2.2 核心要素

 VectorSource  VectorLayer  Feature  Point  Style  Icon


三、显示几何图形、Cancas图形与图形点击事件 

3.1 逻辑层 

3.1.1 引入所需对象

  1. import { VectorSourceEvent } from "ol/source/Vector";
  2. import VectorSource from "ol/source/Vector";
  3. import { Vector as VectorLayer } from "ol/layer";
  4. import Feature from "ol/Feature";
  5. import { Point, Circle as CircleGeo } from "ol/geom";
  6. import Style from "ol/style/Style";
  7. import Icon from "ol/style/Icon";
  8. import Fill from "ol/style/Fill";
  9. import Circle from "ol/style/Circle"; //注意circle引入
  10. // import { Circle } from 'ol/geom' //错误引入示例 需要注意

3.1.2 显示圆形方法

  1. /**
  2. * 画点/圈
  3. */
  4. function addPoint() {
  5. removePoint();
  6. // 画多个圆心示例
  7. let pointArr = [];
  8. for (let i = 0; i < 265; i++) {
  9. let pointF = new Feature({
  10. geometry: new Point([Number(118.05 + i / 100), Number(24.61 - i / 560)]),
  11. });
  12. // 设置特殊类型,以便在点击事件时进行过滤
  13. pointF.set("type", "circleClick");
  14. pointArr.push(pointF);
  15. }
  16. // 画单个圆示例
  17. // let pointFerture = new Feature({
  18. // geometry: new Point([118.05, 24.61]),
  19. // });
  20. let source = new VectorSource({
  21. features: pointArr, // [pointFerture],//单个圆时注意仍需要传入数组[]
  22. });
  23. pointLayer.value = new VectorLayer({
  24. source: source,
  25. style: new Style({
  26. image: new Circle({
  27. radius: 15, //圆半径
  28. fill: new Fill({
  29. color: "#765BBD", //圆填充颜色
  30. }),
  31. }),
  32. }),
  33. });
  34. map.value.addLayer(pointLayer.value);
  35. }
  36. /**
  37. * 清除点/圈
  38. */
  39. function removePoint() {
  40. if (pointLayer.value) {
  41. map.value.removeLayer(pointLayer.value);
  42. pointLayer.value = null;
  43. }
  44. }

3.1.3 点击图形事件

该节主要用于展示图形状态可动态变化,具体点击事件与其他事件的使用见 章节四 地图事件。

以点击圆形后改变大小与颜色为例:

  1. /**
  2. * 监听地图点击事件
  3. */
  4. function changePoint() {
  5. map.value.on("click", function (event) {
  6. let feature = map.value.forEachFeatureAtPixel(
  7. event.pixel,
  8. function (feature) {
  9. return feature;
  10. }
  11. );
  12. if (feature) {
  13. let json = feature.getStyle();
  14. let type = feature.get("type");
  15. let color = null;
  16. console.log("监听事件", json);
  17. // 过滤特殊类型
  18. if (type == "circleClick") {
  19. try {
  20. color = json.image_.fill_.color_;
  21. } catch {}
  22. } else {
  23. return false;
  24. }}
  25. // let color = feature.style_.image_.fill_.color_;
  26. // 点击后将切换⚪颜色
  27. feature.setStyle(
  28. new Style({
  29. image: new Circle({
  30. radius: color == "#FFF000" ? 15 : 20, //圆半径
  31. fill: new Fill({
  32. color: color == "#FFF000" ? "#765BBD" : "#FFF000", //圆填充颜色
  33. }),
  34. }),
  35. })
  36. );
  37. }
  38. });
  39. }

3.1.4 显示Canvas图形方法

  1. /**
  2. * 新增canvas图标
  3. */
  4. function addCanvas() {
  5. removeCanvas();
  6. let vectorSource = new VectorSource();
  7. canvasLayer.value = new VectorLayer({
  8. source: vectorSource,
  9. });
  10. // 使用canvas绘制一个不规则几何图形
  11. var canvas = document.createElement("canvas");
  12. canvas.width = 20;
  13. canvas.height = 20;
  14. var context = canvas.getContext("2d");
  15. context.strokeStyle = "red";
  16. context.lineWidth = 1;
  17. context.beginPath();
  18. context.moveTo(0, 0);
  19. context.lineTo(20, 10);
  20. context.lineTo(0, 20);
  21. context.lineTo(10, 10);
  22. context.lineTo(0, 0);
  23. context.fill();
  24. // 把绘制了的canvas设置到style里面
  25. canvasLayer.value.setStyle(
  26. new Style({
  27. image: new Icon({
  28. img: canvas,
  29. imageSize: [canvas.width, canvas.height],
  30. rotation: (90 * Math.PI) / 180,
  31. }),
  32. })
  33. );
  34. let shape = new Feature({
  35. geometry: new Point([118.05, 24.61]),
  36. });
  37. canvasLayer.value.getSource().addFeature(shape);
  38. map.value.addLayer(canvasLayer.value);
  39. }
  40. /**
  41. * 清楚canvas图标
  42. */
  43. function removeCanvas() {
  44. if (canvasLayer.value) {
  45. map.value.removeLayer(canvasLayer.value);
  46. canvasLayer.value = null;
  47. }
  48. }

3.1.5 显示多类型图形方法

  1. /**
  2. * 显示多类型图形
  3. */
  4. function addMultiType() {
  5. removeMultiType();
  6. let source = new VectorSource();
  7. multiTypeLayer.value = new VectorLayer({
  8. source: source,
  9. style: layerStyle,
  10. });
  11. let rect = new Feature({
  12. geometry: new Point([118.15, 24.61]),
  13. });
  14. multiTypeLayer.value.getSource().addFeature(rect);
  15. let circle = new Feature({
  16. geometry: new Point([118.25, 24.61]),
  17. });
  18. circle.set("type", "circle");
  19. multiTypeLayer.value.getSource().addFeature(circle);
  20. let point = new Feature({
  21. geometry: new Point([118.35, 24.61]),
  22. });
  23. point.set("type", "point");
  24. multiTypeLayer.value.getSource().addFeature(point);
  25. map.value.addLayer(multiTypeLayer.value);
  26. }
  27. /**
  28. * 清除多类型图形
  29. */
  30. function removeMultiType() {
  31. if (multiTypeLayer.value) {
  32. map.value.removeLayer(multiTypeLayer.value);
  33. multiTypeLayer.value = null;
  34. }
  35. }
  36. /**
  37. * 创建不同形状
  38. * @param {*} feature
  39. * @param {*} resolution
  40. */
  41. function layerStyle(feature, resolution) {
  42. let type = feature.get("type");
  43. console.log("接收类型参数", feature, type);
  44. let style = null;
  45. if (type === "point") {
  46. style = new Style({
  47. image: new Circle({
  48. radius: 20,
  49. fill: new Fill({
  50. color: "red",
  51. }),
  52. }),
  53. });
  54. } else if (type === "circle") {
  55. style = new Style({
  56. image: new Circle({
  57. radius: 20,
  58. stroke: new Stroke({
  59. color: "red",
  60. size: 1,
  61. }),
  62. }),
  63. });
  64. } else {
  65. style = new Style({
  66. image: new RegularShape({
  67. points: 5,
  68. radius: 20,
  69. fill: new Fill({
  70. color: "blue",
  71. }),
  72. }),
  73. });
  74. }
  75. return [style];
  76. }

3.2 核心要素

VectorSource  VectorLayer  Feature  Point  Style  Icon  Fill  Circle


四、常用地图事件 

4.1 点击事件

4.1.1 事件

click  点击

singleclick  单击

dblclick  双击

 注意:单击事件singleclick与双击事件dblclick均会先触发点击事件click

4.1.2 示例 

  1. function changeClick() {
  2. map.value.on("click", function (event) {
  3. console.log('click事件');
  4. })
  5. }

由于使用单击事件singleclick或双击事件dblclick均会先触发click事件,因此在同一页面存在多个点击事件时,尽量不使用click事件以免事件混淆。

4.2 地图渲染、移动事件

4.2.1事件

precompose  准备渲染

postcompose  开始渲染

postrender  完成渲染

moveend  地图移动结束

注意: 移动地图、缩放层级均会触发moveend事件,可使用map.getView().calculateExtent(map.getSize());获取屏幕左右对角坐标。

4.2.2 示例

  1. function changeMap(){
  2. map.value.on('precompose', function (event) {
  3. console.log('准备渲染');
  4. });
  5. }
  1. function changeMoveMap() {
  2. map.value.on('moveend', function (event) {
  3. // 获取当前屏幕范围坐标
  4. let extent = map.value.getView().calculateExtent(map.value.getSize());
  5. let xmin = extent[0];//左下角x
  6. let ymin = extent[1];//左下角y
  7. let xmax = extent[2];//右上角x
  8. let ymax = extent[3];//右上角y
  9. // 若需要使用相关经纬度则需要对上述坐标进行转化
  10. })
  11. }

4.3 鼠标事件

4.3.1 事件

pointermove  鼠标移动

pointerdrag  鼠标拖拽

 4.3.2 示例

  1. function changePointer(){
  2. map.value.on('pointermove', function (event) {
  3. console.log('鼠标移动');
  4. });
  5. }

4.4 属性事件

4.4.1 事件

change:size  尺寸变更

change:view  视图变更

change:target  地图容器变更

propertychange  属性变更

 注意:

        1.地图首次加载就会触发change:size和propertychange事件;

        2.change:size、change:target、change:view都会触发propertychange事件。

4.4.2 示例

  1. function changeMap(){
  2. // change:size事件
  3. map.value.on('change:size', function (event) {
  4. console.log('size事件');
  5. });
  6. // change:view事件
  7. map.value.on('change:view', function (event) {
  8. console.log('view事件');
  9. });
  10. // change:target事件
  11. map.value.on('change:target', function (event) {
  12. console.log('target事件');
  13. });
  14. // propertychange事件
  15. map.value.on('propertychange', function (event) {
  16. console.log('property事件');
  17. });
  18. }
  19. /*****************触发上述监听之事件*****************/
  20. // 更改Div
  21. function changeSize() {
  22. console.log('-----------');
  23. let div = document.getElementById('map');
  24. div.style.width = '250px';
  25. map.value.updateSize();
  26. }
  27. // 更改Target
  28. function changeTarget() {
  29. map.value.setTarget('map1');
  30. }
  31. // 更改View
  32. function changeView() {
  33. let view = new ol.View({
  34. projection: 'EPSG:4326',
  35. center: [118.05, 24.61],
  36. zoom: 5
  37. });
  38. map.value.setView(view);
  39. }

4.5 销毁监听事件

4.5.1 销毁方法

un( )

unBykey( )

4.5.2 示例

  1. /**
  2. * 监听双击事件
  3. */
  4. function clickChange() {
  5. // 双击事件方法
  6. dblclickFun.value = function (evt) {
  7. console.log("点击事件", evt);
  8. };
  9. // 开启双击事件监听
  10. map.value.on("dblclick", dblclickFun.value);
  11. }
  12. /**
  13. * 取消监听双击事件
  14. */
  15. function cancelDblclick() {
  16. map.value.un("dblclick", dblclickFun.value);
  17. }
  1. // 需要先引入unByKey方法
  2. import { unByKey } from "ol/Observable";
  3. /**
  4. * 监听双击事件
  5. */
  6. function clickChange() {
  7. // 双击事件方法
  8. dblclickFun.value = function (evt) {
  9. console.log("点击事件", evt);
  10. };
  11. // 开启方法监听
  12. dblclickListener.value = map.value.on("dblclick", dblclickFun.value);
  13. }
  14. /**
  15. * 取消监听双击事件
  16. */
  17. function cancelDblclick() {
  18. unByKey(dblclickListener.value);
  19. }

注意:

若仅需要触发一次事件,则可以使用 map.value.once("dblclick", dblclickFun.value);替换原来map.value.on("dblclick", dblclickFun.value);的开启监听方法,使用once函数,只会响应一次事件,之后自动注销事件监听。 


五、信息弹窗 

 5.1 视图层

  1. <template>
  2. <div
  3. id="map"
  4. class="map_x"
  5. ></div>
  6. <!-- 信息弹窗 -->
  7. <div
  8. id="popup"
  9. class="ol-popup"
  10. v-show="clickCoordinate!=null"
  11. >
  12. <a
  13. href="#"
  14. id="popup-closer"
  15. class="ol-popup-closer"
  16. @click="removePopup"
  17. />
  18. <div id="popup-content" />
  19. </div>
  20. </template>
  21. <style>
  22. .ol-popup {
  23. position: absolute;
  24. background-color: white;
  25. box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
  26. padding: 15px;
  27. border-radius: 10px;
  28. border: 1px solid #cccccc;
  29. bottom: 12px;
  30. left: -50px;
  31. min-width: 500px;
  32. }
  33. .ol-popup:after,
  34. .ol-popup:before {
  35. top: 100%;
  36. border: solid transparent;
  37. content: " ";
  38. height: 0;
  39. width: 0;
  40. position: absolute;
  41. pointer-events: none;
  42. }
  43. .ol-popup:after {
  44. border-top-color: white;
  45. border-width: 10px;
  46. left: 48px;
  47. margin-left: -10px;
  48. }
  49. .ol-popup:before {
  50. border-top-color: #cccccc;
  51. border-width: 11px;
  52. left: 48px;
  53. margin-left: -11px;
  54. }
  55. .ol-popup-closer {
  56. text-decoration: none;
  57. position: absolute;
  58. top: 2px;
  59. right: 8px;
  60. }
  61. .ol-popup-closer:after {
  62. content: "✖";
  63. }
  64. <style>

5.2 逻辑层

5.2.1 引入所需对象

  1. import Overlay from "ol/Overlay";
  2. import { transform } from "ol/proj";

5.2.2 双击地图显示信息窗方法

  1. /**
  2. * 创建弹出窗层
  3. * @param {*} ctn
  4. */
  5. function addPopup() {
  6. removePopup();
  7. let container = document.getElementById("popup");
  8. let content = document.getElementById("popup-content");
  9. if (overLayer.value === null) {
  10. overLayer.value = new Overlay({
  11. element: container,
  12. autoPan: true,
  13. autoPanAnimation: {
  14. duration: 250,
  15. },
  16. });
  17. map.value.addOverlay(overLayer.value);
  18. console.log("创建图层对象");
  19. }
  20. clickChange(content);
  21. }
  22. /**
  23. * 监听双击事件
  24. */
  25. function clickChange(content) {
  26. clickCoordinate.value = null;
  27. // 双击事件方法
  28. dblclickFun.value = function (evt) {
  29. // console.log("点击事件", evt);
  30. let coordinate = evt.coordinate;
  31. clickCoordinate.value = coordinate;
  32. let coordinateT = transform(coordinate, "EPSG:4326", "EPSG:3857");
  33. content.innerHTML = `
  34. <h3>信息弹窗</h3>
  35. <br/>
  36. <table>
  37. <tr>
  38. <th>信息1:</th>
  39. <td>${coordinateT}</td>
  40. </tr>
  41. <tr>
  42. <th>信息2:</th>
  43. <td>${coordinate}</td>
  44. </tr>
  45. </table>
  46. `;
  47. overLayer.value.setPosition(coordinate);
  48. };
  49. // 开启方法监听
  50. dblclickListener.value = map.value.on("dblclick", dblclickFun.value);
  51. }
  52. /**
  53. * 取消监听双击事件
  54. */
  55. function cancelDblclick() {
  56. // map.value.un("dblclick", dblclickFun.value);
  57. unByKey(dblclickListener.value);
  58. console.log("取消监听双击事件");
  59. }
  60. /**
  61. * 清除弹出层
  62. */
  63. function removePopup() {
  64. if (overLayer.value) {
  65. overLayer.value.setPosition(undefined);
  66. }
  67. }

5.3 核心要素

Overlay  


六 、GeoJson行政区域边界显示 

6.1 逻辑层

6.1.1 引入所需对象

  1. import GeoJSON from "ol/format/GeoJSON";
  2. import { GEOJSON_CONST } from "@/assets/geojson/zhejian.js";

注意:其中zhejian.js文件中,抛出GEOJSON_CONST方法返回geojson数据即可,在本地运行时直接读取json文件可能产生跨域问题。

6.1.2 显示GeoJSon数据方法

  1. /**
  2. * 加载geojson数据
  3. */
  4. function addGeojson() {
  5. clearGeojson();
  6. let geojson = GEOJSON_CONST();
  7. // 载入数据
  8. let source = new VectorSource({
  9. features: new GeoJSON().readFeatures(geojson),
  10. });
  11. geojsonLayer.value = new VectorLayer({
  12. source: source,
  13. style: new Style({
  14. // 数据边界颜色与描边宽度
  15. stroke: new Stroke({
  16. color: "#25C67A",
  17. width: 2,
  18. }),
  19. // 内部填充色
  20. fill: new Fill({
  21. color: "rgba(255,255,255,0.2)",
  22. }),
  23. }),
  24. });
  25. map.value.addLayer(geojsonLayer.value);
  26. }
  27. /**
  28. * 清除geojson数据
  29. */
  30. function clearGeojson() {
  31. if (geojsonLayer.value) {
  32. map.value.removeLayer(geojsonLayer.value);
  33. geojsonLayer.value = null;
  34. }
  35. }

6.2 核心要素

GeoJSON  VectorSource  VectorLayer  Style  Stroke  Fill


七、加热力图

7.1 逻辑层

7.1.1 引入所需对象

  1. import { Heatmap } from "ol/layer";
  2. import QYWZ from "@/assets/geojson/qywz.json";//热力图数据
  3. //热力图数据部分示例
  4. /*{"type":"FeatureCollection", "features": [
  5. *{"type":"Feature","geometry":{"type":"Point","coordinates":
  6. * [121.57605318350262,29.84480421358972]},"properties":{"OBJECTID":1}},]}
  7. */

7.1.2 显示热力图方法

  1. /**
  2. * 加载热力图数据
  3. */
  4. function addHotmap() {
  5. clearHotmap();
  6. let source = new VectorSource({
  7. features: new GeoJSON().readFeatures(QYWZ),
  8. });
  9. hotmapLayer.value = new Heatmap({
  10. source: source,
  11. blur: 10, //模糊程度
  12. radius: 2,
  13. });
  14. map.value.addLayer(hotmapLayer.value);
  15. }
  16. /**
  17. * 清除热力图
  18. */
  19. function clearHotmap() {
  20. if (hotmapLayer.value) {
  21. map.value.removeLayer(hotmapLayer.value);
  22. hotmapLayer.value = null;
  23. }
  24. }

注意:该部分未完善,重点在于热力图数据的生成,后续完善 

7.2 核心要素

Heatmap  GeoJSON  VectorSource


参考链接 

[1].WangConvey文章 WangConvey_开发常见问题,openlayers学习之路-CSDN博客

[2].OpenLayers 3指南 OpenLayers 3 介绍 | OpenLayers 3 Primer

[3].OplenLayers中文文档 OpenLayers Examples

[4].OplenLayers文档 OpenLayers - Welcome

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/595169
推荐阅读
相关标签
  

闽ICP备14008679号