高德百度地图替换方案OpenLayers

一、前言

因为工作需要在使用百度/高德以外实现地图功能。。。。巴拉巴拉。。。。 前文此处省略****字

二、介绍

WebGIS四大地图框架:Leaflet、OpenLayers、Mapbox、Cesium

Leaflet

Leaflet是一个轻量级、易于使用的开源JavaScript库,为开发者提供了创建交互式地图的强大工具。它具有丰富的地图功能和插件生态系统,支持各种地图数据源,从基本的点标记到复杂的地图覆盖物都可以轻松实现。Leaflet的优势在于其简洁性和易用性,使得它成为初学者和专业开发者的首选。

除了在普通地图应用程序中广泛应用外,Leaflet在公共卫生和生物计算等领域也有着广泛的应用。

在公共卫生领域,Leaflet可以用于疫情数据的可视化展示。例如,在新冠疫情期间,Leaflet被广泛应用于疫情数据的可视化展示,以帮助公众更好地了解疫情的传播和分布情况。同时,Leaflet还可以将疫苗接种点的分布数据可视化展示在地图上,以帮助公众查找附近的疫苗接种点和了解疫苗接种进展情况。

OpenLayers

OpenLayers 是一个开源的地图库,用于在 Web 应用中展示交互式地图。它使用 JavaScript 构建,并且支持多种地图数据源,包括 OpenStreetMap、Google Maps、Bing Maps 等。OpenLayers 提供了丰富的地图功能和交互性,使开发者能够在网页中轻松集成地图,并实现各种地理信息展示和交互。

在招聘市场中,OpenLayers的地位也是不可小觑的,能够帮助开发者使网页程序拥有强大的地图功能,用于实施各种项目,包括地理空间搜索、室内分析、地图影像分析和动画模拟等。例如,使用OpenLayers,开发者可以创建支持多个空间图层的互动Web应用程序,可以显示不同底图和支持多种地图操作,比如缩放和平移。此外,开发者还可以在其中添加自定义内容,如文字标签和街景,使Web地图更加完整和生动。

Mapbox

mapbox是一个开源的地图类库,通过使用mapbox的类库,可以很方便的构建web、app等地图应用,支持的地图sdk有web、ios、Android和Unity。

mapbox gl js是mapbox地图的一部分,使用了webgl技术渲染地图上的一些酷炫的效果。

网址:docs.mapbox.com/mapbox-gl-j...

mapbox gl要使用mapbox在线的一些资源,所以,要申请开发者的key才能进行开发使用。

mapbox gl包括了二维三维地图的交互,三维地图是在平面地图的基础上进行立体展示,三维模型是简单的颜色形状渲染,能够基于geojson数据进行渲染,渲染的数据量还是挺可观的,并可以进行数据的交互。

Cesium

Cesium是一个用于创建三维地球和地图应用程序的JavaScript库。它利用WebGL技术实现高性能的地球渲染,为开发者提供了强大的地理空间分析和可视化功能。Cesium不仅支持地球表面的三维渲染,还可以展示地球上的各种数据,如卫星轨道、地质信息等。借助Cesium,开发者可以在Web浏览器中实现惊人的三维地球应用

Cesium目前的功能: 3D地球可视化漫游和导航地形和影像数据3D建筑模型3D TilesCZML实时位置追踪地下和空中场景天文数据集成其他GIS工具

平面:Leaflet,OpenLayers

3D:Mapbox,Cesium

以OpenLayers为例

OpenLayer中的基本对象结构

Map:地图容器,通过target指定地图绘制的容器id,如代码中的map;

Layer:图层,map拥有1个获多个图层,可以理解成PS绘图中的图层概念,整个map是由一个个图层堆叠出来的;

View:可视区域,这个类主要是控制地图与人的交互,如进行缩放,调节分辨率、地图的旋转等控制。同时可以设置投影,默认为球形墨卡托,代码中olProj.fromLonLat方法也是将经纬度转换成对应的坐标,这块不做拓展,有需要的同学可自行去学习GIS的理论。

