当前位置: 首页 > news >正文

鸿蒙OSUniApp 实现的地图定位与导航功能#三方框架 #Uniapp

UniApp 实现的地图定位与导航功能

随着移动互联网的发展,地图定位与导航功能已成为众多应用的标配。本文将详细介绍如何在 UniApp 框架下实现地图定位与导航功能,并探讨如何适配鸿蒙系统,助力开发者打造更加流畅的地图体验。

前言

最近在做一个外勤签到应用,需要实现地图定位、标记和导航功能。由于产品需要覆盖安卓、iOS、鸿蒙等多个平台,我们选择了UniApp作为开发框架。其中对鸿蒙系统的适配是一个新挑战,经过一番摸索,总结出了一套可行的实现方案,今天就把这个过程分享给大家。

技术选型

在实现地图功能前,需要先明确技术选型:

  1. 地图服务商:高德地图、百度地图、腾讯地图
  2. UniApp地图组件:map组件 + plus.maps模块
  3. 鸿蒙系统适配:HarmonyOS地图服务

经过评估,我选择了高德地图作为底层服务,主要考虑因素有:

  • 高德地图在国内覆盖面广,数据相对精准
  • 接口丰富,满足定位、标记、路线规划等需求
  • 与鸿蒙系统兼容性较好,HMS Core中的地图服务与高德地图接口相似
  • uniapp对高德地图支持较好

环境准备

在正式开发前,我们需要完成以下准备工作:

  1. 创建UniApp项目
  2. 申请高德地图开发者账号并创建应用,获取Key
  3. 配置SDK权限

高德地图Key申请

  1. 注册高德开发者账号:https://lbs.amap.com/
  2. 创建应用,分别为Android和iOS平台申请Key
  3. 鸿蒙系统可以使用Android的Key,或者单独申请HMS Core地图服务的Key

项目配置

manifest.json中配置相关权限和Key:

{"app-plus": {"modules": {"Maps": {}},"distribute": {"android": {"permissions": ["<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>","<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>","<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>","<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>","<uses-permission android:name=\"android.permission.INTERNET\"/>","<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>","<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>"],"abiFilters": ["armeabi-v7a", "arm64-v8a"]},"ios": {"UIBackgroundModes": ["location"],"urlSchemePrefix": "amap","maps": {"amap": {"appkey": "你的iOS平台高德Key"}}},"sdkConfigs": {"maps": {"amap": {"appkey_android": "你的安卓平台高德Key","appkey_ios": "你的iOS平台高德Key"}}}}}
}

对于鸿蒙系统,还需要额外添加HMS Core相关配置:

{"app-plus": {"distribute": {"android": {"pushconfig": {"hms": {"appid": "你的HMS Core AppID","appkey": "你的HMS Core AppKey","clientid": "你的HMS Core ClientID","clientsecret": "你的HMS Core ClientSecret"}}}}}
}

基础地图功能实现

首先,我们来实现基础的地图展示和定位功能。创建一个map.vue文件:

