在react中使用OpenLayers (二)

695 阅读2分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

一、前言

最近由于项目需要,需要在react项目中使用地图功能,所以决定使用openlayers进行开发,由于网上对于在react function components中使用OpenLayers 的文章并不多,网上大部分的文章都是用class组件写的,所以来分享一下使用的方法。由于地图需要在内网使用所以需要使用到本地瓦片,还将介绍搭建本地瓦片文件服务。

二、实现步骤

1、实现瓦片文件服务

首先下载瓦片文件图片

这里提供合肥市的瓦片

链接:pan.baidu.com/s/11cUTcPnq… 提取码:s17x

这里使用http-server开启文件服务也可以使用nginx或者tomcat,在相应的瓦片文件下打开powershell输入npx http-server(需要安装node)

image-20220126170109969

在浏览器输入ip+端口显示已经成功,能够读取相应的瓦片文件

2、替换线上瓦片为本地瓦片

具体实现将layer图层的source改成本地瓦片并计算相应文件名称

import React, { useState, useRef,useEffect } from 'react';
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import XYZ from 'ol/source/XYZ'
import OSM from 'ol/source/OSM';
import { transform } from "ol/proj";
import './map.css'
import { Style, Fill, Stroke, Circle as sCircle } from 'ol/style';
import { Feature } from 'ol';
import { Point } from 'ol/geom';
import * as olProj from 'ol/proj';
function MapWrapper(props) {
    let centerPos = transform([117.29, 31.85], 'EPSG:4326', 'EPSG:3857');
    // openlayers将会渲染进这个div
    const mapElement = useRef()
    let map = null; //地图全局变量
    function zeroFill(num, len, radix) {
        var str = num.toString(radix || 10);
        while (str.length < len) {
            str = "0" + str;
        }
        return str;
    }
    useEffect(()=>{
        map = new Map({
            view: new View({
                center: centerPos,//地图中心位置
                zoom: 10,//地图初始层级
                maxZoom: 15,
                minZoom: 9
            }),
            layers: [],
            target: mapElement.current
        });
        let tileLayer = new TileLayer({
            // source: new OSM()
            source: new XYZ({
                tileUrlFunction: function (coordinate) {
                    const x = 'C' + zeroFill(coordinate[1], 8, 16);
                    const y = 'R' + zeroFill(coordinate[2], 8, 16);
                    const z = 'L' + zeroFill(coordinate[0], 2, 10);
                    return `http://172.16.1.119:8080/hefei/${z}/${y}/${x}.png`;//这里可以修改地图路径这里可以换成自己本地服务启动的ip
                },
            })
        });
        map.addLayer(tileLayer)
        setMarker(map);
    },[])

    const setMarker = () => {
        const _style = new Style({
            image: new sCircle({
                radius: 10,
                stroke: new Stroke({
                    color: '#fff',
                }),
                fill: new Fill({
                    color: '#3399CC',
                }),
            }),
        });
        const _feature = new Feature({
            geometry: new Point(olProj.fromLonLat([117.28, 31.86])),
        });
        _feature.setStyle(_style);
        const _marker = new VectorLayer({
            source: new VectorSource({
                features: [_feature],
            }),
        });
        map.addLayer(_marker);
    };

    return (
        <div ref={mapElement} className="map-container"/>
    )
}

export default MapWrapper

image-20220126171605433

如图显示出替换后的瓦片文件及为成功替换,可以在内网使用地图