本文是博主在开发过程中遇到的一些问题的整理。
学习教程为:《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有哪些事件
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 =