Openlayers + Vue实现GIS地图的一些常见问题(整理)

本文总结了使用Openlayers与Vue在GIS地图开发中遇到的问题,包括离线地图实现、基础概念(坐标系、投影转换、比例尺等)、开发中遇到的事件处理、性能优化和地图功能实现,如地图测距功能的Vue实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文是博主在开发过程中遇到的一些问题的整理。
学习教程为:《WebGIS之Openlayers全面解析(第二版)》一书。

Openlayers实现离线地图的实现方案

前端: Openlayers
后端: GeoServer

基于 JavaEE 的解决方案

GeoServer(服务器)
uDig(桌面软件)
Tomact(中间件)
PostGIS|MySQL空间扩展(数据库)
OpenLayers(JS)/OpenScales(Flex)(浏览器客户端)		

基础概念

坐标系

坐标原点(O)
长半轴(a)
短半轴(b)
扁率(f)
可分为两个系统
	地理坐标系(Geography Coor dinate System)
		经度、维度
		直接建立在椭球体上
	投影坐标系(Projected Coordinate System)
		米
		建立在平面上

投影转换

球面是个不可展曲面
把球面直接展开为平面时,不避免地会发生破裂或褶皱
地图投影理论
	基本原理
		球面上一点的位置决定于它的经度和纬度
		先将一些经线和纬线的交点展绘在平面上
		再将相同经度的点连成经线,相同纬度的点连成纬线,构成经纬网。
	一般按照两种标准进行分类
		按投影的变形性质分类
			等角投影
				没有角度变形
				航海、洋流和风向图
				面积变形很大,不能测量面积
			等积投影
				地质、土壤、土地利用、行政区划等地图
			任意投影
				角度和面积的变形都存在,但都适中
		按照投影的构成方式分类
			几何投影
			解析投影

比例尺

图上距离除以实际距离
比例尺越小,抽象缩小的程度越高,表达的地物就少而简单
比例尺越大,抽象缩小的程度越低,表达的地物就越详细

GIS 两大基本存储模型

矢量数据模型
	以离散的点坐标来表示地理要素,通过点、线、面以及注记来抽象表达空间实体以及实体间的关系
	明确对象的专题
	地籍数据、行政边界、街道
栅格数据模型
	以一系列栅格值来表示,基于网格结构使用不同颜色和灰度的像元来表达
	连续空间变化的专题
	呈现出河流、湖泊、地块等的形态
	遥感影像为栅格数据

WebGIS的二维地图主要分为矢量地图与瓦片地图两种形式。

矢量地图
	矢量数据模型存储的矢量数据组成的地图
	实时生成请求范围对应的地图
瓦片地图
	瓦片数据是指网格中多个类似瓦片的图片集。
	瓦片数据是通过将矢量或影像数据进行预处理,采用高效的缓存机制(即金字塔结构)形成的,采用级、行、列方式进行组织,可在网页中快速加载。

OGC(Open Geosp atial Consortium,开放地理空间信息联盟)

制定了一系列针对空间数据的服务规范
WMS、WMTS、WFS

安装最新的OpenLayers 开发环境

npm install ol

实现地图显示功能

创建一个地图容器对象(ol.Map)
通过target参数关联到地图容器(ID为map的div层)
通过layers参数设置加载瓦片图层(ol.layer.Tile)
绑定数据源(ol.source.XYZ 或其它source,如ol.source.TileWMS)
	默认情况下,遵循我们广泛使用的Google网格。如果是自定义网格,则在url模板中使用{x}、{y}、{z}占位符即可。
	如果使用GeoServer,后端的数据的服务规范可能是WMS,则使用ol.source.TileWMS。
通过view参数设置地图视图(ol.View)

开发中的问题

ol.Map有哪些事件

map事件

const _this = this  // JS作用域
this.map.on('click', (evt) => {
   
		// 点击某个元素点,做的一些操作
        let feature = _this.map.forEachFeatureAtPixel(evt.pixel,
          function (feature) {
   
            return feature
          })
        if (feature && feature.get('className') === 'point') {
   
          let data = feature.get('data')
          this.gotoAreaByCoordinate(14, [data.lon, data.lat])
        }
      })

feature点太多,ol.layer.Vector绘制的地图移动卡顿

直接改用ol.layer.VectorImage

import VectorLayer from 'ol/layer/Vector'
import VectorImageLayer from 'ol/layer/VectorImage'
	  //  原先代码
      this.vectorLineCover = new VectorLayer({
   
        source: source,
        style: style
      })
      // 改动后代码
      this.vectorLineCover = new VectorImageLayer({
   
        source: source,
        style: style
      })

设置地图可视窗口大小,可视区域

import {
    boundingExtent as BoundingExtent } from 'ol/extent'
const _this = this  // JS作用域
this.map = new Map({
   
        target: 'map',
        layers: [
          _this.basicMap,
        ],
        view: new View({
   
          center: _this.initCenter,
          zoom: _this.initZoom,
          minZoom: _this.GISZoomRange[0],
          maxZoom: _this.GISZoomRange[1],
          extent: new BoundingExtent([
	        [window.GISVisibleAreaRange[0], window.GISVisibleAreaRange[1]],
	        [window.GISVisibleAreaRange[2], window.GISVisibleAreaRange[3]],
	        [window.GISVisibleAreaRange[0], window.GISVisibleAreaRange[3]],
	        [window.GISVisibleAreaRange[2], window.GISVisibleAreaRange[1]]
	      ]), // 限定可视范围
        }),
        // 配置控件
        controls: defaults().extend([])
      })

设置投影

const _this = this  // JS作用域
this.map = new Map({
   
        view: new View({
   
          projection: 'EPSG:4326',   // 投影
        })
      })

设置只在一个世界展示数据

const _this = this  // JS作用域
this.map = new Map({
   
        view: new View({
   
          multiWorld: false, // 是否只在一个世界展示数据
        })
      })

Javascript移除页面一个DOM元素

使用removeChild方法

let box = document.querySelectorAll('.tooltip-hidden')
let parent = document.getElementsByClassName('ol-overlaycontainer-stopevent')[0]
 if (parent) {
   
   box.forEach(item => {
   
     parent.removeChild(item.parentNode)
   })
 }

创建DOM元素添加事件,如点击事件click

let elementDiv = document.createElement('div')
elementDiv.className = 'label-point'
let markerDiv = document.createElement('div')
markerDiv.id = 'marker'
markerDiv.className = 'marker'
markerDiv.style = 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值