建立网站和小程序需要多少钱/软文营销的三个层面

建立网站和小程序需要多少钱,软文营销的三个层面,wordpress安装第二步,免费的网站如何建设目录 引言功能设计与开发步骤第一步:初始化项目与地图第二步:动态切换城市地图第三步:标记加油站位置第四步:获取用户位置并计算最近加油站第五步:城市名称解析完整代码总结 引言 在上一篇《加油站小程序实战05&#…

目录

  • 引言
  • 功能设计与开发步骤
  • 第一步:初始化项目与地图
  • 第二步:动态切换城市地图
  • 第三步:标记加油站位置
  • 第四步:获取用户位置并计算最近加油站
  • 第五步:城市名称解析
  • 完整代码
  • 总结

引言

在上一篇《加油站小程序实战05:地图加载》中,我们讲解了如何在小程序中加载地图,并实现了基础的地图显示功能。本篇,我们将进一步完善这一功能。通过一个城市切换地图的示例,展示如何根据用户选择或定位,实现动态加载城市地图,并标记城市中的加油站信息。这篇文章将详细拆解代码实现,让你理解每一步的开发思路和过程。

功能设计与开发步骤

在本次示例中,我们的目标是实现以下功能:

  1. 城市选择器:允许用户从列表中选择城市。
  2. 地图初始化:基于用户选择或定位加载对应城市的地图。
  3. 标记加油站:在地图上动态标记城市内的加油站位置。
  4. 定位与最近加油站:通过用户的定位,计算并高亮显示最近的加油站。

第一步:初始化项目与地图

在代码中,我们首先需要确保地图组件加载正确。为了使用高德地图的 API,我们需要引入相应的 JS 文件,并在页面初始化时完成地图的加载:

