【HarmonyOS Next】地图使用详解(一)

news2025/3/31 6:03:39

背景


这系列文章主要讲解鸿蒙地图的使用,当前可以免费使用,并提供了丰富的SDK给开发者去自定义控件开发。目前可以实现个性化显示地图、位置搜索和路径规划等功能,轻松完成地图构建工作。需要注意的是,现在测试只能使用实体手机去做调试,模拟器和预览器是没有办法做测试和使用的

地图开发环境搭建


1. AGC中创建项目

在AGC中新建项目,并复制AGC项目中的Client ID 填写到工程中的entry模块的module.json5文件中,新增metadata,配置name为client_id,value为AGC项目中的Client ID。

请添加图片描述

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone",
      "tablet",
      "2in1"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:layered_image",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ],
    "extensionAbilities": [
      {
        "name": "EntryBackupAbility",
        "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
        "type": "backup",
        "exported": false,
        "metadata": [
          {
            "name": "ohos.extension.backup",
            "resource": "$profile:backup_config"
          }
        ],
      }
    ],
    "metadata": [
      {
        "name": "client_id",
        "value": "6917564776665168777"
      }
    ]
  }
}

2.AGC中开通地图服务

在API管理界面,打开地图服务

在这里插入图片描述

3.AGC中创建APP

在证书、APP ID和Profile中,APP ID中创建之前项目中的App

4.在项目文件中生成密钥请求文件

这个密钥文件比较重要,务必妥善保存。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这里的Alias需要记住,后面需要用到
在这里插入图片描述

保存csr文件

在这里插入图片描述

查看生成的csr文件

在这里插入图片描述

5.AGC项目中创建证书和设备

新建调试证书,并把证书下载到本地。

在这里插入图片描述

在这里插入图片描述

6.AGC项目中创建Profile

选择对应的调试证书,完成Profile的创建

在这里插入图片描述

在这里插入图片描述

7.把生成的证书和调试文件添加到项目结构中

在这里插入图片描述

在这里插入图片描述

8.确保当前IDE已经登陆了你的华为账号

在这里插入图片描述

地图组件(MapComponent)

  • 示例代码使用MVVM架构来配置

1、MapComponent组件初始化

  • 提供了两个必填参数,mapOptions和mapCallback
属性名称属性类型属性备注是否必填
mapOptionsmapCommon.MapOptions初始化参数,提供了地图类型、相机位置、地图边界等属性
mapCallbackAsyncCallback<map.MapComponentController>地图主要功能类map.MapComponentController的回调函数,提供了地图各种操作的API
  • 项目初始化框架
import { MapViewModel } from '../ViewModels/MapViewModel';
import { MapComponent } from '@kit.MapKit';

@Entry
@ComponentV2
struct FirstPage {
  @Local MapVM: MapViewModel = new MapViewModel();

  aboutToAppear(): void {
    this.MapVM.Init();
  }

  build() {
    RelativeContainer() {
      MapComponent({
        mapOptions: this.MapVM.MapOption,
        mapCallback: this.MapVM.MapCallBack
      })
        .width("100%")
        .height("100%")
        .id("Map")
    }
    .height('100%')
    .width('100%')
  }
}
  • VM中的MapOption赋值
this.MapOption = {
  //相机位置
  position: {
    target: {
      latitude: this.LocationLatitude,
      longitude: this.LocationLongitude
    },
    zoom: 10
  },
  //地图类型
  mapType: mapCommon.MapType.STANDARD,
  //地图最小图层,默认值为2
  minZoom: 2,
  //地图最大图层,默认值为20
  maxZoom: 20,
  //是否支持旋转手势
  rotateGesturesEnabled: true,
  //是否支持滑动手势
  scrollGesturesEnabled: true,
  //是否支持缩放手势
  zoomGesturesEnabled: true,
  //是否支持倾斜手势
  tiltGesturesEnabled: true,
  //是否展示缩放控件
  zoomControlsEnabled: true,
  //是否展示定位按钮
  myLocationControlsEnabled: true,
  //是否展示指南针控件
  compassControlsEnabled: false,
  //是否展示比例尺
  scaleControlsEnabled: true,
  //是否一直显示比例尺,只有比例尺启用时该参数才生效。
  alwaysShowScaleEnabled: true
};
  • VM中的MapCallBack赋值
