侧边栏

初识前端GIS开发

发布于 | 分类于 前端/前端业务|本文包含AIGC内容

等某次等待滴滴司机的途中,对Web地图功能的实现有点好奇,之前没怎么接触过,了解一下。

什么是GIS

前端 GIS (地理信息系统) 开发是指在浏览器中展示、交互和处理地理数据的技术。

GIS 是用来收集、存储、分析和展示地理空间数据的系统,常见的地理数据包括点(如城市坐标)、线(如道路)和面(如国家边界)。

在很多应用中都有GIS的身影,GIS开发的需求,可以分为基础需求和进阶需求。

基础需求

加载地图:加载一个简单的地图

添加标记和图层:学会如何在地图上添加标记(如地点坐标)和自定义图层(如显示城市区域或道路)。

交互功能:添加地图的缩放、平移功能,支持用户在地图上交互

进阶需求

路径规划:学习如何实现路线规划功能,如提供两个地点之间的导航路线。

热力图:利用地理数据生成热力图,显示某区域内数据的密集程度。

空间分析:如缓冲区分析、重叠分析等,这些分析可以帮助用户从地图数据中提取更深层次的信息。

坐标系

理解地图投影和坐标系统,对于正确显示和操作地理数据至关重要。

地理坐标系

地理坐标系(Geographic Coordinate System, GCS)是用于描述地球上任意位置的一种坐标系统。它通过经度和纬度的数值来表示地球表面上的点的位置,是地图学和地理信息系统(GIS)中的核心概念。

地理坐标系使用两个角度参数来定义地球上的位置:

  • 纬度(Latitude):表示一个点相对于赤道的北或南的角度。
    • 纬度的范围是 -90°(南极)到 +90°(北极),赤道为 0°。
  • 经度(Longitude):表示一个点相对于本初子午线(穿过英国格林尼治的子午线)的东西方向角度。
    • 经度的范围是 -180°(西经)到 +180°(东经),本初子午线为 0°。

比如成都的地理坐标是 纬度 30.67, 经度 104.06

地理坐标系依赖于基准面(Datum),用于定义地球的数学模型,描述地球的形状和大小。地理坐标系中的点是相对于这个基准面定义的。常用的基准面有

  • WGS84:世界大地坐标系 1984,是全球广泛使用的标准坐标系,GPS 设备和大部分地图都使用它,通过卫星测量提供全球范围内的精确位置。
  • NAD83NAD27:主要用于北美地区。
  • CGCS2000:中国大地坐标系 2000,是中国使用的地理坐标系统,与 WGS84 很接近,但有所不同,主要应用于中国的地理信息处理。

因为地球并不是完美的球体,椭球体(Ellipsoid)是对地球形状的更精确的数学表示,常用于地理坐标系的计算。

  • 椭球体通过定义长轴和短轴来表示地球的扁平度。

投影坐标系

投影坐标系(Projected Coordinate System, PCS):是地理坐标系经过平面投影后的二维坐标系统,通常用来在地图或其他平面中表示地理位置。

Web Mercator 是目前互联网地图服务中最广泛使用的地图投影,它是一种 投影坐标系,用于将地球的三维球体表面投影到二维平面地图上,主要应用于在线地图服务如 Google Maps、Bing Maps、OpenStreetMap 等。

Web Mercator 是基于经典 墨卡托投影(Mercator Projection) 的一种变体。它通过将地球上的经纬度转换为平面上的 x 和 y 坐标,允许用户在地图上进行平滑的缩放和平移。然而,Web Mercator 的投影并不是完全严格的标准墨卡托投影,因此称为 伪墨卡托(Pseudo-Mercator)

Web Mercator 的坐标系不直接使用 经纬度,而是使用经过投影变换的平面坐标(单位为米)。转换过程如下:

  • 经度 转换为 x 坐标,范围从 -20037508.34 米到 20037508.34 米,对应经度范围从 -180° 到 180°。
  • 纬度 转换为 y 坐标,范围也从 -20037508.34 米到 20037508.34 米,对应纬度范围大约是 -85.0511° 到 85.0511°。高纬度地区(靠近极点)的投影会被压缩,实际上的纬度范围不会显示极点。

