OpenLayers 地图定位

news2025/6/7 23:49:37

注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key

地图定位功能很常见,在移动端和PC端都需要经常用到,像百度、高德、谷歌都提供了方便快捷的定位功能。OpenLayers中也提供了定位的接口,通过ol.Geolocation即可实现地图定位功能。虽然OpenaLayers提供了定位类,但是在PC上的定位效果并不是很完善。本节主要介绍加载地图地图定位

1. 创建定位导航对象

在导航定位类中设置最终参数。

// 创建定位导航对象
const geolocation = new ol.Geolocation({
    projection: map.getView().getProjection(),
    tracking: true,  // 开启定位追踪
    trackingOptions: {
        maximumAge: 10000,
        enableHighAccuracy: true, // 是否开启高精度
        timeout: 600000 // 最大等待时间,微秒
    }
})

2. 监听位置事件

当位置信息改变时,更新导航数据。在定位过程中,监听定位错误事件,输出错误信息。

// 添加定位change事件
geolocation.on('change', evt => {
    $('#accuracy').text(geolocation.getAccuracy() + ' [m]');
    $('#altitude').text(geolocation.getAltitude() + ' [m]');
    $('#altitudeAccuracy').text(geolocation.getAltitudeAccuracy() + ' [m]');
    $('#heading').text(geolocation.getHeading() + ' [rad]');
    $('#speed').text(geolocation.getSpeed() + ' [m/s]');
})

// 定位错误处理事件
geolocation.on('error', error => {
    console.error("定位错误:", error.message)
})

// 定位导航事件位置变更处理
geolocation.on('change:position', () => {
    const coordinates = geolocation.getPosition()
    positionPoint.setGeometry(coordinates ? new ol.geom.Point(coordinates) : null)
})

3. 地图定位

通过获取地图中心点进行定位,并更新中心点坐标。

const lonInput = document.querySelector(".lon-input")
const latInput = document.querySelector(".lat-input")
document.querySelector(".map-center").addEventListener('click', evt => {
    const center = map.getView().getCenter()
    lonInput.value = center[0]
    latInput.value = center[1]
})

根据地图中心点坐标跳转到定位位置。

document.querySelector(".navigator-location").addEventListener('click', evt => {
    if (lonInput.value && latInput.value) {
        removeLayerByName("centerPoint")
        const center = [+lonInput.value, +latInput.value]
        map.getView().animate({ center: center, zoom: 15 })
        const point = new ol.layer.Vector({
            source: new ol.source.Vector({
                features: [
                    new ol.Feature({
                        geometry: new ol.geom.Point(center)
                    })
                ]
            }),
            style: new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 5,
                    fill: new ol.style.Fill({
                        color: 'red'
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'red'
                    })
                })
            })
        })
        point.setProperties({ layerName: 'centerPoint' })
        map.addLayer(point)
    }
})

4. 完整代码