this.MapCallBack = async (err, mapController) => {
  if (!err) {
    this.MapController = mapController;
    //启用我的位置图层
    mapController.setMyLocationEnabled(true);
    //设置我的位置跟随设备移动
    mapController.setMyLocationStyle({
      displayType: mapCommon.MyLocationDisplayType.LOCATE
    })
    //启用我的位置按钮
    mapController.setMyLocationControlsEnabled(true);
    //地图监听时间管理器
    this.MapEventManager = this.MapController.getEventManager();
  }
}
  • 权限申请(在VM中封装申请)
/**
 * 所需要得权限
 */
MapPermissions: Permissions[] =
  [
    'ohos.permission.INTERNET',
    'ohos.permission.LOCATION',
    'ohos.permission.APPROXIMATELY_LOCATION'
  ]
/**
 * 初始化方法
 */
public async Init() {
  //识别权限是否赋予
  if (!PermissionUtils.CheckPermissions(this.MapPermissions)) {
    const perResult: boolean = await PermissionUtils.RequestPermissions(this.MapPermissions);
    if (!perResult) {
      return;
    }
  }
}

权限方法封装

import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';

/**
 *权限封装类
 */
export class PermissionUtils {
  /**
   * 检查权限是否授权(完全授权)
   * @param permissionsArr 权限集合
   * @returns true:已经全部授权;false:没有全部授权
   */
  public static CheckPermissions(permissionsArr: Permissions[]): boolean {
    const atManager = abilityAccessCtrl.createAtManager();
    //获取bundle信息
    const bundleInfo =
      bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    // 拿到当前应用的tokenID 标识
    const tokenID = bundleInfo.appInfo.accessTokenId
    //校验应用是否被授予权限
    let result: boolean = true;
    permissionsArr.forEach((x: Permissions, index: number) => {
      if (!(atManager.checkAccessTokenSync(tokenID, x) === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)) {
        result = false;
        return;
      }
    })
    return result;
  }

  /**
   * 申请授权(首次弹窗申请)
   * @param permissionList 权限集合
   * @returns true:权限完全加载;false:有权限没有加载
   */
  public static async RequestPermissions(permissionList: Permissions[]): Promise<boolean> {
    // 程序访问控制管理
    const atManager = abilityAccessCtrl.createAtManager();
    // 拉起弹框请求用户授权
    const grantStatus = await atManager.requestPermissionsFromUser(getContext(), permissionList)
    // 获取请求权限的结果
    const isAuth = grantStatus.authResults.every(v => v === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
    // 返回 Promise 授权结果
    return isAuth ? Promise.resolve(true) : Promise.reject(false)
  }

  /**
   * 打开系统设置的权限管理页面
   */
  public static OpenPermissionSettingsPage() {
    // 获取上下文
    const context = getContext() as common.UIAbilityContext
    // 获取包信息
    const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
    // 打开系统设置页
    context.startAbility({
      bundleName: 'com.huawei.hmos.settings',
      abilityName: 'com.huawei.hmos.settings.MainAbility',
      uri: 'application_info_entry',
      parameters: {
        // 按照包名打开对应设置页
        pushParams: bundleInfo.name
      }
    })
  }
}
  • 项目加载时,先进行VM的初始化
aboutToAppear(): void {
  this.MapVM.Init();
}
  • 界面初始化展示

在这里插入图片描述

2、地图初始化类(MapOptions)

属于mapCommon类