虽然 Web Mercator 保持了线性比例,但在靠近两极的地区失真会很严重。越靠近极点,地图上的地物会显得越大。例如,在 Web Mercator 中,格陵兰岛看起来与非洲大陆差不多大,尽管非洲的面积远远超过格陵兰岛。

Web Mercator 的投影方式适合用于在线地图,因为它在较小的区域(如城市或街道)显示时非常精确,并且允许地图以图块(tiles)的形式平滑渲染和缩放

因此,尽管存在高纬度地区的失真问题,但它在全球范围内提供了流畅且一致的用户体验,成为当前 Web GIS 和在线地图服务的标准投影。

地理编码和逆地理编码

需要理解地理编码(将地址转换为坐标)和逆地理编码(将坐标转换为地址)的概念和服务

GIS数据格式

在实际开发中,

在实际开发中,除了渲染地图图层本身之外,还需要在其之上展示更多定制化的内容,比如一条推荐的导航路线、一份圈中的区域边界等,需要约定一些数据格式,用于存储和传输地理空间等数据,然后通过支持这种数据格式的框架来进行展示。

下面介绍一下GIS开发中常见的三种数据格式。

GeoJSON

GeoJSON 是一种用于表示地理空间数据的常用格式,特别适合在 Web GIS 应用中传输和处理地理数据。

GeoJSON本身有一套规范定义

  • 表示地理数据:GeoJSON 是表示点、线、面等地理特征及它们属性信息的标准格式,括空间区域(几何图形)、空间边界实体(特征)或特征列表(特征集合)。
  • 数据交互:通过属性字段,GeoJSON 可以存储与几何对象相关的元数据,如名称、人口等,便于交互和显示。
  • 轻量级:由于 GeoJSON 是基于 JSON 的格式,轻量且易于传输,非常适合在前端进行动态地图渲染。

GeoJSON 定义了一些关键的地理要素,包括:Point、LineString、Polygon、MultiPoint、MultiLineString、MultiPolygon 和 GeometryCollection。

  • Point:表示单个地理点。
  • LineString:表示一条由多个坐标点连接而成的线。
  • Polygon:表示封闭的多边形,由多个点组成(第一个点和最后一个点是相同的,以封闭区域)。
  • Feature:包含几何对象及其属性的geometry地理要素。
  • FeatureCollection:由多个 Feature 组成的集合。

下面展示了一份 GeoJSON的示例代码

js
// 定义 GeoJSON 数据
var geojsonData = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [104.0668, 30.5728]
            },
            "properties": {
                "name": "Chengdu",
                "population": 16300000
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [104.0668, 30.5728],
                    [104.0734, 30.5769]
                ]
            },
            "properties": {
                "name": "Chengdu Line"
            }
        }
    ]
};

GeoJSON基于 JSON 格式,使用标准的 JSON 对象和数组结构来表示地理数据,文本轻量级,适合网络传输和处理,易于与现代Web技术集成(如 JavaScript 和 AJAX),常用于Web地图应用和APIs。

Shapefile

参考:Shapefile定义-wiki

Shapefile 是一种广泛使用的地理信息系统矢量数据格式,由ESRI(环境系统研究所)开发。

  • 它是一种文件集,由多个文件组成,通常包括三种基本类型的文件:.shp(几何信息)、.shx(几何索引)、.dbf(属性信息),有时还包括其他几个可选文件。
  • Shapefile 支持存储点(Point)、线(Line)、多边形(Polygon)等几何形状,并且可以包含与这些几何形状相关联的属性数据。
  • 由于其广泛的兼容性,Shapefile 成为了GIS数据交换的一个标准格式,几乎所有GIS软件都能够读写Shapefile格式的数据。

Shapefile 更侧重于GIS专业人士使用,它在数据的精确性和复杂性方面表现更好,适合进行空间分析和复杂的地理数据处理。