useEffect(() => {const loadAMap = async () => {if (!window.AMap) {const script = document.createElement("script");script.src = "https://webapi.amap.com/maps?v=2.0&key=你的key";script.async = true;script.onload = () => {initMap();};document.body.appendChild(script);} else {initMap();}};const initMap = () => {if (window.AMap) {const map = new window.AMap.Map(mapContainerRef.current, {center: defaultCityLocation, // 默认中心位置zoom: 12,mapStyle: "amap://styles/normal", // 地图样式});setMapInstance(map);}};loadAMap();
}, []);

代码解析:

  1. 高德地图 SDK 加载:通过动态插入 script 标签引入高德地图 API。
  2. 地图初始化:默认加载北京地图作为示例。

第二步:动态切换城市地图

为了实现城市切换功能,我们使用了一个下拉选择框(select),并通过状态管理来更新地图中心点和标记。

useEffect(() => {if (mapInstance) {const selectedCityData = cities.find((city) => city.name === selectedCity);if (selectedCityData) {mapInstance.setCenter(selectedCityData.location);addMarkers(selectedCityData.stations);calculateNearestStation(selectedCityData.stations);}}
}, [selectedCity, mapInstance]);

代码解析:

  1. selectedCity 状态监听:当用户选择的城市发生变化时,触发地图中心点的更新。
  2. 标记加油站:通过 addMarkers 函数将城市加油站位置标记在地图上。

第三步:标记加油站位置

为每个城市的加油站添加标记,并在标记上显示信息窗口,展示距离用户的距离:

const addMarkers = (stations) => {mapInstance.clearMap(); // 清空现有标记stations.forEach((station) => {const marker = new window.AMap.Marker({position: station.location,map: mapInstance,});const distance = calculateDistance(userLocation, station.location);const infoWindow = new window.AMap.InfoWindow({content: `<div style="padding: 10px; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"><div><strong>${station.name}</strong></div><div style="color: #666;">距当前站点 ${distance.toFixed(1)} km</div></div>`,offset: new window.AMap.Pixel(0, -40),});marker.on("click", () => {infoWindow.open(mapInstance, marker.getPosition());});if (nearestStation && nearestStation.name === station.name) {infoWindow.open(mapInstance, marker.getPosition());}});
};

代码解析:

  1. 清空标记:切换城市时,移除旧标记。
  2. 添加标记:为每个加油站生成一个 Marker。
  3. 信息窗口:显示加油站名称和与用户的距离。

第四步:获取用户位置并计算最近加油站

为了提升用户体验,我们通过浏览器定位功能获取用户的当前位置,并基于当前位置计算最近的加油站:

const getUserLocation = () => {if (navigator.geolocation) {navigator.geolocation.getCurrentPosition((position) => {const { latitude, longitude } = position.coords;setUserLocation([longitude, latitude]);fetchCityNameFromCoords(longitude, latitude);},() => {setUserLocation([111.75199, 40.84211]); // 默认呼和浩特setSelectedCity("呼和浩特市");});}
};
const calculateNearestStation = (stations) => {let nearest = null;let minDistance = Infinity;stations.forEach((station) => {const distance = calculateDistance(userLocation, station.location);if (distance < minDistance) {minDistance = distance;nearest = station;}});setNearestStation(nearest);
};

代码解析:

  1. 浏览器定位:调用 navigator.geolocation 获取用户位置。
  2. 最近加油站计算:逐一比较加油站距离,找到最近的标记。

第五步:城市名称解析

当获取到用户位置后,我们调用高德地图的逆地理编码 API,解析用户所在的城市并自动切换城市地图:

const fetchCityNameFromCoords = async (lng, lat) => {try {const response = await fetch(`https://restapi.amap.com/v3/geocode/regeo?key=你的key&location=${lng},${lat}`);const data = await response.json();if (data.status === "1" && data.regeocode) {const cityName = data.regeocode.addressComponent.city || data.regeocode.addressComponent.province;setSelectedCity(cityName);}} catch {console.error("获取城市名称失败");}
};

完整代码

import React, { useRef, useEffect, useState } from "react";export default function CitySwitcherMap(props) {const { style } = props;const mapContainerRef = useRef(null);const [selectedCity, setSelectedCity] = useState("");const [defaultCityLocation, setDefaultCityLocation] = useState([116.397428, 39.90923]); // 默认北京const [mapInstance, setMapInstance] = useState(null);const [userLocation, setUserLocation] = useState([116.397428, 39.90923]); // 默认用户位置为北京const [nearestStation, setNearestStation] = useState(null);const cities = [{ name: "北京", location: [116.397428, 39.90923], stations: [{ name: "天安门", location: [116.397428, 39.90923] }, { name: "鸟巢", location: [116.397524, 39.992424] }] },{ name: "上海", location: [121.473701, 31.230416], stations: [{ name: "外滩", location: [121.490317, 31.241638] }, { name: "陆家嘴", location: [121.502771, 31.238068] }] },{ name: "广州", location: [113.264385, 23.129112], stations: [{ name: "广州塔", location: [113.330863, 23.113455] }, { name: "白云山", location: [113.28848, 23.168778] }] },{ name: "深圳市", location: [114.057868, 22.543099], stations: [{ name: "世界之窗", location: [113.976373, 22.53332] }, { name: "欢乐谷", location: [113.998048, 22.546054] }] },{ name: "成都", location: [104.066541, 30.572269], stations: [{ name: "宽窄巷子", location: [104.062837, 30.667493] }, { name: "大熊猫基地", location: [104.138817, 30.735778] }] },{ name: "呼和浩特市", location: [111.75199, 40.84211], stations: [{ name: "大召寺", location: [111.692018, 40.812225] },{ name: "昭君墓", location: [111.930514, 40.718719] },{ name: "呼和浩特火车站", location: [111.75199, 40.841939] },{ name: "五塔寺", location: [111.695302, 40.809052] },{ name: "敕勒川草原", location: [111.81666, 40.88189] },{ name: "内蒙古博物院", location: [111.704164, 40.818445] },] },];useEffect(() => {const loadAMap = async () => {if (!window.AMap) {const script = document.createElement("script");script.src = "https://webapi.amap.com/maps?v=2.0&key=你的key";script.async = true;script.onload = () => {initMap();};document.body.appendChild(script);} else {initMap();}};const initMap = () => {if (window.AMap) {const map = new window.AMap.Map(mapContainerRef.current, {center: defaultCityLocation,zoom: 12,mapStyle: "amap://styles/normal",});setMapInstance(map);}};loadAMap();}, []);useEffect(() => {if (mapInstance) {const selectedCityData = cities.find((city) => city.name === selectedCity);if (selectedCityData) {mapInstance.setCenter(selectedCityData.location);addMarkers(selectedCityData.stations);calculateNearestStation(selectedCityData.stations);}}}, [selectedCity, mapInstance]);const addMarkers = (stations) => {mapInstance.clearMap();stations.forEach((station) => {const marker = new window.AMap.Marker({position: station.location,map: mapInstance,});const distance = calculateDistance(userLocation, station.location);const infoWindow = new window.AMap.InfoWindow({content: `<div style="padding: 10px; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"><div><strong>${station.name}</strong></div><div style="color: #666;">距当前站点 ${distance.toFixed(1)} km</div></div>`,offset: new window.AMap.Pixel(0, -40), // 调整偏移,避免遮挡标记
});marker.on("click", () => {infoWindow.open(mapInstance, marker.getPosition());});if (nearestStation && nearestStation.name === station.name) {infoWindow.open(mapInstance, marker.getPosition());}});};const calculateNearestStation = (stations) => {let nearest = null;let minDistance = Infinity;stations.forEach((station) => {const distance = calculateDistance(userLocation, station.location);if (distance < minDistance) {minDistance = distance;nearest = station;}});setNearestStation(nearest);};const calculateDistance = (start, end) => {const startLngLat = new window.AMap.LngLat(start[0], start[1]);const endLngLat = new window.AMap.LngLat(end[0], end[1]);return startLngLat.distance(endLngLat) / 1000; // 返回公里数};const getUserLocation = () => {if (navigator.geolocation) {navigator.geolocation.getCurrentPosition((position) => {const { latitude, longitude } = position.coords;setUserLocation([longitude, latitude]);fetchCityNameFromCoords(longitude, latitude);},() => {setUserLocation([111.75199, 40.84211]); // 呼和浩特setSelectedCity("呼和浩特市");});}};const fetchCityNameFromCoords = async (lng, lat) => {try {const response = await fetch(`https://restapi.amap.com/v3/geocode/regeo?key=你的key&location=${lng},${lat}`);const data = await response.json();if (data.status === "1" && data.regeocode) {const cityName = data.regeocode.addressComponent.city || data.regeocode.addressComponent.province;setSelectedCity(cityName);}} catch {console.error("获取城市名称失败");}};useEffect(() => {getUserLocation();}, []);return (<div><div style={{ marginBottom: "10px", zIndex: 999 }}><selectvalue={selectedCity}onChange={(e) => setSelectedCity(e.target.value)}style={{padding: "8px",fontSize: "14px",borderRadius: "4px",border: "1px solid #ccc",}}><option value="">请选择城市</option>{cities.map((city) => (<option key={city.name} value={city.name}>{city.name}</option>))}</select></div><divref={mapContainerRef}style={{position: "relative",width: "100%",height: "500px",marginTop: "0px",...style,}}/></div>);
}

注意事项是,地图加载和逆地址解析需要不同的key
在这里插入图片描述
在浏览器中可以看到多站点信息,点击某个站点的时候弹出窗口显示站点名称和距离信息
在这里插入图片描述

总结

本篇文章详细介绍了如何基于高德地图实现城市切换与加油站标记功能,主要涵盖了地图加载、城市切换、加油站标记以及定位等功能模块。这不仅是地图功能的进一步完善,也为后续的加油站小程序开发奠定了坚实的基础。

下一篇文章将继续完善小程序功能,探索如何实现动态数据加载与交互优化。希望这篇文章能为你提供开发思路与实践参考!

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

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

相关文章

如何在一台服务器上搭建 mongodb副本集1主2从节点

在一台服务器上搭建 MongoDB 副本集&#xff08;1 主节点 2 从节点&#xff09;可以通过运行多个 MongoDB 实例并使用不同端口和数据目录来实现。以下是详细步骤&#xff1a; 1. 准备工作 确保已安装 MongoDB。为每个实例创建独立的数据目录和日志文件。 2. 创建数据目录和…

【Mac】2025-MacOS系统下常用的开发环境配置

早期版本的一个环境搭建参考 1、brew Mac自带终端运行&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Installation successful!成功后运行三行命令后更新环境&#xff08;xxx是mac的username&a…

本地部署 DeepSeek:从 Ollama 配置到 Spring Boot 集成

前言 随着人工智能技术的迅猛发展&#xff0c;越来越多的开发者希望在本地环境中部署和调用 AI 模型&#xff0c;以满足特定的业务需求。本文将详细介绍如何在本地环境中使用 Ollama 配置 DeepSeek 模型&#xff0c;并在 IntelliJ IDEA 中创建一个 Spring Boot 项目来调用该模型…

科技查新有不通过的情况吗?为什么?

1. 科技查新有不通过的情况吗&#xff1f;为什么&#xff1f; 有。科技查新“不通过”&#xff08;即查新报告显示技术缺乏新颖性或存在侵权风险&#xff09;的情况并不罕见&#xff0c;主要原因包括&#xff1a; &#xff08;1&#xff09;技术缺乏创新性 重复开发&#xff…

Docker安装Postgres_16数据库

PostgreSQL简介 PostgreSQL 是一个功能强大、开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;以其可靠性、功能丰富性和可扩展性而闻名。它支持复杂的查询、事务完整性、并发控制以及多种数据类型和扩展功能&#xff0c;适用于各种规模的应用程序; 适用传…

文件上传漏洞:upload-labs靶场1-10

目录 文件上传漏洞介绍 定义 产生原因 常见危害 漏洞利用方式 upload-labs详解 pass-01 pass-02 pass-03 pass-04 pass-05 pass-06 pass-07 pass-08 pass-09 pass-10 文件上传漏洞介绍 定义 文件上传漏洞是指网络应用程序在处理用户上传文件时&#xff0c;没有…

探秘基带算法:从原理到5G时代的通信变革【二】Viterbi解码

文章目录 二、关键算法原理剖析2.1 Viterbi 解码2.1.1 卷积码与网格图基础**卷积码****网格图****生成多项式****理想情况下解码过程** 2.1.2 Viterbi 算法核心思想2.1.3 路径度量与状态转移机制2.1.4 算法流程与关键步骤详解2.1.5 译码算法举例与复杂度分析2.1.6 算法代码示例…

神经网络AI原理回顾

长期记忆存储在大模型的参数权重中&#xff0c;不经过推理和编码无法读取&#xff0c;且必须依赖输入的提示&#xff0c;因为大模型不会无缘无故的自言自语&#xff0c;毕竟输入层是它唯一 与外界交互的窗口。 目前个性化大模型的局限就是训练成本过高&#xff0c;除非使用RAG&…

DeepSeek开源周Day6:DeepSeek V3、R1 推理系统深度解析,技术突破与行业启示

DeepSeek 在开源周第六天再次发文&#xff0c;中文原文、官方号在知乎 DeepSeek - 知乎DeepSeek-V3 / R1 推理系统概览 - 知乎deepseek-ai/open-infra-index: Production-tested AI infrastructure tools for efficient AGI development and community-driven innovation 引言 …

时间复杂度练习题(6道题,C语言)

// 第一道int x 90;int y 100;while (y>0)if(x>100){x x -10;y--;}else x; // 第二道for (int i 0;i<n;i){for (int j 0;j<m;j){a[i][j] 0;}}// 第三道s 0;for(int i 1;i<n;i){for(int j 1;j<n;j){s B[i][j];}}sum s; // 第四道i 1;while (i<…

内网渗透信息收集linuxkali扫描ip段,收集脚本(web安全)

内网ip段扫描↓ 工具1↓ nmap -sn 192.168.128.0/24工具2↓ nbtscan 192.168.128.0/24 工具↓3 arp-scan -t 1000 192.168.128.0/24 cmd命令扫描↓ for /L %I in (1,1,255) Do ping -w 1 -n 1 192.168.128.%I | findstr "TTL" 这个命令在Windows命令提示符下使…

拼电商客户管理系统

内容来自&#xff1a;尚硅谷 难度&#xff1a;easy 目 标 l 模拟实现一个基于文本界面的 《 拼电商客户管理系统 》 l 进一步掌握编程技巧和调试技巧&#xff0c;熟悉面向对象编程 l 主要涉及以下知识点&#xff1a; 类结构的使用&#xff1a;属性、方法及构造器 对象的创建与…

SuperMap iClient3D for WebGL三维场景与二维地图联动

作者&#xff1a;Lzzzz 在城市规划&#xff0c;应急救援&#xff0c;旅游规划等项目场景中&#xff0c;普遍存在通过二维地图定位区域或路线&#xff0c;三维场景展示布局细节的情况&#xff0c;那么&#xff0c;如何使三维场景与二维地图联动起来呢&#xff0c;一起来看看如何…

win本地vscode通过代理远程链接linux服务器

时间&#xff1a;2025.2.28 1. win本地下载nmap.exe nmap官网 https://nmap.org/或者 https://nmap.org/download#windows下载win版本并安装。 2. vscode插件Remote-SSH 插件下载Remote-SSH 3. 配置 按照图中顺序配置ssh 1.点击左侧工具栏的“小电视”图标 2.点击ssh的…

基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局

生态安全是指生态系统的健康和完整情况。生态安全的内涵可以归纳为&#xff1a;一&#xff0c;保持生态系统活力和内外部组分、结构的稳定与持续性&#xff1b;二&#xff0c;维持生态系统生态功能的完整性&#xff1b;三&#xff0c;面临外来不利因素时&#xff0c;生态系统具…

Java 入门 (超级详细)

一、什么是Java Java是一种高级编程语言&#xff0c;由Sun Microsystems公司于1995年推出。Java具有跨平台性、面向对象、健壮性、安全性、可移植性等特点&#xff0c;被广泛应用于企业级应用开发、移动应用开发、大数据处理、云计算等领域。Java程序可以在不同的操作系统上运…

神经网络 - 激活函数(Swish函数、GELU函数)

一、Swish 函数 Swish 函数是一种较新的激活函数&#xff0c;由 Ramachandran 等人在 2017 年提出&#xff0c;其数学表达式通常为 其中 σ(x) 是 Sigmoid 函数&#xff08;Logistic 函数&#xff09;。 如何理解 Swish 函数 自门控特性 Swish 函数可以看作是对输入 x 进行“…

Lua | 每日一练 (5)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Lua | 每日一练 (5)题目参考答案浅拷贝深拷贝使用场景…

JavaEE--计算机是如何工作的

一、一台计算机的组成部分 1.CPU&#xff08;中央处理器&#xff09; 2.主板&#xff08;一个大插座&#xff09; 3.内存&#xff08;存储数据的主要模板&#xff09; 4.硬盘&#xff08;存储数据的主要模板&#xff09; 内存和硬盘对比&#xff1a; 内存硬盘读写速度快慢存…

电源测试系统有哪些可以利用AI工具的科技??

AI技术的发展对电源模块测试系统的影响是深远的&#xff0c;不仅协助系统提升了测试效率和精度&#xff0c;还推动了测试方法的创新和智能化。那么在电源测试系统中哪些模块可以利用AI工具实现自动化测试? 1. 自动化测试与效率提升 智能测试流程优化 AI算法可以自动优化测试…