使用Leaflet查找最近的坐标点:计算与JSON数据集中自行车站点距离

使用Leaflet查找最近的坐标点:计算与JSON数据集中自行车站点距离

同时,确保你有一个包含自行车站点信息的json文件(例如 citybike.json),其结构类似于以下示例:

{    "stationBeanList": [        {            "id": 72,            "stationName": "W 52 St & 11 Ave",            "availableDocks": 32,            "totalDocks": 39,            "latitude": 40.76727216,            "longitude": -73.99392888,            "statusValue": "In Service",            "statusKey": 1,            "availableBikes": 6,            "stAddress1": "W 52 St & 11 Ave",            "stAddress2": "",            "city": "",            "postalCode": "",            "location": "",            "altitude": "",            "testStation": false,            "lastCommunicationTime": null,            "landMark": ""        },        {            "id": 76,            "stationName": "1st & Houston",            "availableDocks": 23,            "totalDocks": 30,            "latitude": 41.76727216,            "longitude": -74.99392888,            "availableBikes": 7        },        {            "id": 12,            "stationName": "White plains",            "availableDocks": 12,            "totalDocks": 22,            "latitude": 51.76727216,            "longitude": 1.99392888,            "availableBikes": 10        }    ]}

2. 计算距离的函数

我们将使用Haversine公式来计算两个坐标点之间的距离。以下是一个JavaScript函数,用于计算地球上两点之间的距离(以米为单位):

function getDistance(lat1, lon1, lat2, lon2, unit = 'M') {  const R = 6371e3; // 地球半径(米)  const φ1 = lat1 * Math.PI/180;  const φ2 = lat2 * Math.PI/180;  const Δφ = (lat2-lat1) * Math.PI/180;  const Δλ = (lon2-lon1) * Math.PI/180;  const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +            Math.cos(φ1) * Math.cos(φ2) *            Math.sin(Δλ/2) * Math.sin(Δλ/2);  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));  const d = R * c; // 距离(米)  if (unit === 'km') return d * 0.001;  if (unit === 'mi') return d * 0.0006213712;  return d;}

这个函数接受两个坐标点的纬度和经度,以及一个可选的单位参数(默认为米)。 你也可以选择返回公里或英里。

3. 查找最近站点的函数

接下来,创建一个函数,该函数接受起始坐标、站点列表和单位,并返回按距离排序的站点列表:

function getStationDistances(locLat, locLng, stationsList, unit = 'mi') {  return stationsList.map(station => {    const {      id,      stationName: name,      latitude: sLat,      longitude: sLng,      availableDocks    } = station;    const distance = Number.parseFloat((Math.round(getDistance(      locLat,      locLng,      sLat,      sLng,      unit) * 100) / 100).toFixed(2));    return {      id,      name,      distance,      unit,      sLat,      sLng,      availableDocks    };  }).sort((a, b) => a.distance > b.distance);}

这个函数使用 map 方法遍历站点列表,计算每个站点与给定坐标之间的距离,并将结果存储在一个新的对象中。 然后,使用 sort 方法按距离对结果进行排序。

4. 在Leaflet地图上应用

现在,让我们将这些函数应用到Leaflet地图上。 首先,创建一个地图实例:

var map_var = L.map('map_id').setView([40.72730240765651, -73.9939667324035], 16);L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {    attribution: '© OpenStreetMap contributors'}).addTo(map_var);var startPosition = L.latLng();var endPosition = L.latLng();L.Routing.control({    waypoints: [        startPosition,        endPosition,    ],    routeWhileDragging: true,    collapsible: true,    geocoder: L.Control.Geocoder.nominatim()}).addTo(map_var);

然后,使用 $.getJSON 方法加载JSON数据,并调用 getStationDistances 函数来查找最近的站点:

