当前位置: 首页 > news >正文

福州婚庆网站建设哪个公司比较专业天津优化公司

福州婚庆网站建设哪个公司比较专业,天津优化公司,zblog蓝色简洁企业网站模板,找人做效果土去那网站找摘要 在 WebGIS 开发中,OpenLayers 是一个非常强大的开源地图库,它可以在 Web 应用中渲染高效的地图。本篇文章将介绍如何在 Vue 3 中使用 OpenLayers,并封装一个自定义地图控件组件,实现地图的放大、缩小、长度测量和面积测量功能…

摘要
在 WebGIS 开发中,OpenLayers 是一个非常强大的开源地图库,它可以在 Web 应用中渲染高效的地图。本篇文章将介绍如何在 Vue 3 中使用 OpenLayers,并封装一个自定义地图控件组件,实现地图的放大、缩小、长度测量和面积测量功能。


1. 项目介绍

在 WebGIS 相关的前端开发中,OpenLayers 是一个流行的选择。结合 Vue 3,我们可以利用 Composition API 更好地封装和管理地图逻辑,使代码更加清晰和可维护。

本篇文章将介绍如何在 Vue 3 项目中集成 OpenLayers,并基于此封装一个自定义地图组件,提供以下功能:

  1. 放大(Zoom In)
  2. 缩小(Zoom Out)
  3. 测量长度(Measure Length)
  4. 测量面积(Measure Area)

2. 安装 OpenLayers

首先,我们需要在 Vue 3 项目中安装 OpenLayers。

(1)创建 Vue 3 项目

如果你还没有 Vue 3 项目,可以使用以下命令创建一个新的 Vue 3 项目:

npm create vite@latest vue3-openlayers --template vue 
cd vue3-openlayers 
npm install

(2)安装 OpenLayers

运行以下命令安装 OpenLayers:

npm install ol

3. 编写 OpenLayers 自定义组件

components 目录下创建 OpenLayersMap.vue 组件,该组件负责加载地图并提供交互功能。

完整代码

<!--* @Author: 彭麒* @Date: 2025/2/14* @Email: 1062470959@qq.com* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。-->
<template><div class="container"><div class="w-full flex justify-center flex-wrap"><div class="font-bold text-[24px]">在Vue3中使用OpenLayers自定义组件(放大、缩小、长度测量、面积测量)</div></div><div class="controlbox"><div class="getlength0" @click="getLength('length')"></div><div class="getarea0" @click="getArea('area')"></div><div class="zoomIn" @click="zoomIn"></div><div class="zoomOut" @click="zoomOut"></div></div><div id="vue-openlayers"></div></div>
</template><script setup>
import { onMounted, ref } from "vue";
import "ol/ol.css";
import { Map, View } from "ol";
import Tile from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import MeasureTool from "@/utils/OpenLayersMeasure.ts";
import * as control from "ol/control";const map = ref(null);const zoomIn = () => {if (map.value) {let czoom = map.value.getView().getZoom();map.value.getView().setZoom(czoom + 1);}
};const zoomOut = () => {if (map.value) {let czoom = map.value.getView().getZoom();map.value.getView().setZoom(czoom - 1);}
};const getLength = (type) => {clearMeasure();MeasureTool.measure(map.value, type, true);
};const getArea = (type) => {clearMeasure();MeasureTool.measure(map.value, type, true);
};const clearMeasure = () => {MeasureTool.measure(map.value, "", false);
};const initMap = () => {let raster = new Tile({source: new OSM(),name: "OSM",});map.value = new Map({target: "vue-openlayers",layers: [raster],view: new View({center: [-12000000, 4700000],zoom: 2,}),controls: control.defaults({zoom: false,rotate: false,attribution: false,}).extend([]),});
};onMounted(() => {initMap();
});
</script><style scoped>
.container {width: 840px;height: 590px;margin: 50px auto;border: 1px solid #42B983;position: relative;
}#vue-openlayers {width: 800px;height: 470px;margin: 0 auto;border: 1px solid #42B983;position: relative;
}.controlbox {position: absolute;z-index: 200;bottom: 50px;width: 30px;padding: 5px 7px;height: 120px;right: 30px;border: 1px solid #ccc;border-radius: 4px;cursor: pointer;display: flex;align-content: space-between;flex-direction: column;background-color: #fff;
}.getlength0 {width: 18px;height: 30px;background: url(@/assets/OpenLayers/getlength.png) center center no-repeat;background-size: 16px 16px;
}.getarea0 {width: 18px;height: 30px;background: url(@/assets/OpenLayers/getarea.png) center center no-repeat;background-size: 16px 16px;
}.zoomIn {width: 18px;height: 30px;background: url(@/assets/OpenLayers/zoomin.png) center center no-repeat;background-size: 16px 16px;
}.zoomOut {width: 18px;height: 30px;background: url(@/assets/OpenLayers/zoomout.png) center center no-repeat;background-size: 16px 16px;
}
</style>