KML

KML(Keyhole Markup Language)是一种基于XML的文件格式,以.kml结尾,由Google开发,用于Google Earth和Google Maps等应用程序中表示地理数据。

  • KML 文件可以包含点、线、多边形、模型、图像叠加以及其他与地理位置相关的信息。
  • 它支持丰富的视觉和交互特性,如自定义图标、颜色、标签、折线样式、填充样式等,使得地理数据的展示更加直观和动态。
  • KML 常用于创建和分享地理注释、路径、边界以及其他地理信息,也常用于制作地理信息系统的交互式演示。

KML 更侧重于地理数据的可视化和分享,它在Google Earth等虚拟地球软件中使用广泛,适合普通用户创建和浏览地理信息。

地图服务

地图服务是指在网络环境下提供地图数据和相关功能的服务。这些服务通常通过标准的网络协议,如HTTP或HTTPS,允许用户访问、检索和使用地理空间数据。

地图服务的目的是使地理信息能够在不同的平台和设备上被共享和利用,而无需用户直接处理原始的地理数据文件。

地图服务通常包括以下几种类型:

  1. Web Map Service (WMS):这是一种标准的OGC(Open Geospatial Consortium)服务,用于在网络上提供地图数据作为地理参考的图片。WMS允许用户定义地图的输出格式、区域、缩放级别和图层等。

  2. Web Feature Service (WFS):WFS也是OGC的标准服务之一,它允许用户访问地理空间数据集中的地理要素(如点、线、面)。与WMS不同,WFS提供的是数据本身,而不是数据的图片表示。

  3. Web Coverage Service (WCS):WCS用于在网络上传输覆盖数据,这些数据通常是由栅格构成的,如卫星图像或数字高程模型。

  4. Web Map Tile Service (WMTS):WMTS是为现代网络地图应用提供高效地图瓦片的服务。它定义了一种用于传输预渲染地图瓦片的方式,这些瓦片可以被客户端应用程序快速加载和显示。

  5. GeoJSON:虽然不是服务,但GeoJSON是一种基于JSON的轻量级数据交换格式,它被广泛用于在网络上传输简单的地理数据。

  6. KML (Keyhole Markup Language):这是Google Earth使用的一种数据格式,用于在网络上共享地理数据和创建丰富的地理信息表现。

  7. Tile Map Service (TMS):TMS是一种用于提供地图瓦片的服务,它通常与WMS或WMTS一起使用,以支持地图客户端的无缝缩放和平移。

地图服务使得开发者可以在他们的应用程序中嵌入地图,添加地理数据层,进行空间查询和分析,而无需自己管理和维护地理信息系统。这些服务通常由GIS数据提供商、政府机构或企业通过他们的服务器提供。

在选择地图服务商时,开发者会考虑服务的覆盖范围、数据更新频率、易用性、成本以及是否符合特定需求等因素。

国内外比较主流的地图服务商包括:

  1. 谷歌地图(Google Maps):提供全球地图服务,包括导航、卫星图像和街道视图等功能,是全球广泛使用的地图服务之一。

  2. 百度地图:中国领先的地图服务商,提供地图浏览、地点搜索、路线规划、导航、路况信息等服务。

  3. 高德地图:阿里巴巴集团旗下的地图服务,提供地图浏览、地点搜索、路线规划、导航、实时路况等服务。

  4. 腾讯地图:腾讯公司提供的地图服务,同样提供地图浏览、地点搜索、路线规划、导航等功能。

  5. HERE地图:原诺基亚地图,现为独立公司,提供全球地图数据和服务,被用于多种汽车和移动设备中。

  6. OpenStreetMap(OSM):一个由志愿者贡献的地图项目,提供全球范围内的地图数据,数据可自由使用。

  7. 四维图新:中国领先的数字地图内容和服务提供商,提供导航地图、位置大数据和车联网服务。

  8. Yandex地图:俄罗斯最大的搜索引擎公司Yandex提供的地图服务,主要服务于俄罗斯和周边国家。

  9. 天地图:中国国家地理信息公共服务平台,提供权威、准确的地理信息数据服务。

  10. Mapbox:一个地图数据服务平台,允许用户自定义地图样式并嵌入到自己的应用中。

这些服务商通常通过API或SDK的形式,为开发者提供地图数据和相关服务的接入,使得开发者可以在自己的应用中集成地图功能。

瓦片图层

瓦片图层TileLayer是GIS应用中用于地图可视化的一种技术,特别是在Web GIS应用中,尤其是在使用瓦片地图服务(如OpenStreetMap或Google Maps API)时,它是最基本的地图图层类型。

TileLayer是前端地图应用的基础,通过加载和拼接预渲染的地图图块,使得地图可以流畅地展示、缩放和交互。无论是显示基本的道路信息,还是高精度的卫星图像,TileLayer 都是最常用的地图数据展现方式。

TileLayer(瓦片图层)是将地图分割成多个小的、预渲染的图块(tiles),这些图块通常是正方形的图像(通常为 256x256 像素),根据不同的缩放级别分别加载并拼接起来。这样做的好处是:

  • 提高效率:只加载用户当前视野内的地图部分,而不是一次性加载整个地图,减少网络传输量。
  • 支持多级缩放:根据不同的缩放级别,显示不同的细节层次。
  • 平滑缩放和导航:当用户在地图上缩放或移动时,新的地图图块会在后台动态加载,保持地图的流畅性。

TileLayer 使用的基本原理是将整个地图按缩放级别切割成多个小图块,然后根据用户的视角来动态加载和显示这些图块。

  • 缩放级别(zoom level):地图根据不同的缩放级别展示不同的细节。缩放级别越高,图块的数量就越多,显示的细节越丰富。
  • 瓦片坐标:每个瓦片(tile)都有对应的 x 和 y 坐标,结合缩放级别(z),确定要加载的具体图块。

可以把地图的展示过程想象成下面的伪代码

js
// TileLayer sever保存了具体的tile图片和位置的映射关系
const images = findImage(longitude and latitude, zomm level)
render(images)

不同的地图服务提供不同的 TileLayer,下面是常见的一些类型:

  • OpenStreetMap:开源的全球地图服务。
  • Mapbox:提供高性能、高定制化的地图服务(需要 API 密钥)。
  • Google Maps:Google 的地图服务。
  • Bing Maps:微软提供的地图服务。

你也可以使用自定义的瓦片服务器提供地图服务。例如,你可以自定义地图样式、添加特殊图层(如等高线图、卫星图等),或者自建瓦片服务器来提供内部地图。瓦片地图需要准备大量的地图素材,还需要保证地图的更新,工作量想来应该不会少。

OpenStreetMap

OpenStreetMap 是一个全球性、开源的地图项目,由全球用户编辑和维护,它类似于 Google Maps,但完全免费和开放,允许用户以不同的方式使用和自定义地图数据。

OpenStreetMap 是一个众包式的地理信息数据库,用户可以贡献地图信息,比如道路、建筑物、公园、河流等。所有这些数据都可以公开获取,并且允许用于开发地图应用,创建自定义地图视图,或者分析地理数据。

在前端 GIS 开发中,OpenStreetMap 通常被用作底图(Base Map),即地图应用的基础图层,用于显示城市道路、地标、建筑物等信息。基于这个底图,可以叠加其他图层,比如路径、标记或数据可视化。

图层的作用包括:

  • 底图功能:提供基础地理信息,如道路、建筑物、水体等,作为应用的地图背景。
  • 交互功能:OpenStreetMap 图层支持用户交互(如缩放、平移),让用户能够在不同的缩放级别查看地图。
  • 实时更新:因为 OpenStreetMap 是开源的,用户可以随时更新数据,最新的地理信息会很快反映在地图上。

在使用 GIS 库如 Leaflet 时,可以很方便地通过调用 OpenStreetMap 提供的瓦片地图(Tile Map)作为地图图层。Leaflet 会通过 URL 格式从 OpenStreetMap 的服务器获取地理瓦片数据(实际上就是一些图片),并将这些瓦片拼接成完整的地图显示在网页中。