  • 常用属性
名称类型可选说明
mapTypeMapType地图类型,默认值为MapType.STANDARD,异常值按默认值处理。
positionCameraPosition地图相机位置。
boundsLatLngBounds地图展示边界,异常值根据无边界处理。说明西南角纬度不能大于东北角纬度。
minZoomnumber地图最小图层,有效范围:[2, 20],默认值为2,异常值按默认值处理。如果设置的最小缩放级别小于2,minZoom会取2。
maxZoomnumber地图最大图层,有效范围:[2, 20],默认值为20,异常值按默认值处理。如果设置的最大缩放级别大于20,maxZoom会取20。
rotateGesturesEnabledboolean是否支持旋转手势,默认值为true,异常值按默认值处理。true:支持false:不支持
scrollGesturesEnabledboolean是否支持滑动手势,默认值为true,异常值按默认值处理。true:支持false:不支持
zoomGesturesEnabledboolean是否支持缩放手势,默认值为true,异常值按默认值处理。true:支持false:不支持
tiltGesturesEnabledboolean是否支持倾斜手势,默认值为true,异常值按默认值处理。true:支持false:不支持
zoomControlsEnabledboolean是否展示缩放控件,默认值为true,异常值按默认值处理。true:展示false:不展示
myLocationControlsEnabledboolean是否展示定位按钮,默认值为false,异常值按默认值处理。true:展示false:不展示
compassControlsEnabledboolean是否展示指南针控件,默认值为true,异常值按默认值处理。true:展示false:不展示
scaleControlsEnabledboolean是否展示比例尺,默认值为false,异常值按默认值处理。true:展示false:不展示
paddingPadding设置地图和边界的距离,默认值为{ left: 0 , top: 0 , right: 0 , bottom: 0 }。
styleIdstring自定义样式ID。
dayNightModeDayNightMode日间夜间模式,默认值为DayNightMode.DAY(日间模式)
alwaysShowScaleEnabledboolean是否一直显示比例尺,只有比例尺启用时该参数才生效。
  • 在VM类中,需要在类初始化的时候把MapOption初始化。
constructor() {
  this.MapOption = {
    //相机位置
    position: {
      target: {
        latitude: this.LocationLatitude,
        longitude: this.LocationLongitude
      },
      zoom: 10
    },
    //地图类型
    mapType: mapCommon.MapType.STANDARD,
    //地图最小图层,默认值为2
    minZoom: 2,
    //地图最大图层,默认值为20
    maxZoom: 20,
    //是否支持旋转手势
    rotateGesturesEnabled: true,
    //是否支持滑动手势
    scrollGesturesEnabled: true,
    //是否支持缩放手势
    zoomGesturesEnabled: true,
    //是否支持倾斜手势
    tiltGesturesEnabled: true,
    //是否展示缩放控件
    zoomControlsEnabled: true,
    //是否展示定位按钮
    myLocationControlsEnabled: true,
    //是否展示指南针控件
    compassControlsEnabled: false,
    //是否展示比例尺
    scaleControlsEnabled: true,
    //是否一直显示比例尺,只有比例尺启用时该参数才生效。
    alwaysShowScaleEnabled: true
  };
  this.MapCallBack = async (err, mapController) => {
    if (!err) {
      this.MapController = mapController;
      //启用我的位置图层
      mapController.setMyLocationEnabled(true);
      //设置我的位置跟随设备移动
      mapController.setMyLocationStyle({
        displayType: mapCommon.MyLocationDisplayType.LOCATE
      })
      //启用我的位置按钮
      mapController.setMyLocationControlsEnabled(true);
      //地图监听时间管理器
      this.MapEventManager = this.MapController.getEventManager();
    }
  }
}

3、获取手机用户当前位置

通过geoLocationManager的getCurrentLocation方法,获取用户的坐标经纬度,然后封装成更新用户定位的方法,在初始化的时候调用,就可以实现手机打开后会直接更新到用户的位置

/**
 * 更新用户定位
 */
public async UpdateLocation() {
  // 获取用户位置坐标
  let location: geoLocationManager.Location = await geoLocationManager.getCurrentLocation();
  this.LocationLongitude = location.longitude;
  this.LocationLatitude = location.latitude;
}

完整代码

  • Page
import { MapViewModel } from '../ViewModels/MapViewModel';
import { MapComponent } from '@kit.MapKit';

@Entry
@ComponentV2
struct FirstPage {
  @Local MapVM: MapViewModel = new MapViewModel();

  aboutToAppear(): void {
    this.MapVM.Init();
  }

