91.在 Vue 3 中使用 OpenLayers 非 4326、3857 的投影示例
前言
在 Web 地图开发中,OpenLayers 是一个非常强大且灵活的地图库,广泛应用于地图渲染和地理信息展示。通常情况下,OpenLayers 默认使用 EPSG:4326(经纬度坐标系)或 EPSG:3857(Web Mercator 投影)这两种投影进行地图渲染。但是,在某些特定场景下,我们可能需要使用非标准的投影,例如 Mollweide 投影(ESRI:53009)。
本文将带领大家一起在 Vue 3 中使用 OpenLayers 来展示如何实现非标准投影的地图应用,具体使用 Mollweide 投影,并通过 Vue 3 + OpenLayers 结合的方式来实现地图渲染。
项目依赖
首先,我们需要在项目中安装一些必要的依赖:
npm install vue@next openlayers proj4
- Vue 3:用于构建前端应用。
- OpenLayers:用于地图的展示和渲染。
- proj4:用于自定义地图投影。
配置投影
在 OpenLayers 中,我们可以使用 proj4
来定义自定义的投影,并将其注册到 OpenLayers 中。我们将使用 Mollweide 投影(ESRI:53009
),这是一种常用于世界地图展示的投影方式。
在代码中,我们首先定义投影,并注册它:
import {register} from 'ol/proj/proj4';
import proj4 from 'proj4'; // 定义自定义投影(Mollweide 投影)
proj4.defs( 'ESRI:53009', '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +a=6371000 ' + '+b=6371000 +units=m +no_defs' );
register(proj4);
投影的范围设置
为确保地图在正确的范围内显示,我们需要设置投影的有效范围。extent
属性定义了地图的最大显示区域,worldExtent
定义了地图的包围盒(通常是全世界的经纬度范围):
const sphereMollweideProjection = new Projection({
code: 'ESRI:53009',
extent: [ -18019909.21177587, -9009954.605703328, 18019909.21177587, 9009954.605703328, ],
worldExtent: [-179, -89.99, 179, 89.99],
});
设置地图
在 Vue 3 中,我们使用 onMounted
生命周期钩子来初始化 OpenLayers 地图。通过 Map
对象配置地图的基本信息,包括地图的容器、图层、视图等。
import { onMounted, ref } from 'vue';
import 'ol/ol.css';
import { Map, View } from 'ol';
import { Graticule } from 'ol/layer';
import { VectorLayer } from 'ol/layer';
import { VectorSource } from 'ol/source';
import { GeoJSON } from 'ol/format';
import { Style, Fill } from 'ol/style';
const map = ref(null);
const initMap = () => { const style = new Style({ fill: new Fill({ color: '#eeeeee', }), });
map.value = new Map({ target: 'vue-openlayers', // 地图容器 ID
layers: [ new VectorLayer({ source: new VectorSource({ url: 'https://openlayers.org/data/vector/ecoregions.json', format: new GeoJSON(), }), style: function (feature) {
const color = feature.get('COLOR_BIO') || '#eeeeee';
style.getFill().setColor(color); return style; }, }),
new Graticule(), ],
view: new View({ center: [0, 0], projection: sphereMollweideProjection, // 使用自定义投影 zoom: 2, }),
});
};
onMounted(() => { initMap(); });
代码解析
- GeoJSON 数据加载:我们使用
VectorSource
从https://openlayers.org/data/vector/ecoregions.json
加载 GeoJSON 数据,该数据包含地理区域的边界。 - 样式设置:每个矢量图层的样式是通过
Style
和Fill
对象来设置的,基于数据中的COLOR_BIO
属性来为区域上色。 - 视图设置:设置地图的视图(
View
),包括中心点[0, 0]
(经纬度 0,0),并且使用自定义的sphereMollweideProjection
投影,初始缩放级别为2
。
样式定制
在地图中,我们使用 Style
来定制每个矢量要素的样式。在本例中,我们使用 Fill
来设置区域的填充颜色。你可以根据需要调整样式,使其符合你的项目需求。
const style = new Style({ fill: new Fill({ color: '#eeeeee', }), });
如果你的数据源包含其他类型的属性,例如区域名称、面积等,你也可以利用这些属性动态调整样式,例如不同的填充颜色、边框等。
完整代码
下面是完整的代码示例,结合前面的所有配置:
<!--
* @Author: 彭麒
* @Date: 2025/2/22
* @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非4326,3857的投影示例</div>
</div>
<div id="vue-openlayers"></div>
</div>
</template>
<script setup>
import {onMounted, ref} from 'vue';
import 'ol/ol.css';
import GeoJSON from 'ol/format/GeoJSON';
import Graticule from 'ol/layer/Graticule';
import Map from 'ol/Map';
import Projection from 'ol/proj/Projection';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import proj4 from 'proj4';
import {Fill, Style} from 'ol/style';
import {register} from 'ol/proj/proj4';
const map = ref(null);
const initMap = () => {
proj4.defs(
'ESRI:53009',
'+proj=moll +lon_0=0 +x_0=0 +y_0=0 +a=6371000 ' +
'+b=6371000 +units=m +no_defs'
);
register(proj4);
const sphereMollweideProjection = new Projection({
code: 'ESRI:53009',
extent: [
-18019909.21177587, -9009954.605703328, 18019909.21177587,
9009954.605703328,
],
worldExtent: [-179, -89.99, 179, 89.99],
});
const style = new Style({
fill: new Fill({
color: '#eeeeee',
}),
});
map.value = new Map({
target: 'vue-openlayers',
layers: [
new VectorLayer({
source: new VectorSource({
url: 'https://openlayers.org/data/vector/ecoregions.json',
format: new GeoJSON(),
}),
style: function (feature) {
const color = feature.get('COLOR_BIO') || '#eeeeee';
style.getFill().setColor(color);
return style;
},
}),
new Graticule(),
],
view: new View({
center: [0, 0],
projection: sphereMollweideProjection,
zoom: 2,
}),
});
};
onMounted(() => {
initMap();
});
</script>
<style scoped>
.container {
width: 840px;
height: 590px;
margin: 50px auto;
border: 1px solid #42B983;
}
#vue-openlayers {
width: 800px;
height: 470px;
margin: 0 auto;
border: 1px solid #42B983;
position: relative;
}
</style>
总结
在本篇文章中,我们通过一个实际示例,介绍了如何在 Vue 3 项目中使用 OpenLayers 配合 proj4
来实现非标准投影的地图渲染。我们自定义了 Mollweide 投影,并通过 OpenLayers 加载并展示了一个 GeoJSON 数据源。这个实现可以为需要特定投影的 GIS 项目提供帮助。
如果你有任何问题或建议,欢迎在评论区留言讨论!