其中libs文件夹下的包需要更换为自己下载的本地包或者引用在线资源。

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>地图定位</title>
    <meta charset="utf-8" />
    <script src="../libs/js/ol-5.3.3.js"></script>
    <script src="../libs/js/jquery-2.1.1.min.js"></script>
    <link rel="stylesheet" href="../libs/css//ol.css">
    <style>
        * {
            padding: 0;
            margin: 0;
            font-size: 14px;
            font-family: '微软雅黑';
        }

        html,
        body {
            width: 100%;
            height: 100%;
        }

        #map {
            position: absolute;
            top: 50px;
            bottom: 0;
            width: 100%;
        }

        #lcoation {
            position: absolute;
            width: 100%;
            height: 50px;
            background: linear-gradient(135deg, #ff00cc, #ffcc00, #00ffcc, #ff0066);
            color: #fff;
        }

        .map-location {
            position: absolute;
            top: 50%;
            left: 63%;
            transform: translateY(-50%);
            border-radius: 5px;
            border: 1px solid #50505040;
            padding: 5px 20px;
            color: #fff;
            margin: 0 10px;
            background: #377d466e;
        }

        .map-location:hover {
            cursor: pointer;
            filter: brightness(120%);
            background: linear-gradient(135deg, #c850c0, #4158d0);
            transition-delay: .25s;
        }

        .active {
            background: linear-gradient(135deg, #c850c0, #4158d0);
        }

        .navigator {
            position: absolute;
            line-height: 50px;
            left: 55%;
        }

        .navigator-location {
            border-radius: 5px;
            border: 1px solid #50505040;
            padding: 5px 20px;
            color: #fff;
            margin: 0 10px;
            background: #377d466e;
        }

        .navigator-location:hover {
            cursor: pointer;
            filter: brightness(120%);
            background: linear-gradient(135deg, #c850c0, #4158d0);
            transition-delay: .25s;
        }

        .view-center {
            position: absolute;
            line-height: 50px;
            left: 20%;
        }

        .view-center span {
            border-radius: 5px;
            border: 1px solid #50505040;
            padding: 5px 20px;
            color: #fff;
            margin: 0 10px;
            background: #377d466e;
        }

        .view-center span:hover {
            cursor: pointer;
            filter: brightness(120%);
            background: linear-gradient(135deg, #c850c0, #4158d0);
            transition-delay: .25s;
        }

        input[type='text'] {
            padding: 0 10px;
            height: 25px;
            border: none;
            border-radius: 2.5px;
        }

        input[type='text']:focus-visible {
            outline: 2px solid #8BC34A;
        }

        #location-info {
            position: absolute;
            padding: 10px;
            right: 20px;
            top: 70px;
            background-color: #0028657a;
            border-radius: 2.5px;
            color: #fff;
        }
    </style>
</head>

<body>
    <div id="map" title="地图显示"></div>
    <div id="lcoation">
        <button type="button" class="map-location">地图定位</button>
    </div>
    <div class="view-center">
        <span class="map-center">获取地图中心点</span>
        <input type="text" value="" class="lon-input">
        <input type="text" value="" class="lat-input">
    </div>
    <div class="navigator">
        <button type="button" class="navigator-location">导航定位</button>
    </div>
    <div id="location-info">
        <div id="container">
            <p>位置精度: <code id="accuracy"></code></p>
            <p>海拔高度: <code id="altitude"></code></p>
            <p>海拔精度: <code id="altitudeAccuracy"></code></p>
            <p>航向: <code id="heading"></code></p>
            <p>速度: <code id="speed"></code></p>
        </div>
    </div>
</body>

</html>

<script>
    //地图投影坐标系
    const projection = ol.proj.get('EPSG:3857');
    //==============================================================================//
    //============================天地图服务参数简单介绍==============================//
    //================================vec:矢量图层==================================//
    //================================img:影像图层==================================//
    //================================cva:注记图层==================================//
    //======================其中:_c表示经纬度投影,_w表示球面墨卡托投影================//
    //==============================================================================//
    const TDTImgLayer = new ol.layer.Tile({
        title: "天地图影像图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",
            attibutions: "天地图注记描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const TDTImgCvaLayer = new ol.layer.Tile({
        title: "天地图影像注记图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",
            attibutions: "天地图注记描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const map = new ol.Map({
        target: "map",
        loadTilesWhileInteracting: true,
        view: new ol.View({
            // center: [11421771, 4288300],
            // center: [102.6914059817791, 25.10595662891865],
            center: [104.0635986160487, 30.660919181071225],
            zoom: 10,
            worldsWrap: true,
            minZoom: 1,
            maxZoom: 20,
            projection: "EPSG:4326"
        }),
        layers: [TDTImgLayer, TDTImgCvaLayer],
        // 鼠标控件:鼠标在地图上移动时显示坐标信息。
        controls: ol.control.defaults().extend([
            // 加载鼠标控件
            // new ol.control.MousePosition()
        ])
    })
    map.on('click', evt => {
        console.log(evt.coordinate)
    })

    // 创建定位导航对象
    const geolocation = new ol.Geolocation({
        projection: map.getView().getProjection(),
        tracking: true,  // 开启定位追踪
        trackingOptions: {
            maximumAge: 10000,
            enableHighAccuracy: true, // 是否开启高精度
            timeout: 600000 // 最大等待时间,微秒
        }
    })

    // 添加定位change事件
    geolocation.on('change', evt => {
        $('#accuracy').text(geolocation.getAccuracy() + ' [m]');
        $('#altitude').text(geolocation.getAltitude() + ' [m]');
        $('#altitudeAccuracy').text(geolocation.getAltitudeAccuracy() + ' [m]');
        $('#heading').text(geolocation.getHeading() + ' [rad]');
        $('#speed').text(geolocation.getSpeed() + ' [m/s]');
    })

    // 定位错误处理事件
    geolocation.on('error', error => {
        console.error("定位错误:", error.message)
    })

    // 精确模式定位
    const accuracyFeature = new ol.Feature()
    geolocation.on("change:accuracyGeometry", () => {
        accuracyFeature.setGeometry(geolocation.getAccuracyGeometry())
    })

    // 定位点要素
    const positionPoint = new ol.Feature({
        style: new ol.style.Style({
            image: new ol.style.Circle({
                radius: 5,
                fill: new ol.style.Fill({
                    color: "yellow"
                }),
                stroke: new ol.style.Stroke({
                    color: "#blue",
                    width: 2
                })
            })
        })
    })
    // 定位导航事件位置变更处理
    geolocation.on('change:position', () => {
        const coordinates = geolocation.getPosition()
        positionPoint.setGeometry(coordinates ? new ol.geom.Point(coordinates) : null)
    })

    //创建定位点矢量图层(featuresOverlay)
    const features = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: [accuracyFeature, positionPoint]
        })
    });
    features.setProperties({ layerName: "locationLayer" })
    map.addLayer(features)

    // 定位按钮事件
    document.querySelector('.map-location').addEventListener('click', evt => {
        // 若添加了图层,则移除
        // removeLayerByName("locationLayer")
        // 启动位置跟踪
        geolocation.setTracking(true)
        navigator.geolocation.getCurrentPosition(function (position) {
            console.log(position)
            const coordinate = [position.coords.longitude, position.coords.latitude]

            map.getView().animate({ center: coordinate, zoom: 15 })
        })

    })

    const lonInput = document.querySelector(".lon-input")
    const latInput = document.querySelector(".lat-input")
    document.querySelector(".map-center").addEventListener('click', evt => {
        const center = map.getView().getCenter()
        lonInput.value = center[0]
        latInput.value = center[1]
    })

    document.querySelector(".navigator-location").addEventListener('click', evt => {
        if (lonInput.value && latInput.value) {
            removeLayerByName("centerPoint")
            const center = [+lonInput.value, +latInput.value]
            map.getView().animate({ center: center, zoom: 15 })
            const point = new ol.layer.Vector({
                source: new ol.source.Vector({
                    features: [
                        new ol.Feature({
                            geometry: new ol.geom.Point(center)
                        })
                    ]
                }),
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 5,
                        fill: new ol.style.Fill({
                            color: 'red'
                        }),
                        stroke: new ol.style.Stroke({
                            color: 'red'
                        })
                    })
                })
            })
            point.setProperties({ layerName: 'centerPoint' })
            map.addLayer(point)
        }
    })

    function removeLayerByName(layerName) {
        const layers = map.getLayers().getArray()
        layers.forEach(layer => {
            if (layer.get('layerName') === layerName) map.removeLayer(layer)
        });
    }