  build() {
    RelativeContainer() {
      MapComponent({
        mapOptions: this.MapVM.MapOption,
        mapCallback: this.MapVM.MapCallBack
      })
        .width("100%")
        .height("100%")
        .id("Map")
    }
    .height('100%')
    .width('100%')
  }
}
  • ViewModel
import { mapCommon, map, sceneMap } from '@kit.MapKit';
import { AsyncCallback } from '@kit.BasicServicesKit';
import { common, Permissions } from '@kit.AbilityKit';
import { PermissionUtils } from '../Utils/PermissionUtils';
import geoLocationManager from '@ohos.geoLocationManager';
import { image } from '@kit.ImageKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';
import { MapMarkImage } from '../Utils/MapMarkImage';

@ObservedV2
export class MapViewModel {
  /**
   * 地图初始化参数设置
   */
  MapOption?: mapCommon.MapOptions
  /**
   * 地图回调方法
   */
  MapCallBack?: AsyncCallback<map.MapComponentController>
  /**
   * 地图控制器
   */
  MapController?: map.MapComponentController
  /**
   * 地图监听管理器
   */
  MapEventManager?: map.MapEventManager
  /**
   * 地图标记集合
   */
  Markers: map.Marker[] = []
  /**
   * 所需要得权限
   */
  MapPermissions: Permissions[] =
    [
      'ohos.permission.INTERNET',
      'ohos.permission.LOCATION',
      'ohos.permission.APPROXIMATELY_LOCATION'
    ]
  /**
   * 当前位置的维度
   */
  public LocationLatitude: number = 39.9;
  /**
   * 当前位置的经度
   */
  public LocationLongitude: number = 116.4;

  /**
   * 初始化方法
   */
  public async Init() {
    //识别权限是否赋予
    if (!PermissionUtils.CheckPermissions(this.MapPermissions)) {
      const perResult: boolean = await PermissionUtils.RequestPermissions(this.MapPermissions);
      if (!perResult) {
        return;
      }
    }
    //标点初始化
    MapMarkImage.Init(getContext(this));
  }

  constructor() {
    this.UpdateLocation();
    this.MapOption = {
      //相机位置
      position: {
        target: {
          latitude: this.LocationLatitude,
          longitude: this.LocationLongitude
        },
        zoom: 10
      },
      //地图类型
      mapType: mapCommon.MapType.STANDARD,
      //地图最小图层,默认值为2
      minZoom: 2,
      //地图最大图层,默认值为20
      maxZoom: 20,
      //是否支持旋转手势
      rotateGesturesEnabled: true,
      //是否支持滑动手势
      scrollGesturesEnabled: true,
      //是否支持缩放手势
      zoomGesturesEnabled: true,
      //是否支持倾斜手势
      tiltGesturesEnabled: true,
      //是否展示缩放控件
      zoomControlsEnabled: true,
      //是否展示定位按钮
      myLocationControlsEnabled: true,
      //是否展示指南针控件
      compassControlsEnabled: false,
      //是否展示比例尺
      scaleControlsEnabled: true,
      //是否一直显示比例尺,只有比例尺启用时该参数才生效。
      alwaysShowScaleEnabled: true
    };
    this.MapCallBack = async (err, mapController) => {
      if (!err) {
        this.MapController = mapController;
        //启用我的位置图层
        mapController.setMyLocationEnabled(true);
        //设置我的位置跟随设备移动
        mapController.setMyLocationStyle({
          displayType: mapCommon.MyLocationDisplayType.LOCATE
        })
        //启用我的位置按钮
        mapController.setMyLocationControlsEnabled(true);
        //地图监听时间管理器
        this.MapEventManager = this.MapController.getEventManager();
      }
    }
  }

  /**
   * 更新用户定位
   */
  public async UpdateLocation() {
    // 获取用户位置坐标
    let location: geoLocationManager.Location = await geoLocationManager.getCurrentLocation();
    this.LocationLongitude = location.longitude;
    this.LocationLatitude = location.latitude;
  }

  /**
   * 移动视图相机
   * @param latitude 维度
   * @param longitude 经度
   */
  public async MoveCamera(latitude: number, longitude: number) {
    if (this.MapController) {
      //将视图移动到标点位置
      let nwPosition = map.newCameraPosition({
        target: {
          latitude: latitude,
          longitude: longitude
        },
        zoom: 10
      })
      // 以动画方式移动地图相机
      this.MapController.animateCamera(nwPosition, 1000);
    }
  }
}
  • PermissionUtils
import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';

/**
 *权限封装类
 */
export class PermissionUtils {
  /**
   * 检查权限是否授权(完全授权)
   * @param permissionsArr 权限集合
   * @returns true:已经全部授权;false:没有全部授权
   */
  public static CheckPermissions(permissionsArr: Permissions[]): boolean {
    const atManager = abilityAccessCtrl.createAtManager();
    //获取bundle信息
    const bundleInfo =
      bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    // 拿到当前应用的tokenID 标识
    const tokenID = bundleInfo.appInfo.accessTokenId
    //校验应用是否被授予权限
    let result: boolean = true;
    permissionsArr.forEach((x: Permissions, index: number) => {
      if (!(atManager.checkAccessTokenSync(tokenID, x) === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)) {
        result = false;
        return;
      }
    })
    return result;
  }