source:数据来源,即图层Layers的数据组成部分,上文代码中TileLayer就是使用了一个高德地图XYZ格式的切片数据绘制而成,

三、具体实现

本项目基于vue开发

定义瓦片图资源,以天地图为例

js 复制代码
typeMapping: {
    img: 'http://t{0-7}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=',
    cia: 'http://t{0-7}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=',
    vec: 'http://t{0-7}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=',
    cva: 'http://t{0-7}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk='
},
js 复制代码
// 添加地图层
plugins?.forEach((e) => {
    layers.push(
        new TileLayer({
            title: '****图',
            id: `${e}-mapLayer`,
            className: `${e}-mapLayer`,//增加className属性
            source: new XYZ({
                    wrapX: true,
                    url: `${this.typeMapping[e]}${key}`,
            })
        })
    )
})

保存不同的图层便于后期操作

js 复制代码
this.markerSource = new VectorSource({ id: 'clusterMarker' });
this.regionSource = new VectorSource({ id: 'region' });

OpenLayers点聚合使用聚合类Cluster

官方文档:openlayers.org/en/v6.15.1/...

使用Cluster类来添加Marker点

js 复制代码
try {
    let features = []
    PointData.forEach((e, i) => {
        const feature = new Feature({
            type: 'Point',
            id: e.id || `clusterMarker${i}`,
            geometry: new Point(e.position),
            item: e,
            image: e.content.src,
            style: new VectorStyle({
                image: new Icon(e.content),
                id: e.id || `clusterMarker${i}`,
                geometryName: e.geometryName || `clusterMarker${i}`,
            })
        });
        features.push(feature)
    })
    this.markerSource.addFeatures(features)

    let clusterStrategy = new Cluster({
        distance: parseInt(40, 10),
        minDistance: 20,
    })
    clusterStrategy.setSource(this.markerSource)
    this.geometryLayer.setSource(clusterStrategy)
} catch (err) {
    console.error('点聚合生成错误', err)
}

在 new VectorLayer 中styl实现聚合点不同的动态展示逻辑

js 复制代码
// 生成标记点图层

layers.push(this.geometryLayer = new VectorLayer({
    id: `geometryLayer`,
    className: `geometryLayer`,
    zIndex: 999,
    source: this.markerSource,
    style: (feature) => {
        let size = feature.get('features')?.length || 1;
        let moreIconMap = new Map
        let moreIcon = { key: '', value: 0 }
        let style
        if (size > 1) {
            feature.get('features').forEach(e => {
                try {
                    let iconPath = ****.png`)
                if (moreIconMap.has(iconPath)) {
                    moreIconMap.set(iconPath, moreIconMap.get(iconPath) + 1)
                } else {
                    moreIconMap.set(iconPath, 1)
                }
                }catch(err){
                    console.error('图片读取错误',err)
                }
            })
            moreIconMap.forEach((value, key) => {
            if (moreIcon.value < value) {
                moreIcon.value = value
                moreIcon.key = key
            }
        })
        
        // 计算出现最多的图标
        style = new VectorStyle({
            image: new Icon({
                src: moreIcon.key,
                scale: 0.8,
            }),
            text: new Text({
                font: 'bold 1rem myFont ',
                offsetY: -39,
                offsetX: 26.9,
                text: size.toString() <= 99?size.toString():'99+',
                fill: new Fill({
                    color: '#fff',
                })
            })
        });
        return style;
        } else {
            return feature.get('features')[0].values_.style
        }
    }
}))

如果需要使用国标2000 需要 使用proj4 自定义添加

projection = "EPSG:4326"

js 复制代码
import proj4 from 'proj4';
proj4.defs(
"EPSG:4490",
'GEOGCS["China Geodetic Coordinate System 2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","1043"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'
);
register(proj4);
相关推荐
GIS程序媛—椰子14 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00121 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端24 分钟前
Content Security Policy (CSP)
前端·javascript·面试
木舟100927 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤439138 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落1 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt