使用OpenLayers和React在网页中添加带位置标记的地图

本文详细介绍了如何利用开源工具OpenLayers和OpenStreetMap在React项目中集成交互式地图,包含坐标转换、图层控制、标记样式定制等关键技术实现。

使用OpenLayers和React在网页中添加带位置标记的地图

本文将探索如何使用免费开源工具在网页中添加带有位置标记的简单地图,整个过程无需API密钥。我们将使用:

  • OpenLayers:用于显示地图和添加标记等功能的JavaScript库
  • OpenStreetMap (OSM):提供免费地图数据的开源项目

这两者共同构成了Google Maps等商业地图平台的全开源替代方案。

✅ 本示例基于React构建,但方法可轻松适配Vue、Angular或原生JavaScript项目。

1. 创建React项目(或使用现有项目)

推荐使用Vite模板快速搭建:

1
npm create vite@latest ol-react-app -- --template react-ts

2. 安装OpenLayers

通过npm安装:

1
npm install ol

或通过CDN引入:

1
<script src="https://cdn.jsdelivr.net/npm/ol@v10.6.0/dist/ol.js"></script>

3. 创建地图组件

src/Map.tsx中初始化地图,关键参数包括:

  • target:地图容器的HTML元素ID/ref
  • view:设置地图初始中心点和缩放级别
  • layers:包含OSM基础图层和标记矢量图层

以下是伦敦坐标标记的完整实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import React, { useEffect } from 'react';
import { Map, View, Feature } from 'ol';
import { Zoom } from 'ol/control';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
import { Point } from 'ol/geom';
import { fromLonLat } from 'ol/proj.js';
import { Style, Icon } from 'ol/style.js';
import reactSvg from './assets/pin.svg?url';

const MAP = 'map' as const;
const coordinatesLondon: [number, number] = [-0.118092, 51.509865];
const coordinates = fromLonLat(coordinatesLondon);

const feature = new Feature({
  geometry: new Point(coordinates),
});

const vectorLayer = new VectorLayer({
  source: new VectorSource({ features: [feature] }),
  style: new Style({
    image: new Icon({
      src: reactSvg,
      anchor: [0.5, 1],
    }),
  }),
});

const OSMLayer = new TileLayer({ source: new OSM() });

const MapElement: React.FC = () => {
  useEffect(() => {
    const map = new Map({
      target: MAP,
      view: new View({ center: coordinates, zoom: 12 }),
      layers: [OSMLayer, vectorLayer],
      controls: [new Zoom()],
    });
    return () => map.setTarget(undefined);
  }, []);

  return (
    <div className="mapContainer">
      <div id={MAP}></div>
      <div className="attribution">
        © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors
      </div>
    </div>
  );
};

4. 控件样式定制

通过CSS自定义缩放控件样式:

1
2
3
4
5
6
7
8
.ol-zoom {
  position: absolute;
  bottom: 35px;
  right: 10px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

5. OSM图层署名要求

必须包含OpenStreetMap贡献者署名,通常置于地图右下角。

✅ 注意:需为地图容器设置明确宽度

完整代码参见GitHub仓库:[项目链接]

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计