  /**
   * 申请授权(首次弹窗申请)
   * @param permissionList 权限集合
   * @returns true:权限完全加载;false:有权限没有加载
   */
  public static async RequestPermissions(permissionList: Permissions[]): Promise<boolean> {
    // 程序访问控制管理
    const atManager = abilityAccessCtrl.createAtManager();
    // 拉起弹框请求用户授权
    const grantStatus = await atManager.requestPermissionsFromUser(getContext(), permissionList)
    // 获取请求权限的结果
    const isAuth = grantStatus.authResults.every(v => v === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
    // 返回 Promise 授权结果
    return isAuth ? Promise.resolve(true) : Promise.reject(false)
  }

  /**
   * 打开系统设置的权限管理页面
   */
  public static OpenPermissionSettingsPage() {
    // 获取上下文
    const context = getContext() as common.UIAbilityContext
    // 获取包信息
    const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
    // 打开系统设置页
    context.startAbility({
      bundleName: 'com.huawei.hmos.settings',
      abilityName: 'com.huawei.hmos.settings.MainAbility',
      uri: 'application_info_entry',
      parameters: {
        // 按照包名打开对应设置页
        pushParams: bundleInfo.name
      }
    })
  }
}

总结

上面的流程是地图组件的初始化的个人理解流程,看完这篇希望可以在地图开发上给你提供帮助。

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

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

相关文章

顶刊配图复现:Origin+DeepSeek完美协同

学习目标&#xff1a; &#xff08;1&#xff09;软件掌握熟练安装并配置Origin&#xff0c;掌握基础操作与核心功能。学会利用Origin进行多类型图表绘制及美化。掌握DeepSeek的数据清洗、统计分析与可视化方法。&#xff08;2&#xff09;设计能力理解顶刊图表的设计原则&…

Scratch032(百发百中)

提示:知识回顾 1、排列克隆体的方法 2、复习“发送广播并等待”积木 3、“获取第几个字符”积木的使用 4、使用角色显示得分 前言 提示:中国射箭拥有悠久的历史,是最早进入教育体系的运动项目之一,君子六艺中“礼,乐,射,御,书,数”的射 ,就是指的射箭。这节课我带你…

Minio分布式多节点多驱动器集群部署

Minio分布式多节点多驱动器集群部署 Minio分布式多节点多驱动器集群部署节点规划先决条件开放防火墙端口设置主机名更新域名映射文件时间同步存储要求内存要求 增加虚拟机磁盘(所有机器都要执行)部署分布式 MinIO测试上传与预览测试高可用MinIO 配置限制模拟单节点磁盘故障模拟…

【信号量】

信号量 目录操作系统信号信号的默认处理动作示例解释信号的捕获与处理使用 signal 函数使用 sigaction 函数 信号的阻塞 信号的生命周期1. 信号产生2. 信号在进程中注册3. 信号在进程中注销4. 信号处理main 7 signal命令含义使用场景手册页包含的关键信息1. 信号概述2. 信号列表…

一篇文章学懂Vuex

一、基于VueCli自定义创建项目 233 344 二、Vuex 初始准备 建项目的时候把vuex勾选上就不用再yarn add vuex3了 store/index.js // 这里面存放的就是vuex相关的核心代码 import Vuex from vuex import Vue from vue// 插件安装 Vue.use(Vuex)// 创建仓库&#xff08;空仓库…

DeepSeek 助力 Vue 开发:打造丝滑的二维码生成(QR Code)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

图像处理篇---图像处理中常见参数

文章目录 前言一、分贝&#xff08;dB&#xff09;的原理1.公式 二、峰值信噪比&#xff08;PSNR, Peak Signal-to-Noise Ratio&#xff09;1.用途2.公式3.示例 三、信噪比&#xff08;SNR, Signal-to-Noise Ratio&#xff09;1.用途2.公式3.示例 四、动态范围&#xff08;Dyna…

【Java】—— 二叉树

一、树型结构 树形结构是一种重要的数据结构&#xff0c;它类似于现实生活中的树的结构&#xff0c;由结点和边构成。树形结构具有以下特点&#xff1a; 树形结构是一种层次化的结构&#xff0c;由根结点、内部结点和叶子结点组成。根结点是树的顶部结点&#xff0c;没有父结点…

机场导航系统有哪些功能?精准定位与高效路径规划技术深度剖析

本文专为关注机场服务优化、乘客体验提升的IT技术员及航空业同仁而写。将深入探讨机场室内导航系统的核心功能&#xff0c;旨在解决乘客在机场内部定位、路径规划、服务寻找等方面的痛点。如需获取机场导航系统解决方案可前往文章最下方获取&#xff0c;如有项目合作及技术交流…

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上)

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上) 一、引言 1.1 研究背景与意义 在科技飞速发展的当下,医疗 AI 作为人工智能技术与医疗领域深度融合的产物,正引领着医疗行业的深刻变革。近年来,医疗 AI 在疾病诊断、药物研发、健康管理等诸多方面取得了显著进展,…