</script>

OpenLayers示例数据下载,请回复关键字:ol数据

全国信息化工程师-GIS 应用水平考试资料,请回复关键字:GIS考试

【GIS之路】 已经接入了智能助手,欢迎关注,欢迎提问。

欢迎访问我的博客网站-长谈GIShttp://shanhaitalk.com

都看到这了,不要忘记点赞、收藏 + 关注

本号不定时更新有关 GIS开发 相关内容,欢迎关注 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2403485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑龙江云前沿服务器租用:便捷高效的灵活之选​

服务器租用&#xff0c;即企业直接从互联网数据中心&#xff08;IDC&#xff09;提供商处租赁服务器。企业只需按照所选的服务器配置和租赁期限&#xff0c;定期支付租金&#xff0c;即可使用服务器开展业务。​ 便捷快速部署&#xff1a;租用服务器能极大地缩短服务器搭建周期…

论文解读:Locating and Editing Factual Associations in GPT(ROME)

论文发表于人工智能顶会NeurIPS(原文链接)&#xff0c;研究了GPT(Generative Pre-trained Transformer)中事实关联的存储和回忆&#xff0c;发现这些关联与局部化、可直接编辑的计算相对应。因此&#xff1a; 1、开发了一种因果干预方法&#xff0c;用于识别对模型的事实预测起…