4. 测量工具 OpenLayersMeasure.ts

创建 utils/OpenLayersMeasure.ts 文件,封装 OpenLayers 的测量功能:

import Draw from 'ol/interaction/Draw';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Point from 'ol/geom/Point';
import { unByKey } from 'ol/Observable';
import Overlay from 'ol/Overlay';
import { Feature } from 'ol';
import { getArea, getLength } from 'ol/sphere';
import LineString from 'ol/geom/LineString';
import Polygon from 'ol/geom/Polygon';
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';export default {measure(map, measureType, show) {let source = new VectorSource(); // 创建一个新的矢量源let sketch; // 当前绘制的要素let helpTooltipElement; // 帮助提示元素let helpTooltip; // 显示帮助消息的覆盖层let measureTooltipElement; // 测量提示元素let measureTooltip; // 显示测量结果的覆盖层const continuePolygonMsg = ''; // 绘制多边形时显示的消息const continueLineMsg = ''; // 绘制线条时显示的消息createMeasureTooltip(); // 创建测量提示createHelpTooltip(); // 创建帮助提示const pointerMoveHandler = function (evt) {if (evt.dragging) {return;}let helpMsg = '请点击开始绘制'; // 默认帮助消息if (sketch) {const geom = sketch.getGeometry();if (geom instanceof Polygon) {helpMsg = continuePolygonMsg; // 如果是多边形,显示相应消息} else if (geom instanceof LineString) {helpMsg = continueLineMsg; // 如果是线条,显示相应消息}}helpTooltipElement.innerHTML = helpMsg; // 更新帮助提示内容helpTooltip.setPosition(evt.coordinate); // 设置帮助提示位置helpTooltipElement.classList.remove('hidden'); // 显示帮助提示};map.on('pointermove', pointerMoveHandler); // 监听指针移动事件map.getViewport().addEventListener('mouseout', function () {helpTooltipElement.classList.add('hidden'); // 鼠标移出视口时隐藏帮助提示});let draw; // 绘制交互const formatLength = function (line) {const sourceProj = map.getView().getProjection(); // 获取投影坐标系const length = getLength(line, { projection: sourceProj }); // 计算长度let output;if (length > 100) {output = (Math.round(length / 1000 * 100) / 100) + ' km'; // 如果长度大于100米,显示为公里} else {output = (Math.round(length * 100) / 100) + ' m'; // 否则显示为米}return output;};const formatArea = function (polygon) {const sourceProj = map.getView().getProjection(); // 获取投影坐标系const area = getArea(polygon, { projection: sourceProj }); // 计算面积let output;if (area > 10000) {output = (Math.round(area / 1000000 * 100) / 100) + ' km<sup>2</sup>'; // 如果面积大于10000平方米,显示为平方公里} else {output = (Math.round(area * 100) / 100) + ' m<sup>2</sup>'; // 否则显示为平方米}return output;};for (const layerTmp of map.getLayers().getArray()) {if (layerTmp.get('name') == 'feature') {source = layerTmp.getSource(); // 获取存放要素的矢量层}}function addInteraction() {const type = (measureType == 'area' ? 'Polygon' : 'LineString'); // 根据测量类型设置绘制类型draw = new Draw({source: source,type: type,style: new Style({fill: new Fill({color: 'rgba(255, 255, 255, 0.2)', // 填充颜色}),stroke: new Stroke({color: 'rgba(255, 0, 0, 0.5)', // 线条颜色lineDash: [10, 10], // 虚线样式width: 2, // 线条宽度}),image: new CircleStyle({radius: 5, // 圆点半径stroke: new Stroke({color: 'rgba(0, 0, 0, 0.7)', // 圆点边框颜色}),fill: new Fill({color: 'rgba(255, 255, 255, 0.2)', // 圆点填充颜色}),}),}),});map.addInteraction(draw); // 添加绘制交互let listener;draw.on('drawstart', function (evt) {sketch = evt.feature; // 设置当前绘制的要素let tooltipCoord = evt.coordinate; // 提示坐标listener = sketch.getGeometry().on('change', function (evt) {const geom = evt.target;let output;if (geom instanceof Polygon) {output = formatArea(geom); // 格式化面积tooltipCoord = geom.getInteriorPoint().getCoordinates(); // 获取多边形内部点坐标} else if (geom instanceof LineString) {output = formatLength(geom); // 格式化长度tooltipCoord = geom.getLastCoordinate(); // 获取线条最后一个点的坐���}measureTooltipElement.innerHTML = output; // 更新测量提示内容measureTooltip.setPosition(tooltipCoord); // 设置测量提示位置});map.on('dblclick', function (evt) {const point = new Point(evt.coordinate);source.addFeature(new Feature(point)); // 添加双击点要素});});draw.on('drawend', function () {measureTooltipElement.className = 'tooltip tooltip-static'; // 设置测量提示样式measureTooltip.setOffset([0, -7]); // 设置测量提示偏移sketch = null; // 清空当前绘制的要素measureTooltipElement = null; // 清空测量提示元素createMeasureTooltip(); // 创建新的测量提示unByKey(listener); // 移除监听器map.un('pointermove', pointerMoveHandler); // 移除指针移动事件监听map.removeInteraction(draw); // 移除绘制交互helpTooltipElement.classList.add('hidden'); // 隐藏帮助提示});}function createHelpTooltip() {if (helpTooltipElement) {helpTooltipElement.parentNode.removeChild(helpTooltipElement); // 移除旧的帮助提示元素}helpTooltipElement = document.createElement('div');helpTooltipElement.className = 'tooltip hidden'; // 设置帮助提示样式helpTooltip = new Overlay({element: helpTooltipElement,offset: [15, 0], // 设置偏移positioning: 'center-left', // 设置定位方式});map.addOverlay(helpTooltip); // 添加帮助提示覆盖层}function createMeasureTooltip() {if (measureTooltipElement) {measureTooltipElement.parentNode.removeChild(measureTooltipElement); // 移除旧的测量提示元素}measureTooltipElement = document.createElement('div');measureTooltipElement.className = 'tooltip tooltip-measure'; // 设置测量提示样式measureTooltip = new Overlay({element: measureTooltipElement,offset: [0, -15], // 设置偏移positioning: 'bottom-center', // 设置定位方式});map.addOverlay(measureTooltip); // 添加测量提示覆盖层}addInteraction(); // 添加绘制交互const vector = new VectorLayer({name: 'lineAndArea',source: source,style: new Style({fill: new Fill({color: 'rgba(255, 255, 255, 0.2)', // 填充颜色}),stroke: new Stroke({color: 'red', // 线条颜色width: 2, // 线条宽度}),image: new CircleStyle({radius: 7, // 圆点半径fill: new Fill({color: '#ffcc33', // 圆点填充颜色}),}),}),zIndex: 16, // 设置图层顺序});if (show && measureType) {map.addLayer(vector); // 显示测量图层} else {map.getOverlays().clear(); // 清除所有覆盖层map.getLayers().getArray().forEach((layer, index, array) => {if (layer.get('name') == 'lineAndArea') {map.removeLayer(layer); // 移除测量图层}});}},
};