STM32-智能小车项目

项目框图 ST-link接线 实物图&#xff1a; 正面&#xff1a; 反面&#xff1a; 相关内容 使用L9110S电机模块 电机驱动模块L9110S详解 | 良许嵌入式 一、让小车动起来 新建文件夹智能小车项目 在里面复制19-串口打印功能 重命名为01-让小车动起来 新建文件夹motor&…

星环科技推出DeepSeek全场景解决方案:即开即用、企业级部署、端侧智能三位一体

星环科技&#xff08;688031.SH&#xff09;正式发布DeepSeek全场景解决方案&#xff0c;全面覆盖个人用户、企业客户及行业场景需求&#xff0c;为用户提供从个人到企业、从云端到本地的全方位AI应用支持&#xff0c;为不同需求的用户提供了灵活、高效且安全的AI解决方案。 省…

《全星质量管理 QMS 软件系统》:赋能企业高效质量管理

《全星质量管理 QMS 软件系统》&#xff1a;赋能企业高效质量管理 在当今竞争激烈的商业环境中&#xff0c;《全星质量管理 QMS 软件系统》脱颖而出&#xff0c;展现出了显著且无可比拟的应用优势。 首先&#xff0c;《全星质量管理 QMS 软件系统》犹如一张严密的质量管控大网…

【多模态处理篇三】【DeepSeek语音合成:TTS音色克隆技术揭秘】

最近帮某明星工作室做AI语音助手时遇到魔幻需求——要求用5秒的咳嗽声克隆出完整音色!传统TTS系统直接翻车,生成的语音像得了重感冒的电音怪物。直到祭出DeepSeek的TTS音色克隆黑科技,才让AI语音从"机器朗读"进化到"声临其境"。今天我们就来扒开这个声音…

C++Qt学习笔记——实现一个串口通信界面

CQt学习笔记——实现一个串口通信界面 一.界面二、项目结构三、头文件1. 文件头部2. 类定义3. 构造函数和析构函数4. 成员函数5. 成员变量 四、代码解析ReceiveAeraInit 函数解析SerialHelper 构造函数解析1. 为什么有两个 SerialHelper&#xff1f;2. 为什么用 :: 和 :&#x…

Word(2010)排版技巧

设置标题样式 选择需要设置的标题 如下图所示。选择文字后&#xff0c;点击对应的样式即可设置。 设置标题格式 设置字体格式 设置段落格式 显示所有样式 标题样式展示 建议 建议新建一个正文样式&#xff0c;可以命名为正文1&#xff0c;因为所有的样式参考的“样式基准…

一.Vue中的条件渲染

1.在<head>中引用 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> 2.在<body>中写入 <div id"app"><p><a v-if "user.usernameadmin"href"#">编辑</a><a …

IO进程 day05

IO进程 day05 9. 进程9. 9. 守护进程守护进程的特点守护进程创建步骤 10. 线程10.1. 线程的概念10.2. 进程和线程的区别10.2. 线程资源10.3. 线程的函数接口1. pthread_create-创建线程线程函数和普通函数的区别 2. pthread_exit3.线程资源回收函数join和detach的区别 获取线程…

【HeadFirst系列之HeadFirstJava】第6天之认识Java的API:解锁高效开发的钥匙

认识Java的API&#xff1a;解锁高效开发的钥匙 在《Head First Java》的第六章节中&#xff0c;作者深入探讨了Java的API&#xff08;Application Programming Interface&#xff09;&#xff0c;并强调了它在Java开发中的重要性。Java API 是Java开发工具包&#xff08;JDK&a…