$.getJSON("citybike.json", function (json1) {    const locationLat = 40.72730240765651; // 起始纬度    const locationLng = -73.9939667324035; // 起始经度    const nearestStations = getStationDistances(locationLat, locationLng, json1.stationBeanList, 'mi');    // 输出最近的站点    console.log(nearestStations);    // 在地图上标记站点    nearestStations.forEach(station => {        const marker = L.marker([station.sLat, station.sLng]);        marker.addTo(map_var).bindPopup(`${station.name}
Distance: ${station.distance} ${station.unit}
Available Docks: ${station.availableDocks}`); });});

这段代码首先定义了起始坐标。 然后,它调用 getStationDistances 函数,并将结果存储在 nearestStations 变量中。 最后,它遍历 nearestStations 数组,并在地图上标记每个站点,并显示一个包含站点名称、距离和可用停靠点的弹出窗口。

5. 完整示例代码

    Leaflet Nearest Station                        #map_id { height: 500px; }        
var map_var = L.map('map_id').setView([40.72730240765651, -73.9939667324035], 16); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map_var); function getDistance(lat1, lon1, lat2, lon2, unit = 'M') { const R = 6371e3; // 地球半径(米) const φ1 = lat1 * Math.PI/180; const φ2 = lat2 * Math.PI/180; const Δφ = (lat2-lat1) * Math.PI/180; const Δλ = (lon2-lon1) * Math.PI/180; const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ/2) * Math.sin(Δλ/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); const d = R * c; // 距离(米) if (unit === 'km') return d * 0.001; if (unit === 'mi') return d * 0.0006213712; return d; } function getStationDistances(locLat, locLng, stationsList, unit = 'mi') { return stationsList.map(station => { const { id, stationName: name, latitude: sLat, longitude: sLng, availableDocks } = station; const distance = Number.parseFloat((Math.round(getDistance( locLat, locLng, sLat, sLng, unit) * 100) / 100).toFixed(2)); return { id, name, distance, unit, sLat, sLng, availableDocks }; }).sort((a, b) => a.distance > b.distance); } $.getJSON("citybike.json", function (json1) { const locationLat = 40.72730240765651; // 起始纬度 const locationLng = -73.9939667324035; // 起始经度 const nearestStations = getStationDistances(locationLat, locationLng, json1.stationBeanList, 'mi'); // 输出最近的站点 console.log(nearestStations); // 在地图上标记站点 nearestStations.forEach(station => { const marker = L.marker([station.sLat, station.sLng]); marker.addTo(map_var).bindPopup(`${station.name}
Distance: ${station.distance} ${station.unit}
Available Docks: ${station.availableDocks}`); }); });

注意事项:

确保 citybike.json 文件与HTML文件位于同一目录下,或者提供正确的路径。根据你的需求调整起始坐标和单位。可以自定义弹出窗口的内容,以显示更多站点信息。

6. 总结

通过本教程,你学习了如何使用Leaflet地图库和JavaScript来计算给定坐标与JSON数据集中自行车站点之间的距离,并找到最近的站点。 你可以将这些技术应用到各种基于位置的服务中,例如查找最近的餐馆、商店或公共交通站点。

以上就是使用Leaflet查找最近的坐标点:计算与JSON数据集中自行车站点距离的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1524238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 16:37:55
下一篇 2025年12月20日 16:38:05

相关推荐

  • 基于ServiceNow目录项中引用限定符的动态筛选教程

    第一段引用上面的摘要:本文旨在解决ServiceNow目录项中引用类型变量的引用限定符无法按预期工作的问题。通过分析问题原因,并提供修改后的JavaScript代码,帮助开发者实现基于帐户动态筛选服务项目的功能,确保在目录项中只显示与所选帐户相关的服务项目。 问题分析 在ServiceNow的目录项…

    2025年12月20日
    000
  • 使用 ServiceNow 引用限定符动态过滤目录项变量

    本文旨在帮助 ServiceNow 开发者解决目录项中引用类型变量的引用限定符不生效的问题。通过本文,你将学习如何利用脚本包含和 GlideRecord,结合 sys_idIN 操作符,动态过滤引用类型变量的选项,使其仅显示与特定条件匹配的值。 问题描述 在 ServiceNow 的目录项中,我们经…

    2025年12月20日
    000
  • 在HTML页面中离线调用MathJax库的教程

    本文旨在指导开发者如何在没有互联网连接或第三方安装的情况下,在HTML页面中直接使用MathJax库渲染LaTeX公式。通过下载MathJax的精简版本,并加载相应的打包文件,可以实现在本地环境中独立运行MathJax,从而在应用程序中显示数学公式,无需依赖网络资源。本文将详细介绍具体步骤和注意事项…

    2025年12月20日
    000
  • 根据账户筛选服务项:ServiceNow 目录项中引用限定符的正确使用

    本文旨在帮助ServiceNow开发者解决在目录项中使用引用限定符时遇到的问题,特别是当需要根据账户动态筛选服务项时。我们将深入探讨如何正确配置引用限定符,并通过示例代码演示如何利用脚本包含来实现动态筛选,确保只显示与当前账户相关的服务项,从而提升用户体验和数据准确性。 在ServiceNow中,目…

    2025年12月20日
    000
  • TypeScript中的装饰器如何改变JavaScript的元编程方式?

    TypeScript 装饰器通过类型安全的元编程增强代码可读性与维护性,支持在类、方法、属性上添加元数据或修改行为。结合泛型与接口,编译时即可检查类型错误,避免误用。框架如 Angular、NestJS 利用装饰器声明组件、服务和路由,结合 reflect-metadata 实现依赖注入与自动实例化…

    2025年12月20日
    000
  • JavaScript中的正则表达式有哪些不为人知的高级技巧?

    JavaScript正则高级技巧包括:1. 使用正向/负向断言(如/(?=$)d+(?!USD)/)精准控制匹配边界;2. 命名捕获组((?…))提升可读性,便于提取结构化数据;3. 动态构建RegExp实现灵活搜索;4. replace回调函数支持智能替换,如驼峰…

    2025年12月20日
    000
  • 在Mongoose中实现好友关系:更新User Schema中的好友数组

    本文旨在指导开发者如何在Mongoose中实现用户添加好友的功能,重点讲解在接受好友请求后如何正确更新User Schema中的好友数组。同时,文章也会探讨更高效的数据结构设计方案,以及在使用事务时需要注意的关键点,确保数据一致性。 安全地处理好友请求 首先,确保在处理好友请求时,发送者ID来自已验…

    2025年12月20日
    000
  • 在 Mongoose 中实现用户添加好友功能:最佳实践指南

    本文旨在指导开发者如何在 Mongoose 中实现用户添加好友的功能,重点讨论了如何处理好友请求、更新用户的好友列表,以及避免潜在的数据一致性问题。文章将探讨使用 FriendRequest 模型来管理好友关系,并分析直接在 User 模型中维护好友列表的优缺点,同时提供相应的代码示例和注意事项。 …

    2025年12月20日
    000
  • 如何在用户模式中向好友数组添加用户

    本文旨在指导开发者如何在用户接受好友请求后,将其信息添加到对方用户模式的 friends 数组中。文章将讨论避免前端篡改用户ID的措施,并通过 FriendRequest 模型查询好友列表,同时也会介绍如何在接受好友请求时更新用户模式,并强调使用事务以保证数据一致性的重要性。 确保用户ID的安全性 …

    2025年12月20日
    000
  • 在 Mongoose 中实现用户添加好友功能

    本文旨在指导开发者如何在 Mongoose 中实现用户添加好友的功能,并探讨了维护用户好友关系的不同策略。重点介绍如何安全地处理好友请求,以及在用户接受好友请求后,如何正确更新用户模式中的好友数组。同时,也讨论了使用额外数组存储好友关系的必要性,并提出了更优的查询方案。 安全地处理好友请求 在处理好…

    2025年12月20日
    000
  • JavaScript中防止函数推入数组时立即执行

    本文旨在解决JavaScript中将函数推入数组时函数立即执行的问题。通过将函数包装成匿名函数,可以延迟函数的执行,直到使用Promise.all()等方法需要执行它们时才真正调用。本文将提供详细的示例代码,演示如何避免函数立即执行,并确保它们仅在需要时才被调用。 在JavaScript中,当我们将…

    2025年12月20日
    000
  • JavaScript 中如何避免函数在推入数组时立即执行

    本文旨在解决 JavaScript 中函数被推入数组时立即执行的问题。通过将函数包装在匿名函数中,可以延迟函数的执行,确保函数仅在需要时(例如使用 Promise.all())才被调用。本文将提供详细的示例代码和解释,帮助开发者理解和应用这种技术,从而更有效地管理异步操作。 在 JavaScript…

    2025年12月20日
    000
  • JavaScript 中避免函数推入数组时立即执行

    本文旨在解决 JavaScript 中函数推入数组时立即执行的问题。通过将函数引用而非函数调用推入数组,并结合 Promise.all() 方法,可以实现函数的延迟执行,从而更好地控制异步任务的执行时机。本文将提供详细的示例代码和解释,帮助读者理解和应用这一技巧。 在 JavaScript 中,当我…

    2025年12月20日
    000
  • 使用 Shiny 和 Sortable 创建可滚动 Bucket List

    本文将指导你如何使用 Shiny 和 Sortable.js 库创建一个具有固定高度和滚动条的 bucket list。通过添加 CSS 样式来限制容器高度,并设置 overflow 属性,即可实现当列表项过多时,在容器右侧显示滚动条的效果。 实现可滚动 Bucket List 的步骤 以下步骤将详…

    2025年12月20日
    000
  • 使用 Mongoose 更新用户的好友列表:最佳实践指南

    本文旨在指导开发者如何在使用 Mongoose 构建社交应用时,正确地更新用户的好友列表。文章将探讨如何安全有效地处理好友请求的接受流程,并讨论维护用户好友列表的不同策略,包括直接在 User Schema 中维护以及通过查询 FriendRequest Schema 间接获取。同时,本文将强调数据…

    2025年12月20日
    000
  • JavaScript中避免函数推入数组时立即执行

    本文旨在解决 JavaScript 中函数被推入数组时立即执行的问题。通过将函数包装成匿名函数,可以延迟函数的执行,直到使用 Promise.all() 等方法需要执行时才调用。本文将提供详细的示例代码和解释,帮助开发者理解并掌握如何避免函数被立即执行,从而更好地控制异步操作。 在 JavaScri…

    2025年12月20日
    000
  • 解决 ApexCharts 中日期时间轴梯度填充颜色错位问题

    本文针对 ApexCharts 中在使用 axistype-datetime 的日期时间轴并应用梯度填充时,颜色错位的问题提供了两种解决方案。第一种方案通过计算每个数据点对应的时间戳来精确控制梯度颜色;第二种方案则利用垂直梯度,并根据Y轴的最大值来定义颜色分界点,从而实现颜色的正确对齐。通过本文的学…

    2025年12月20日
    000
  • JavaScript 中防止函数被立即执行并延迟到 Promise.all 执行

    第一段引用上面的摘要: 本文旨在解决 JavaScript 中将函数推入数组时函数被立即执行的问题,并提供解决方案以确保函数仅在 Promise.all() 执行时才被调用。通过将函数引用推入数组,而非直接调用函数,可以实现延迟执行,从而更好地控制异步操作的执行时机。本文将提供详细的代码示例和解释,…

    2025年12月20日
    000
  • 优化OpenAI API:解决GPT应用中意外代码生成问题

    本教程旨在解决使用OpenAI GPT-3.5 API(如text-davinci-003)时,模型意外生成无关代码的问题。文章强调了选择更适合代码生成任务的模型(如gpt-3.5-turbo或gpt-4)的重要性,并深入探讨了通过优化提示词(Prompt Engineering)来提升模型响应质量…

    2025年12月20日
    000
  • Shiny Sortable列表滚动实现教程

    本教程详细介绍了如何在Shiny应用中使用sortable包创建可滚动的列表(rank_list)。核心解决方案是通过CSS样式属性max-height和overflow-y: auto来控制列表容器的高度和溢出行为,从而在内容超出指定高度时自动显示滚动条。文章提供了完整的Shiny应用示例代码,并…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信