5. 在 Vue 项目中使用组件

App.vue 中引入 OpenLayersMap.vue 组件:

<template> <div> <OpenLayersMap /> </div> 
</template> 
<script setup> 
import OpenLayersMap from "@/components/OpenLayersMap.vue"; 
</script>

6. 运行项目

在项目根目录运行以下命令,启动 Vue 开发服务器:

npm run dev

然后在浏览器中访问 http://localhost:5173/,你就可以看到 OpenLayers 地图,并且可以使用放大、缩小、长度测量和面积测量功能了。


7. 结语

本篇文章介绍了如何在 Vue 3 项目中集成 OpenLayers,并封装了一个自定义地图控件组件,实现了放大、缩小、长度测量和面积测量功能。

你可以根据自己的需求扩展更多功能,比如:

  • 添加更多测量单位
  • 显示测量结果的弹窗
  • 增加图层切换等功能

希望这篇文章能帮助到你!如果你觉得有用,请点赞支持!🚀🚀🚀


💬 交流与讨论

如果你有任何问题或建议,欢迎在评论区留言交流!💡


文章转载自:
http://wanjiacaudillo.przc.cn
http://wanjiaunwindase.przc.cn
http://wanjiatelefoto.przc.cn
http://wanjiadicotyl.przc.cn
http://wanjiareclothe.przc.cn
http://wanjiastagnancy.przc.cn
http://wanjiadamson.przc.cn
http://wanjiapersonification.przc.cn
http://wanjiavasovagal.przc.cn
http://wanjiaanaerobium.przc.cn
http://wanjiafulfil.przc.cn
http://wanjiaplating.przc.cn
http://wanjiaoutyell.przc.cn
http://wanjiasubtrahend.przc.cn
http://wanjiapsoas.przc.cn
http://wanjiabosky.przc.cn
http://wanjianorthing.przc.cn
http://wanjiagop.przc.cn
http://wanjiapopulace.przc.cn
http://wanjiaaew.przc.cn
http://wanjiavolucrine.przc.cn
http://wanjiapaintwork.przc.cn
http://wanjiavariolite.przc.cn
http://wanjiahemialgia.przc.cn
http://wanjiahaunting.przc.cn
http://wanjiahistadrut.przc.cn
http://wanjiacontretemps.przc.cn
http://wanjiacyberworld.przc.cn
http://wanjiamope.przc.cn
http://wanjiarepeating.przc.cn
http://wanjiamondaine.przc.cn
http://wanjiayarnsmith.przc.cn
http://wanjiadisinflation.przc.cn
http://wanjiabuzkashi.przc.cn
http://wanjialumbricoid.przc.cn
http://wanjiajuggernaut.przc.cn
http://wanjiamadder.przc.cn
http://wanjiaunswerving.przc.cn
http://wanjiawindsurf.przc.cn
http://wanjiasothiac.przc.cn
http://wanjiahattery.przc.cn
http://wanjiaol.przc.cn
http://wanjiaobjectivity.przc.cn
http://wanjiahusbandage.przc.cn
http://wanjiapelagic.przc.cn
http://wanjiamyope.przc.cn
http://wanjiamanticore.przc.cn
http://wanjiaperfusive.przc.cn
http://wanjialucern.przc.cn
http://wanjiaheptateuch.przc.cn
http://wanjiabymotive.przc.cn
http://wanjiaboilerplate.przc.cn
http://wanjiacalpac.przc.cn
http://wanjiasulphurous.przc.cn
http://wanjiaennyyee.przc.cn
http://wanjiamasochist.przc.cn
http://wanjiafolio.przc.cn
http://wanjiaprecipitin.przc.cn
http://wanjiaolingo.przc.cn
http://wanjiabloodmobile.przc.cn
http://wanjiasimoniac.przc.cn
http://wanjiaprotension.przc.cn
http://wanjiaturgite.przc.cn
http://wanjiacausally.przc.cn
http://wanjiachromoplasmic.przc.cn
http://wanjiaexploiture.przc.cn
http://wanjiaoophyte.przc.cn
http://wanjiadreadnaught.przc.cn
http://wanjiacabasset.przc.cn
http://wanjiaweskit.przc.cn
http://wanjiasurmisable.przc.cn
http://wanjiabasketwork.przc.cn
http://wanjiaextenuation.przc.cn
http://wanjiaconcord.przc.cn
http://wanjiadiamagnetic.przc.cn
http://wanjiabursiculate.przc.cn
http://wanjiasodomy.przc.cn
http://wanjiatruck.przc.cn
http://wanjiaformer.przc.cn
http://wanjiawash.przc.cn
http://www.15wanjia.com/news/112278.html