<template><view class="map-container"><mapid="myMap"ref="myMap"class="map":latitude="latitude":longitude="longitude":markers="markers":polyline="polyline":show-location="true":enable-3D="true":enable-traffic="enableTraffic":enable-rotate="true":enable-poi="true":scale="16"@tap="onMapTap"@markertap="onMarkerTap"></map><view class="controls"><view class="control-item" @tap="getCurrentLocation"><text class="iconfont icon-location"></text></view><view class="control-item" @tap="toggleTraffic"><text class="iconfont" :class="enableTraffic ? 'icon-traffic-on' : 'icon-traffic-off'"></text></view></view></view>
</template><script>
export default {data() {return {// 地图中心点latitude: 39.908823,longitude: 116.397470,// 标记点markers: [],// 路线polyline: [],// 是否显示路况enableTraffic: false,// 当前系统systemInfo: {},// 是否为鸿蒙系统isHarmonyOS: false};},onLoad() {// 获取系统信息this.getSystemInfo();// 初始化地图this.initMap();},methods: {// 获取系统信息getSystemInfo() {uni.getSystemInfo({success: (res) => {this.systemInfo = res;// 检测是否为鸿蒙系统this.isHarmonyOS = this.checkHarmonyOS(res);console.log('当前系统:', this.isHarmonyOS ? 'HarmonyOS' : res.platform);}});},// 检测是否为鸿蒙系统checkHarmonyOS(info) {// 鸿蒙系统检测,目前可通过brand和model判断const brand = (info.brand || '').toLowerCase();const model = (info.model || '').toLowerCase();const system = (info.system || '').toLowerCase();// 华为设备且系统为鸿蒙return (brand.indexOf('huawei') !== -1 || brand.indexOf('honor') !== -1) && (system.indexOf('harmony') !== -1 || system.indexOf('harmonyos') !== -1);},// 初始化地图async initMap() {// 请求定位权限await this.requestLocationPermission();// 获取当前位置this.getCurrentLocation();},// 请求定位权限requestLocationPermission() {return new Promise((resolve, reject) => {uni.authorize({scope: 'scope.userLocation',success: () => {console.log('定位权限请求成功');resolve();},fail: (err) => {console.error('定位权限请求失败', err);uni.showModal({title: '提示',content: '需要获取您的位置信息,请允许',success: (res) => {if (res.confirm) {uni.openSetting();}}});reject(err);}});});},// 获取当前位置getCurrentLocation() {uni.showLoading({ title: '定位中...' });uni.getLocation({type: 'gcj02',accuracy: 'high',success: (res) => {console.log('当前位置:', res);this.latitude = res.latitude;this.longitude = res.longitude;// 添加当前位置标记this.addMarker({id: 0,latitude: res.latitude,longitude: res.longitude,title: '当前位置',iconPath: '/static/images/location.png',width: 40,height: 40});uni.hideLoading();},fail: (err) => {console.error('获取位置失败', err);uni.hideLoading();uni.showToast({title: '定位失败,请检查定位权限',icon: 'none'});}});},// 添加标记点addMarker(marker) {const index = this.markers.findIndex(item => item.id === marker.id);if (index !== -1) {this.markers.splice(index, 1, marker);} else {this.markers.push(marker);}},// 地图点击事件onMapTap(e) {console.log('点击地图位置:', e);// 添加标记点this.addMarker({id: this.markers.length + 1,latitude: e.detail.latitude,longitude: e.detail.longitude,title: `标记 ${this.markers.length + 1}`,iconPath: '/static/images/marker.png',width: 30,height: 30});},// 标记点点击事件onMarkerTap(e) {const markerId = e.detail.markerId;const marker = this.markers.find(item => item.id === markerId);if (!marker) return;uni.showActionSheet({itemList: ['查看详情', '导航到这里'],success: (res) => {if (res.tapIndex === 0) {// 查看详情uni.showModal({title: marker.title,content: `位置:${marker.latitude}, ${marker.longitude}`,showCancel: false});} else if (res.tapIndex === 1) {// 导航this.openMapNavigation(marker);}}});},// 切换路况toggleTraffic() {this.enableTraffic = !this.enableTraffic;}}
};
</script><style lang="scss">
.map-container {position: relative;width: 100%;height: 100vh;.map {width: 100%;height: 100%;}.controls {position: absolute;right: 20rpx;bottom: 100rpx;display: flex;flex-direction: column;.control-item {width: 80rpx;height: 80rpx;background-color: #fff;border-radius: 50%;display: flex;align-items: center;justify-content: center;margin-bottom: 20rpx;box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.2);.iconfont {font-size: 40rpx;color: #3a86ff;}}}
}
</style>

导航功能实现

现在我们来实现导航功能,在 UniApp 中可以通过调用系统地图APP或者使用高德/百度地图SDK实现导航。下面我们添加导航相关方法:

// 添加到methods中
// 打开地图导航
openMapNavigation(destination) {// 目标位置const destinationLatitude = destination.latitude;const destinationLongitude = destination.longitude;const destinationName = destination.title || '目的地';// 鸿蒙系统处理if (this.isHarmonyOS) {this.openHarmonyMapNavigation(destinationLatitude, destinationLongitude, destinationName);return;}// 不同平台的处理方式// #ifdef APP-PLUSthis.openNativeMapApp(destinationLatitude, destinationLongitude, destinationName);// #endif// #ifdef H5this.openWebMapNavigation(destinationLatitude, destinationLongitude, destinationName);// #endif// #ifdef MP// 小程序平台使用map组件的openMapApp方法uni.openLocation({latitude: destinationLatitude,longitude: destinationLongitude,name: destinationName,scale: 18});// #endif
},// 打开原生地图应用(App端)
openNativeMapApp(latitude, longitude, name) {// 检测手机上已安装的地图应用plus.maps.getInstalledMaps((maps) => {console.log('安装的地图应用:', maps);if (maps.length === 0) {uni.showToast({title: '本机未安装地图应用',icon: 'none'});return;}// 优先使用高德地图const amap = maps.find(map => map.id === 'amap');if (amap) {plus.maps.openMap({latitude: latitude,longitude: longitude,name: name,scale: 16,mapType: plus.maps.MapType.NAVIGATION,dst: {latitude: latitude, longitude: longitude,name: name},coordType: 'gcj02',provider: 'amap'});} else {// 使用第一个可用的地图应用plus.maps.openMap({latitude: latitude,longitude: longitude,name: name,scale: 16,dst: {latitude: latitude, longitude: longitude,name: name}});}});
},// 打开Web地图导航(H5端)
openWebMapNavigation(latitude, longitude, name) {// 检测设备类型const isIOS = /iphone|ipad|ipod/i.test(navigator.userAgent);// 高德地图URLconst amapUrl = `https://uri.amap.com/navigation?to=${longitude},${latitude},${encodeURIComponent(name)}&mode=car&callnative=1`;// 百度地图URLconst bdMapUrl = `https://api.map.baidu.com/direction?destination=latlng:${latitude},${longitude}|name:${encodeURIComponent(name)}&mode=driving&origin=我的位置&coord_type=gcj02&output=html&src=webapp.baidu.openAPIdemo`;// 优先使用高德地图window.location.href = amapUrl;// 如果5秒后还在当前页面,说明没有安装高德地图APP,尝试使用百度地图setTimeout(() => {if (document.hidden || document.webkitHidden) return;window.location.href = bdMapUrl;}, 5000);
},// 鸿蒙系统地图导航处理
openHarmonyMapNavigation(latitude, longitude, name) {// #ifdef APP-PLUS// 尝试使用HMS Core地图服务// 注意:需要先集成HMS Core SDKif (plus.hms && plus.hms.map) {plus.hms.map.openMap({latitude: latitude,longitude: longitude,name: name,navigationMode: 'driving' // driving, riding, walking});return;}// 降级处理:如果HMS Core不可用,尝试使用高德地图this.openNativeMapApp(latitude, longitude, name);// #endif
}

路线规划功能

接下来,我们增加路线规划功能,实现从当前位置到目标位置的路线绘制:

// 添加到methods中
// 规划路线
planRoute(startPoint, endPoint) {uni.showLoading({ title: '规划路线中...' });// 鸿蒙系统处理if (this.isHarmonyOS) {this.planRouteForHarmonyOS(startPoint, endPoint);return;}// 调用高德地图API规划路线uni.request({url: 'https://restapi.amap.com/v3/direction/driving',data: {key: this.amapKey, // 高德地图Web服务API的Keyorigin: `${startPoint.longitude},${startPoint.latitude}`,destination: `${endPoint.longitude},${endPoint.latitude}`,extensions: 'all'},success: (res) => {uni.hideLoading();if (res.data && res.data.status === '1' && res.data.route && res.data.route.paths && res.data.route.paths.length > 0) {const path = res.data.route.paths[0];const steps = path.steps;// 解析路线坐标点let points = [];steps.forEach(step => {const stepPoints = step.polyline.split(';');stepPoints.forEach(point => {const [lng, lat] = point.split(',');points.push({longitude: parseFloat(lng),latitude: parseFloat(lat)});});});// 绘制路线this.drawRoute(points, path.distance);} else {uni.showToast({title: '路线规划失败',icon: 'none'});}},fail: (err) => {console.error('请求路线规划API失败', err);uni.hideLoading();uni.showToast({title: '路线规划失败',icon: 'none'});}});
},// 绘制路线
drawRoute(points, distance) {// 清除现有路线this.polyline = [];// 添加新路线this.polyline.push({points: points,color: '#3a86ff',width: 6,arrowLine: true,dottedLine: false});// 设置地图可视区域,以包含路线起点和终点// 获取 map 组件的实例const mapContext = uni.createMapContext('myMap', this);// 设置地图视野范围mapContext.includePoints({points: [points[0], points[points.length - 1]],padding: [80, 80, 80, 80]});// 显示路线信息uni.showModal({title: '路线信息',content: `总距离: ${(distance / 1000).toFixed(2)} 公里`,showCancel: false});
},// 鸿蒙系统路线规划
planRouteForHarmonyOS(startPoint, endPoint) {// #ifdef APP-PLUS// 如果HMS Core可用,使用HMS Core地图服务规划路线if (plus.hms && plus.hms.map && plus.hms.map.routePlan) {plus.hms.map.routePlan({start: {latitude: startPoint.latitude,longitude: startPoint.longitude},end: {latitude: endPoint.latitude,longitude: endPoint.longitude},mode: 'driving', // driving, riding, walkingsuccess: (result) => {uni.hideLoading();// 解析HMS Core返回的路线数据,格式可能与高德略有不同const points = result.paths[0].points.map(point => ({longitude: point.longitude,latitude: point.latitude}));this.drawRoute(points, result.paths[0].distance);},fail: (err) => {console.error('HMS Core路线规划失败', err);uni.hideLoading();// 降级处理:使用高德地图APIthis.planRoute(startPoint, endPoint);}});return;}// HMS Core不可用,降级处理this.planRoute(startPoint, endPoint);// #endif
}

为了完整实现路线规划功能,我们还需要在界面上添加一个规划路线的按钮。在template部分添加以下内容:

<!-- 在controls里添加规划路线按钮 -->
<view class="control-item" @tap="showRoutePlanDialog"><text class="iconfont icon-route"></text>
</view><!-- 添加路线规划对话框 -->
<uni-popup ref="routePlanPopup" type="bottom"><view class="route-plan-dialog"><view class="dialog-title">路线规划</view><view class="dialog-content"><view class="input-item"><view class="label">起点</view><view class="input"><input type="text" v-model="startPoint.name" placeholder="当前位置" disabled /></view></view><view class="input-item"><view class="label">终点</view><view class="input"><input type="text" v-model="endPoint.name" placeholder="请选择终点" @tap="selectEndPoint" /></view></view></view><view class="dialog-footer"><button class="cancel-btn" @tap="closeRoutePlanDialog">取消</button><button class="confirm-btn" @tap="confirmRoutePlan" :disabled="!endPoint.name">开始规划</button></view></view>
</uni-popup>

同时,我们需要在data中添加相关数据:

data() {return {// ... 现有数据// 起点和终点startPoint: {latitude: 0,longitude: 0,name: '当前位置'},endPoint: {latitude: 0,longitude: 0,name: ''}};
},

然后添加相关方法:

// 显示路线规划对话框
showRoutePlanDialog() {// 设置起点为当前位置this.startPoint = {latitude: this.latitude,longitude: this.longitude,name: '当前位置'};// 清空终点this.endPoint = {latitude: 0,longitude: 0,name: ''};// 显示对话框this.$refs.routePlanPopup.open();
},// 关闭路线规划对话框
closeRoutePlanDialog() {this.$refs.routePlanPopup.close();
},// 选择终点
selectEndPoint() {// 提示用户点击地图选择终点uni.showToast({title: '请点击地图选择终点',icon: 'none'});// 关闭对话框this.closeRoutePlanDialog();// 设置地图状态为选择终点this.mapState = 'selectEndPoint';
},// 确认路线规划
confirmRoutePlan() {if (!this.endPoint.name) {uni.showToast({title: '请先选择终点',icon: 'none'});return;}// 关闭对话框this.closeRoutePlanDialog();// 规划路线this.planRoute(this.startPoint, this.endPoint);
}

同时,我们需要修改onMapTap方法,以支持选择终点:

// 地图点击事件
onMapTap(e) {console.log('点击地图位置:', e);const { latitude, longitude } = e.detail;// 如果当前状态是选择终点if (this.mapState === 'selectEndPoint') {// 设置终点this.endPoint = {latitude,longitude,name: '选定位置'};// 添加终点标记this.addMarker({id: 'endPoint',latitude,longitude,title: '终点',iconPath: '/static/images/end.png',width: 30,height: 30});// 重置地图状态this.mapState = '';// 显示路线规划对话框this.showRoutePlanDialog();return;}// 正常添加标记点this.addMarker({id: this.markers.length + 1,latitude,longitude,title: `标记 ${this.markers.length + 1}`,iconPath: '/static/images/marker.png',width: 30,height: 30});
}

鸿蒙系统适配

鸿蒙系统(HarmonyOS)作为国产操作系统,已在越来越多的华为设备上使用。虽然目前鸿蒙系统对安卓应用有较好的兼容性,但仍有一些特殊之处需要注意。

1. 系统检测

鸿蒙系统检测是适配的第一步,我们已在代码中实现:

// 检测是否为鸿蒙系统
checkHarmonyOS(info) {// 鸿蒙系统检测,目前可通过brand和model判断const brand = (info.brand || '').toLowerCase();const model = (info.model || '').toLowerCase();const system = (info.system || '').toLowerCase();// 华为设备且系统为鸿蒙return (brand.indexOf('huawei') !== -1 || brand.indexOf('honor') !== -1) && (system.indexOf('harmony') !== -1 || system.indexOf('harmonyos') !== -1);
}

2. HMS Core集成

鸿蒙系统使用HMS Core(Huawei Mobile Services)替代GMS(Google Mobile Services),因此需要集成HMS Core SDK。以下是基本步骤:

  1. 注册华为开发者账号,创建应用并获取AppID等信息
  2. 下载并集成HMS Core SDK
  3. 在manifest.json中配置相关信息

3. 地图服务适配

鸿蒙系统提供了内置的地图服务,但也可以使用高德地图等第三方服务。对于完全的鸿蒙适配,建议两种方式都支持:

// 鸿蒙系统地图导航处理
openHarmonyMapNavigation(latitude, longitude, name) {// #ifdef APP-PLUS// 尝试使用HMS Core地图服务if (plus.hms && plus.hms.map) {plus.hms.map.openMap({latitude: latitude,longitude: longitude,name: name,navigationMode: 'driving'});return;}// 降级处理:如果HMS Core不可用,尝试使用高德地图this.openNativeMapApp(latitude, longitude, name);// #endif
}

4. 权限处理

鸿蒙系统的权限管理与安卓类似,但可能会有一些差异。对于地图定位功能,需要特别注意位置权限的申请:

// 请求定位权限
requestLocationPermission() {return new Promise((resolve, reject) => {uni.authorize({scope: 'scope.userLocation',success: () => {console.log('定位权限请求成功');resolve();},fail: (err) => {console.error('定位权限请求失败', err);// 对于鸿蒙系统,可能需要特殊处理if (this.isHarmonyOS) {uni.showModal({title: '定位权限申请',content: '地图功能需要获取您的位置信息,请在弹出的对话框中点击"允许"',success: (res) => {if (res.confirm) {// 鸿蒙系统的设置页面可能与安卓有所不同if (plus.os.name.toLowerCase() === 'android') {plus.runtime.openURL('hap://app/com.huawei.systemmanager/settingApp');} else {uni.openSetting();}}}});} else {uni.showModal({title: '提示',content: '需要获取您的位置信息,请允许',success: (res) => {if (res.confirm) {uni.openSetting();}}});}reject(err);}});});
}

常见问题与解决方案

在实际开发过程中,可能会遇到以下问题:

1. 定位不准确

问题描述:有时地图定位不准确,或者无法获取位置。

解决方案

  • 确保申请了高精度定位权限
  • 使用gcj02坐标系统(高德地图使用的坐标系)
  • 使用多种定位方式(GPS、网络、基站)结合
  • 在鸿蒙系统上,确保已正确配置HMS Core定位服务
// 获取高精度位置
uni.getLocation({type: 'gcj02',altitude: true, // 获取海拔信息accuracy: 'high', // 高精度定位geocode: true, // 获取地址信息success: (res) => {console.log('高精度定位结果:', res);// 处理位置信息},fail: (err) => {// 降级处理:尝试使用低精度定位uni.getLocation({type: 'gcj02',success: (lowRes) => {console.log('低精度定位结果:', lowRes);// 处理位置信息},fail: (lowErr) => {console.error('定位失败', lowErr);}});}
});

2. 鸿蒙系统下地图显示异常

问题描述:在某些鸿蒙系统设备上,地图显示异常或功能不完整。

解决方案

  • 确认已在manifest.json中配置了正确的HMS Core服务
  • 对地图组件应用特定的样式修复
  • 使用原生插件进行深度兼容
/* 鸿蒙系统地图样式修复 */
.harmony-map-fix {/* 可能需要特定设备的样式修复 */transform: translateZ(0);-webkit-transform: translateZ(0);
}

3. 导航无法打开地图应用

问题描述:点击导航按钮无法打开地图应用。

解决方案

  • 检查URL Scheme配置是否正确
  • 提供多个地图应用的支持(高德、百度、腾讯等)
  • 针对鸿蒙系统,优先使用HMS Core的地图服务
// 多地图应用支持
openMapNavigation(destination) {const { latitude, longitude, name } = destination;// 检测平台if (this.isHarmonyOS) {// 鸿蒙系统处理this.openHarmonyMapNavigation(latitude, longitude, name);return;}// 获取已安装的地图应用plus.maps.getInstalledMaps((maps) => {if (maps.length === 0) {// 没有安装地图应用,提供网页版导航window.location.href = `https://uri.amap.com/navigation?to=${longitude},${latitude},${encodeURIComponent(name)}&mode=car`;return;}// 展示可用的地图应用列表const mapList = maps.map(map => map.name);uni.showActionSheet({itemList: mapList,success: (res) => {const selectedMap = maps[res.tapIndex];// 打开选择的地图应用plus.maps.openMap({latitude: latitude,longitude: longitude,name: name,scale: 16,provider: selectedMap.id});}});});
}

总结

通过本文,我们详细介绍了如何在UniApp框架下实现地图定位与导航功能,并针对鸿蒙系统进行了适配。主要内容包括:

  1. 基础地图组件:使用UniApp的map组件实现地图展示与交互
  2. 定位功能:获取用户当前位置并显示在地图上
  3. 标记功能:在地图上添加与管理标记点
  4. 导航功能:调用系统地图应用进行导航
  5. 路线规划:使用API规划路线并在地图上绘制
  6. 鸿蒙适配:针对鸿蒙系统的特殊处理

在实际开发中,还可以根据具体需求进一步扩展功能,例如:

  • 添加地点搜索功能
  • 实现自定义地图样式
  • 增加位置共享功能
  • 支持离线地图

希望本文对你在UniApp项目中实现地图功能有所帮助,特别是在需要兼容鸿蒙系统的场景下。

相关文章:

鸿蒙OSUniApp 实现的地图定位与导航功能#三方框架 #Uniapp

UniApp 实现的地图定位与导航功能 随着移动互联网的发展&#xff0c;地图定位与导航功能已成为众多应用的标配。本文将详细介绍如何在 UniApp 框架下实现地图定位与导航功能&#xff0c;并探讨如何适配鸿蒙系统&#xff0c;助力开发者打造更加流畅的地图体验。 前言 最近在做一…...

【HarmonyOS 5】鸿蒙星闪NearLink详解

【HarmonyOS 5】鸿蒙星闪NearLink详解 一、前言 鸿蒙星闪NearLink Kit 是 HarmonyOS 提供的短距离通信服务&#xff0c;支持星闪设备间的连接、数据交互。例如&#xff0c;手机可作为中心设备与外围设备&#xff08;如鼠标、手写笔、智能家电、车钥匙等&#xff09;通过星闪进…...

Java并发编程面试题总结

目录 线程有哪几种状态?状态如何流转? 创建线程的方式? 多线程有什么应用? 线程池的好处? 线程池的七个参数? 为什么不推荐使用jdk的Executors创建线程池? 线程池的执行流程? 任务拒绝策略有哪些&#xff0c;怎么选择? 线程池的核心线程数和最大线程数怎么设定…...

LAMP项目部署实战

一、LAMP部署前期准备 1.1 关闭防火墙 # systemctl stop firewalld # systemctl disable firewalld 1.2 关闭SELinux SELinux(Security-EnhancedLinux)是美国国家安全局&#xff08;NSA&#xff09;对于强制访问控制的实现&#xff0c;是Linux历史上最杰出的新安全子系统。 …...

Dify与n8n全面对比指南:AI应用开发与工作流自动化平台选择【2025最新】

Dify与n8n全面对比指南&#xff1a;AI应用开发与工作流自动化平台选择【2025最新】 随着AI技术与自动化工具的迅速发展&#xff0c;开发者和企业面临着多种平台选择。Dify和n8n作为两个备受关注的自动化平台&#xff0c;分别专注于不同领域&#xff1a;Dify主要面向AI应用开发&…...

VBA_NZ系列工具NZ10:VBA压缩与解压工具

我的教程一共九套及VBA汉英手册一部&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到数据库&#xff0c;到字典&#xff0c;到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑&#xff0c;这么多知识点该如何组织…...

EFT不过整改思路与调试经验

EFT是如何影响EUT的&#xff1a; EFT试验是为了验证电气和电子设备对诸如来自切换瞬态过程(切断感性负载、继电器触点弹跳等)的各种类型瞬变骚扰的抗扰度。EFT干扰是在电路中感性负载断开时产生的&#xff0c;它的特点是干扰信号不是单个脉而是一连串的脉冲群。EFT 干扰可以在…...

2.安卓逆向2-adb指令

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码&#xff1…...

VSCode CMake工作流

Foreword 之前看到CMake有这么多选项&#xff0c;感觉不简单&#xff0c;还是看下别人在这里设计了多少东西 CMake 整体来说CMake遵循这样一套结构 操作-操作预设&#xff08;如果有的话&#xff09;-操作目标&#xff08;如果有的话&#xff09;比如 Configure-Configure…...

【上位机——WPF】App.xml和Application类简介

App.xml和Application类简介 概述App.xamlApp.xaml.cs 入门代码App.xamlMainWindow.xml Application生命周期窗体的声明周期 概述 xaml类型的文件包含两部分&#xff0c;一部分以.xaml扩展名结尾的前端代码&#xff0c;另一部分以.xaml.cs结尾的后端代码&#xff0c;通常我们也…...

MySQL 8.0 OCP 1Z0-908 101-110题

Q101.which two queries are examples of successful SQL injection attacks? A.SELECT id, name FROM backup_before WHERE name‘; DROP TABLE injection; --’; B. SELECT id, name FROM user WHERE id23 oR id32 OR 11; C. SELECT id, name FROM user WHERE user.id (SEL…...

Linux/Centos7离线安装并配置MySQL 5.7

文章目录 前言1、安装包下载2、卸载MariaDB3、创建MySQL用户4、上传安装包5、创建数据目录和配置文件6、安装MySQL7、启动MySQL8、初始化MySQL9、退出验证新密码10、创建普通用户和库11、测试普通用户和库总结 前言 博主参考了一些大佬的文章&#xff0c;部分收费的就看不了了&…...

在Angular中使用Leaflet构建地图应用

Leaflet是一个用于创建地图的JavaScript库&#xff0c;它包含许多功能&#xff0c;并且非常适用于移动设备。 准备 nodejs: v20.15.0 npm: 10.7.0 angular: 19.2.10 创建一个地图应用工程 npx angular/cli new my-leaflet-app --stylecss --routingfalse --skip-tests提示 …...

GPU与NPU异构计算任务划分算法研究:基于强化学习的Transformer负载均衡实践

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 引言 在边缘计算与AI推理场景中&#xff0c;GPU-NPU异构计算架构已成为突破算力瓶颈的关键技…...

iOS 抓包实战:从 Charles 到Sniffmaster 的日常工具对比与使用经验

iOS 抓包实战&#xff1a;从 Charles 到抓包大师 Sniffmaster 的日常工具对比与使用经验 抓包这件事&#xff0c;不是高级黑客才要做的。作为一名移动端开发&#xff0c;我几乎每天都要和网络请求打交道&#xff0c;尤其是 HTTPS 请求——加密、重定向、校验证书&#xff0c;各…...

【微服务】SpringBoot + Docker 实现微服务容器多节点负载均衡详解

目录 一、前言 二、前置准备 2.1 基本环境 2.2 准备一个springboot工程 2.2.1 准备几个测试接口 2.3 准备Dockerfile文件 2.4 打包上传到服务器 三、制作微服务镜像与运行服务镜像 3.1 拷贝Dockerfile文件到服务器 3.2 制作服务镜像 3.3 启动镜像服务 3.4 访问一下服…...

【Linux系统】从 C 语言文件操作到系统调用的核心原理

文章目录 前言lesson 15_基础IO一、共识原理二、回顾C语言接口2.1 文件的打开操作2.2 文件的读取与写入操作2.3 三个标准输入输出流 三、过渡到系统&#xff0c;认识文件系统调用3.1 open 系统调用1. 比特位标志位示例 3.2 write 系统调用1. 模拟实现 w 选项2. 模拟实现 a 选项…...

俄罗斯方块算法

俄罗斯方块是一款风靡全球 38 年的经典益智游戏&#xff0c;凭借其简单易学但难于精通的特点&#xff0c;成为游戏史上的不朽之作。 游戏界面与规则 游戏界面为 20 行10 列的可视区域。横向 X 轴区间为 [0&#xff0c;9]&#xff0c;共 10 列&#xff1b;纵向 Y 轴区间为 [0&a…...

Node.js 循环依赖问题详解:原理、案例与解决方案

文章目录 一、什么是循环依赖&#xff1f;二、循环依赖的典型表现三、解决方案四、如何检测循环依赖五、循环依赖的隐藏危害 一、什么是循环依赖&#xff1f; 当两个或者多个模块互相直接或者间接引用时&#xff0c;就会形成循环依赖。例如&#xff1a; A.js → 依赖 → B.js…...

Linux系统编程——vfork函数的使用方法以及与fork函数的区别

vfork() 是 Linux 系统编程中与 fork() 类似的系统调用&#xff0c;用于创建一个新的子进程。它们都能创建子进程&#xff0c;但在实现机制和使用场景上有明显区别。 以下是对 vfork() 的详细介绍&#xff0c;包括&#xff1a; 使用方法 注意事项 与 fork() 的联系与区别 使…...

.NET 无侵入自动化探针原理与主流实现详解

目录 引言 一、.NET 无侵入自动化探针的原理 1.1 CLR Profiling API 核心机制 示例代码 1.2 CLR Instrumentation 核心机制 示例代码 1.3 反射和动态代理 核心机制 示例代码 1.4 DiagnosticSource 核心机制 示例代码 二、主流实现与工具 2.1 AppDynamics 实现原…...

大数据:新能源汽车宇宙的未来曲率引擎

** 发布日期&#xff1a;2025-05-14** 关键词&#xff1a;大数据、新能源、机器学习、碳中和、CSDN爆款 1. 大数据科普&#xff1a;定义、特征与技术核心 1.1 什么是大数据&#xff1f; 大数据&#xff08;Big Data&#xff09;指规模巨大、类型多样、生成速度快且价值密度低…...

创建你的第一个MCP服务

创建你的第一个MCP服务 Model Context Protocol (MCP) 中国天气查询服务创建教程 什么是 Model Context Protocol (MCP) Model Context Protocol (MCP) 是一种开放标准协议&#xff0c;允许大型语言模型&#xff08;LLM&#xff09;如 Claude 与外部系统和数据源进行交互。通…...

说一说Node.js高性能开发中的I/O操作

众所周知&#xff0c;在软件开发的领域中&#xff0c;输入输出&#xff08;I/O&#xff09;操作是程序与外部世界交互的重要环节&#xff0c;比如从文件读取数据、向网络发送请求等。这段时间&#xff0c;也指导项目中一些项目的开发工作&#xff0c;发现在Node.js运用中&#…...

小白入门:GitHub 远程仓库使用全攻略

一、Git 核心概念 1. 三个工作区域 工作区&#xff08;Working Directory&#xff09;&#xff1a;实际编辑文件的地方。 暂存区&#xff08;Staging Area&#xff09;&#xff1a;准备提交的文件集合&#xff08;使用git add操作&#xff09;。 本地仓库&#xff08;Local…...

Protobuf3协议关键字详解与应用实例

一、核心语法与基础关键字 syntax 声明协议版本&#xff0c;必须为文件的第一行非空、非注释内容。 syntax "proto3"; // 显式指定proto3语法&#xff0c;否则编译器默认使用proto2message 定义消息类型&#xff0c;包含一组结构化字段。支持嵌套消息定义&#xff…...

阿克曼-幻宇机器人系列教程3- 机器人交互实践(Message)

上一篇文章介绍了如何通过topic操作命令实现与机器人的交互&#xff0c;本篇我们介绍如何通过Message&#xff08;即topic的下一级&#xff09;实现与机器人的交互。 和topic一样&#xff0c;首先在一个终端通过ssh命令登录机器人、启动机器人&#xff0c;然后打开另外一个终端…...

Leetcode刷题 | Day63_图论08_拓扑排序

一、学习任务 拓扑排序代码随想录 二、具体题目 1.拓扑排序117. 软件构建 【题目描述】 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依…...

[Harmony]获取资源文件中.txt文件中的字符串

txt文件 src/main/resources/rawfile/userInfo.txt {"Code": 200,"Msg": "登录成功","RetData": {"Name": "shq","Phone": "18511111111","PostName": "按摩技师",&qu…...

matlab多项式

1. 多项式表示 多项式用行向量表示&#xff0c;按降幂排列系数。例如&#xff0c;多项式 3x22x1 表示为 [3 2 1]。 2. 创建多项式 直接输入系数&#xff1a;如 p [1 -3 3 -1] 表示 x3−3x23x−1。由根创建&#xff1a;使用 poly 函数。例如&#xff0c;根为 [1, 1, 1]&…...

手搓传染病模型(SEI - SEIAR )

在传染病防控的前沿研究中&#xff0c;构建精准的数学模型对于理解疾病传播机制、预测疫情走势以及制定有效干预策略至关重要。SEI - SEIAR 模型&#xff08;易感媒介 \(S_m\) - 潜伏媒介 \(E_m\) - 感染媒介 \(I_m\) - 易感人群 S - 潜伏人群 E - 有症状感染者 I - 无症状感染…...

Ubuntu 安装 Redis

1. 下载 redis 下载地址&#xff1a;https://github.com/redis/redis 2. 解压 redis 把下载的软件包&#xff0c;上传到服务器的 /usr/local 目录中&#xff0c;执行解压命令 tar -zxvf redis-8.0.1.tar.gz 3. 安装 redis 安装依赖 sudo apt-get updatesudo apt-get ins…...

【QGIS二次开发】地图显示与交互-03

系列目录&#xff1a; 【QGIS二次开发】地图显示与交互-01_qgis二次开发加载地图案例-CSDN博客 【QGIS二次开发】地图显示与交互-02_setlayerlabeling-CSDN博客 3. 地图符号与色表 3.1 矢量图层符号设置 任务要求&#xff1a;双击图层树节点&#xff0c;实现图层中图元的符…...

28、动画魔法圣典:Framer Motion 时空奥义全解——React 19 交互动效

"在数字世界的夹缝中&#xff0c;存在着连接现实与虚拟的魔法纽带——这便是 Framer Motion 的时空秘术。" ——《前端魔法师手札卷七》 一、时空裂隙动画 - FLIP量子跃迁术 1. FLIP时空扭曲原理 <motion.divlayout // 开启时空裂隙transition{{type: "spr…...

Ken Thompson 和 Dennis Ritchie

Ken Thompson&#xff08;肯汤普逊&#xff09;和Dennis Ritchie&#xff08;丹尼斯里奇&#xff09;是计算机科学领域的两位传奇人物&#xff0c;他们对现代计算机技术的发展产生了深远影响。以下是关于他们的详细介绍&#xff1a; 1. ​​Ken Thompson​​ ​​出生​​&am…...

SQL:MySQL函数:条件函数(Conditional Functions)

目录 什么是条件函数&#xff1f; 常用 MySQL 条件函数总览表 1️⃣ IF() – 条件判断函数&#xff08;If Statement&#xff09; 2️⃣ IFNULL() – 空值判断与替代函数&#xff08;If Null&#xff09; 3️⃣ NULLIF() – 相等返回 NULL&#xff08;Null If Equal&#…...

初识Linux · IP分片

目录 前言&#xff1a; IP分片 分片vs不分片 如何分片 分片举例 三个字段 前言&#xff1a; 前文IP协议上和IP协议下我们已经把IP协议的报头的大多数字段介绍了&#xff0c;唯独有三个字段现在还有介绍&#xff0c;即16位标识&#xff0c;8位协议&#xff0c;13位片偏移…...

TCP 粘包

一、粘包问题详解 1. 粘包的概念 定义&#xff1a; 指在 TCP 通信中&#xff0c;由于发送方和接收方的读写速度、数据量不一致&#xff0c;导致多个数据包被错误地合并成一个数据包处理的现象。产生原因&#xff1a; TCP 是流式协议&#xff08;无边界&#xff09;&#xff0…...

第一个优化

agent项目 tool 调用外部服务时 选择了指数回避的重试机制 优化点&#xff1a;延迟时间那 加了一个随机的时间抖动 指数回避 我第一眼看到 这不就是 tcp重连机制吗 其实就是 如果当时网络波动 网况不好 || 服务正忙 &#xff0c;可以不急着在这个时候选择多次重试&#xff0c…...

LabVIEW的CAN通讯测试程序

该程序是基于 NI LabVIEW 平台开发的 CAN&#xff08;Controller Area Network&#xff0c;控制器局域网&#xff09;通讯测试程序。主要功能是对 CAN 通讯过程进行模拟、数据传输与验证&#xff0c;确保 CAN 通讯的正常运行和数据的准确传输。 程序详细说明 接口选择&#xff…...

视频质量分析时,遇到不同分辨率的对照视频和源视频,分辨率对齐的正确顺序。

背景 我们平时在做视频转码后&#xff0c;会用VMAF/PSNR得评分工具进行视频对比的评分&#xff0c;但是这几种客观评分方式都有一个要求就是分辨率要一模一样&#xff0c;因为这样才对像素点做数学运算。 但是分辨率对齐其实有两种选择&#xff0c;例如源视频是1080P&#xf…...

Kotlin并发请求的一些知识记录

private suspend fun fetchDataConcurrently(list: MutableList<MyType>,onRequestResult: (Int, List<MyType>?) -> Unit //高阶函数回调) {val deferredList mutableListOf<Deferred<MyType?>>()// 设定任务超时时间为12秒&#xff0c;并使用 …...

Ubuntu 编译SRS和ZLMediaKit用于视频推拉流

SRS实现视频的rtmp webrtc推流 ZLMediaKit编译生成MediaServer实现rtsp推流 SRS指定某个固定网卡&#xff0c;修改程序后重新编译 打开SRS-4.0.0/trunk/src/app/srs_app_rtc_server.cpp&#xff0c;在 232 行后面添加&#xff1a; ZLMediaKit编译后文件存放在ZLMediakit/rele…...

typora免费获取序列号

这个方法不是唯一&#xff0c;但是所需要的时长很短。废话不多说 1.下载网盘文件 通过网盘分享的文件&#xff1a;typora破解 链接: https://pan.baidu.com/s/1KQnSUV3V0uBGpLc_iz2UFQ?pwdetc4 提取码: etc4 2.把解压下来的文件放到装软件的文件夹 3. 打开cmd&#xff0c;…...

C++23 新增的查找算法详解:ranges::find_last 系列函数

文章目录 引言C Ranges 库简介ranges::find_last、ranges::find_last_if 和 ranges::find_last_if_not 概述ranges::find_last示例代码代码解释 ranges::find_last_if函数签名参数解释示例代码代码解释 ranges::find_last_if_not示例代码代码解释 使用场景总结 引言 在 C 的发…...

11.基础IO(上)

一、文件概念 对文件归类认知&#xff1a; 对于 0KB 的空文件是占用磁盘空间的 文件是文件属性&#xff08;元数据&#xff09;和文件内容的集合&#xff08;文件 属性&#xff08;元数据&#xff09; 内容&#xff09; 所有的文件操作本质是文件内容操作和文件属性操作。 …...

本地部署Firecrawl+Dify调用踩坑记录

最近自己研究Dify&#xff0c;使用到Firecrawl这个比较好用的工具。用Firecrawl官网的不知道为什么总是卡住得不到结果&#xff0c;于是我打算自己去本地部署一个。好家伙真给我人搞麻了&#xff0c;太多问题了。 我是在京东云上面租的一台服务器。 首先就是docker的安装&…...

硬盘坏了电脑会出现哪些明显现象?机械和固态可不一样

机械硬盘&#xff08;HDD&#xff09;损坏的常见表现 >启动异常&#xff1a;如果是启动盘&#xff0c;可能会遭遇系统无法启动&#xff0c;提示“No Bootable Device”“Operating System not found”或“Sector not found”等错误&#xff1b;以及BIOS无法识别硬盘&#x…...

数据驱动下的具身智能进化范式

数据驱动技术与挑战...

使用Python与正则表达式高效提取Excel中的票号数据

使用Python与正则表达式高效提取Excel中的票号数据 一、需求 本文将介绍如何利用Python的Pandas库和正则表达式&#xff0c;快速实现票号这一数据清洗任务&#xff0c;并将结果整理为规范的表格结构。 在数据处理场景中&#xff0c;从非结构化文本里提取特定格式的信息是常见…...