js
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
}).addTo(map);
  • {s}:表示服务器子域名(a、b、c等)。
  • {z}:表示缩放级别(zoom level),数值越大,地图细节越精细。
  • {x}{y}:代表地图瓦片的 x 和 y 坐标,随着缩放级别变化而变化。

关于Leaflet的具体使用会在后面的章节介绍

小结

地图服务是提供实际地图数据的后端服务,服务商提供了付费或者免费的API接口,可以通过 API 获取地图瓦片或其他数据,结合前端库展示在应用中。

地图库

在Web中从0开始展示地图是很复杂的功能,好在社区已经有很多优秀的前端 JavaScript 库。

在实际开发中,需要选择一个地图服务商,获取到对应的地图数据,然后前端就可以选择合适的工具库将数据渲染的web上面。

Leaflet

Leaflet一个轻量级的开源 JavaScript 库,它为开发者提供了绘制地图、添加标记、创建图层、处理事件等功能,适合初学者使用。

下面是一个简单的例子

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Leaflet 基础地图</title>
    <!-- 引入 Leaflet 的 CSS -->
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <style>
        #map {
            height: 400px;
            width: 100%;
        }
    </style>
</head>
<body>

    <h1>Leaflet 地图示例</h1>
    <!-- 创建一个容器来显示地图 -->
    <div id="map"></div>

    <!-- 引入 Leaflet 的 JavaScript -->
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script>
        const chengduPos = [30.67, 104.06] // [纬度,经度]
        // 初始化地图,设置中心点和缩放级别
        var map = L.map('map').setView(chengduPos, 13);

        // 添加 OpenStreetMap 图层
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
        }).addTo(map);

        // 添加一个标记
        var marker = L.marker(chengduPos).addTo(map);

        // 为标记添加弹出框
        marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
    </script>

</body>
</html>

代码比较好理解,初始化地图,加载tileLayer,然后在地图上添加自定义标记

OpenLayers

OpenLayers是一个功能更丰富的地图库,支持更复杂的 GIS 功能,如 WMS(Web Map Service)、矢量数据处理等,可以处理更大范围的地图数据和自定义图层。

下面是官方文档里面的demo演示

js
import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js'; // 也是OpenStreetMap
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';

const map = new Map({
  layers: [
    new TileLayer({
      source: new OSM(),
    }),
  ],
  target: 'map',
  view: new View({
    center: [0, 0],
    zoom: 2,
  }),
});

document.getElementById('zoom-out').onclick = function () {
  const view = map.getView();
  const zoom = view.getZoom();
  view.setZoom(zoom - 1);
};

document.getElementById('zoom-in').onclick = function () {
  const view = map.getView();
  const zoom = view.getZoom();
  view.setZoom(zoom + 1);
};

可以看见OpenLayers的模块化拆分做的比较好。

Mapbox GL JS

Mapbox GL JS文档

这是一个更加高级的库,支持 3D 地图渲染,适用于高性能地图应用的开发,支持高度自定义的图层来源。

此外还有Cesium、ArcGIS等工具库,可以查阅相关文档,根据实际需求选择合适的内容。

小结

在web的GIS开发中,需要先基础的概念如坐标系、数据格式,然后需要了解主流的地图服务和地图库。

  • 地图服务是提供实际地图数据的后端服务,不负责地图展示和交互等逻辑

  • 前端地图库本身不包含地图数据。为了展示地图,它们需要从地图服务获取数据(通常是通过 API 请求瓦片图层或矢量数据)

在实际开发中,前端地图库负责将获取的数据在网页中渲染出来,并提供交互功能(如缩放、平移、标记等),而地图服务负责维护和提供最新的地图数据。

这种前后端分离的架构使得开发者可以灵活选择不同的地图服务,并根据需求搭配合适的前端地图库。

你要请我喝一杯奶茶?

版权声明:自由转载-非商用-保持署名和原文链接。

本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。