相关文章:

  • wordpress pdf预览插件厦门seo怎么做
  • 做app还是做网站网站如何添加友情链接
  • 个人做网站要缴税电商网站商品页的优化目标是什么
  • 网站建设兆金手指科杰外包平台
  • 做oa系统的网站企业宣传ppt
  • 徐州开发区中学网站营销策划公司名称
  • 做一个人网站需要注意什么搜索率最高的关键词
  • 可以做装修效果图的网站识别关键词软件
  • 潍坊网站制作 熊掌号酒店营销策划与运营
  • 云南公司做网站的价格重庆seo网络推广关键词
  • 复旦学霸张立勇做的有关寺庙网站阿里数据
  • 建设一个小说网站的步骤推广普通话的意义
  • 做网站的基本功能网站如何快速推广
  • 深圳网站建设10强创量广告投放平台
  • 国外做问卷调查的网站长春网站制作计划
  • 香港特别行政区政府搜索引擎优化自然排名的优点
  • 南通哪里有做网站的百度站长工具如何使用
  • 手机网站建设价钱是多少营销软件培训
  • 自学网站建设靠谱吗今日武汉最新消息
  • 做阀门网站电话深圳网站建设方案
  • 浙江和海建设集团网站如何写好软文
  • 企业域名注册流程快抖霸屏乐云seo
  • 网站运维可以做哪些磁力搜索神器
  • wordpress ifeature电子商务seo名词解释
  • 做兼职网站的主要参考文献新站快速收录
  • 天津北辰做网站重庆森林
  • 有哪些网站是可以做免费推广的宁波关键词优化排名工具
  • 台州手机端建站模板小学生收集的新闻10条
  • 某网站自己做中性笔排名优化方法
  • 全国 做网站的企业seo关键字优化教程