学习设计模式《十二》——命令模式

一、基础概念 命令模式的本质是【封装请求】命令模式的关键是把请求封装成为命令对象&#xff0c;然后就可以对这个命令对象进行一系列的处理&#xff08;如&#xff1a;参数化配置、可撤销操作、宏命令、队列请求、日志请求等&#xff09;。 命令模式的定义&#xff1a;将一个…

十三、【核心功能篇】测试计划管理:组织和编排测试用例

【核心功能篇】测试计划管理&#xff1a;组织和编排测试用例 前言准备工作第一部分&#xff1a;后端实现 (Django)1. 定义 TestPlan 模型2. 生成并应用数据库迁移3. 创建 TestPlanSerializer4. 创建 TestPlanViewSet5. 注册路由6. 注册到 Django Admin 第二部分&#xff1a;前端…

手撕 K-Means

1. K-means 的原理 K-means 是一种经典的无监督学习算法&#xff0c;用于将数据集划分为 kk 个簇&#xff08;cluster&#xff09;。其核心思想是通过迭代优化&#xff0c;将数据点分配到最近的簇中心&#xff0c;并更新簇中心&#xff0c;直到簇中心不再变化或达到最大迭代次…

SmolVLA: 让机器人更懂 “看听说做” 的轻量化解决方案

&#x1f9ed; TL;DR 今天&#xff0c;我们希望向大家介绍一个新的模型: SmolVLA&#xff0c;这是一个轻量级 (450M 参数) 的开源视觉 - 语言 - 动作 (VLA) 模型&#xff0c;专为机器人领域设计&#xff0c;并且可以在消费级硬件上运行。 SmolVLAhttps://hf.co/lerobot/smolvla…

day45python打卡

知识点回顾&#xff1a; tensorboard的发展历史和原理tensorboard的常见操作tensorboard在cifar上的实战&#xff1a;MLP和CNN模型 效果展示如下&#xff0c;很适合拿去组会汇报撑页数&#xff1a; 作业&#xff1a;对resnet18在cifar10上采用微调策略下&#xff0c;用tensorbo…

AIGC赋能前端开发

一、引言&#xff1a;AIGC对前端开发的影响 1. AIGC与前端开发的关系 从“写代码”到“生成代码”传统开发痛点&#xff1a;重复性编码工作、UI 设计稿还原、问题定位与调试...核心场景的AI化&#xff1a;需求转代码&#xff08;P2C&#xff09;、设计稿转代码&#xff08;D2…

Web 3D协作平台开发案例:构建制造业远程设计与可视化协作

HOOPS Communicator为开发者提供了丰富的定制化能力&#xff0c;助力他们在实现强大 Web 3D 可视化功能的同时&#xff0c;灵活构建符合特定业务需求的工程应用。对于希望构建在线协同设计工具的企业而言&#xff0c;如何在保障性能与用户体验的前提下实现高效开发&#xff0c;…

AI Agent开发第78课-大模型结合Flink构建政务类长公文、长文件、OA应用Agent

开篇 AI Agent2025确定是进入了爆发期,到处都在冒出各种各样的实用AI Agent。很多人、组织都投身于开发AI Agent。 但是从3月份开始业界开始出现了一种这样的声音: AI开发入门并不难,一旦开发完后没法用! 经历过至少一个AI Agent从开发到上线的小伙伴们其实都听到过这种…

第三方测试机构进行科技成果鉴定测试有什么价值

在当今科技创新的浪潮中&#xff0c;科技成果的鉴定测试至关重要&#xff0c;而第三方测试机构凭借其独特优势&#xff0c;在这一领域发挥着不可替代的作用。那么&#xff0c;第三方测试机构进行科技成果鉴定测试究竟有什么价值呢&#xff1f; 一、第三方测试机构能提供独立、公…

华为云Flexus+DeepSeek征文|基于华为云Flexus X和DeepSeek-R1打造个人知识库问答系统

目录 前言 1 快速部署&#xff1a;一键搭建Dify平台 1.1 部署流程详解 1.2 初始配置与登录 2 构建专属知识库 2.1 进入知识库模块并创建新库 2.2 选择数据源导入内容 2.3 上传并识别多种文档格式 2.4 文本处理与索引构建 2.5 保存并完成知识库创建 3接入ModelArts S…

【数据结构】_排序

【本节目标】 排序的概念及其运用常见排序算法的实现排序算法复杂度及稳定性分析 1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 1.2特性…

PPT转图片拼贴工具 v4.3

软件介绍 这个软件就是将PPT文件转换为图片并且拼接起来。 效果展示 支持导入文件和支持导入文件夹&#xff0c;也支持手动输入文件/文件夹路径 软件界面 这一次提供了源码和开箱即用版本&#xff0c;exe就是直接用就可以了。 软件源码 import os import re import sys …

Chrome安装代理插件ZeroOmega(保姆级别)

目录 本文直接讲解一下怎么本地安装ZeroOmega一、下载文件在GitHub直接下ZeroOmega 的文件&#xff08;下最新版即可&#xff09; 二、安装插件打开 Chrome 浏览器&#xff0c;访问 chrome://extensions/ 页面&#xff08;扩展程序管理页面&#xff09;&#xff0c;并打开开发者…

Transformer-BiGRU多变量时序预测(Matlab完整源码和数据)

Transformer-BiGRU多变量时序预测&#xff08;Matlab完整源码和数据&#xff09; 目录 Transformer-BiGRU多变量时序预测&#xff08;Matlab完整源码和数据&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现Transformer-BiGRU多变量时间序列预测&…

新华三H3CNE网络工程师认证—Easy IP

Easy IP 就是“用路由器自己的公网IP&#xff0c;给全家所有设备当共享门牌号”的技术&#xff01;&#xff08;省掉额外公网IP&#xff0c;省钱又省配置&#xff01;&#xff09; 生活场景对比&#xff0c;想象你住在一个小区&#xff1a;普通动态NAT&#xff1a;物业申请了 …

Excel 模拟分析之单变量求解简单应用

正向求解 利用公式根据贷款总额、还款期限、贷款利率&#xff0c;求每月还款金额 反向求解 根据每月还款能力&#xff0c;求最大能承受贷款金额 参数&#xff1a; 目标单元格&#xff1a;求的值所在的单元格 目标值&#xff1a;想要达到的预期值 可变单元格&#xff1a;变…

装备制造项目管理具备什么特征?如何选择适配的项目管理软件系统进行项目管控?

国内某大型半导体装备制造企业与奥博思软件达成战略合作&#xff0c;全面引入奥博思 PowerProject 打造企业专属项目管理平台&#xff0c;进一步提升智能制造领域的项目管理效率与协同能力。 该项目管理平台聚焦半导体装备研发与制造的业务特性&#xff0c;实现了从项目立项、…

FPGA 动态重构配置流程

触发FPGA 进行配置的方式有两种&#xff0c;一种是断电后上电&#xff0c;另一种是在FPGA运行过程中&#xff0c;将PROGRAM 管脚拉低。将PROGRAM 管脚拉低500ns 以上就可以触发FPGA 进行重构。 FPGA 的配置过程大致可以分为&#xff1a;配置的触发和建立阶段、加载配置文件和建…