web JS高德地图标点、点聚合、自定义图标、自定义窗体信息、换肤等功能实现和高复用性组件封装教程

文章目录

  • 前言
  • 一、点聚合是什么?
  • 二、开发前准备
  • 三、API示例
    • 1.引入高德地图
    • 2.创建地图实例
    • 3.添加标点
    • 4.删除标点
    • 5.删除所有标点(覆盖物)
    • 6.聚合点
    • 7.自定义聚合点样式
    • 8.清除聚合
    • 9.打开窗体信息
  • 四、实战开发
    • 需求要求
    • 效果图如下:
    • 封装思路分析
    • 完整代码
    • 效果


前言

本文将讲述如何利用高德地图JS API实现地图标点、聚合点、自定义图标、点击窗体信息展示等基本功能实现,结合实际项目中遇到场景需求进行演示和封装高复用性组件


一、点聚合是什么?

当地图中的标点很多的时候,缩小地图层级时候会重叠在一起,这时候可以把局部区域重叠的点聚合成一个点并标注当前区域重合点个数来展示,随着地图缩放层级动态响应式渲染。

在这里插入图片描述


二、开发前准备

    需要到高德开放平台-控制台申请key,我的应用——添加key——服务平台选择Web端(JS API)

在这里插入图片描述


三、API示例

接下来将以Vue项目演示API功能

1.引入高德地图

  入口文件index.html引入高德sdk,key填写申请的key
<script src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值"></script>

2.创建地图实例

创建一个地图容器

<div id="map"></div>

`创建一个地图实例,之后功能将依赖该实例,vue要在mounted周期函数内执行

 mounted() {
//地图实例
 let map = new AMap.Map(
        'map',//地图容器id
        {
        resizeEnable: true, //是否监控地图容器尺寸变化
        zoom:11, //初始化地图层级
        center: [116.397428, 39.90923], //初始化地图中心点
      //  mapStyle:'amap://styles/blue',//地图样式(背景)可选,可以在后台新建自定义样式
        });
 }

在这里插入图片描述

3.添加标点

   //新建一个标点
   let marker = new AMap.Marker({
        position:[116.397428, 39.90923], //位置
        offset: new AMap.Pixel(-13, -30),//偏移
        //icon:'', //图标可选,可以使用本地或者在线图标
      });
      
  //监听标点点击事件
   marker.on('click',e=>{
    console.log(e,'click')
  })
 
   //标点添加到地图上
   map.add(marker)

在这里插入图片描述

4.删除标点

删除一个或者多个标点,入参markers数组表示标点对象集合

   let marker = new AMap.Marker({
        position:[116.39, 39.90], //位置
      });
   let marker2 = new AMap.Marker({
     position:[117.39, 40.90], //位置
    });
    map.add(marker)
    map.add(marker2)
    //删除第一个标点
    map.remove([marker]);

5.删除所有标点(覆盖物)

   map.clearMap()

6.聚合点

  //添加2个标点
  let marker = new AMap.Marker({
        position:[116.397428, 39.90923], //位置
      });
   let marker2 = new AMap.Marker({
     p position:[116.3680, 39.9200], //位置
    });
    map.add(marker)
    map.add(marker2)
    
   /*设置聚合
   *@param map:地图实例
   *@param markers:标点对象数组
   */
     let cluster = new AMap.MarkerClusterer(map, markers, {
        gridSize:80
      });

未聚合
在这里插入图片描述

聚合效果:
聚合效果

7.自定义聚合点样式

聚合点自定义样式通过设置renderClusterMarker字段配置渲染函数,并在渲染函数中通过dom操作生成样式节点插入聚合点父节点上

      //聚合点实例
     let cluster = new AMap.MarkerClusterer(map, markers, {
        gridSize: 80,
        renderClusterMarker:renderClusterMarker,//自定义样式渲染
      });
   
  //渲染函数
      function renderClusterMarker(context) {
      var div = document.createElement("div");
      div.style.width = "50px";
      div.style.height = "50px";
      div.style.lineHeight = "50px";
      div.style.backgroundImage = `url(/static/images/icon.png)`;//自定义图标背景
      div.style.backgroundSize = "100%";
      div.style.backgroundRepeat = "no-repeat";
      div.innerHTML = context.count;//聚合个数
      div.style.color = "#fff";
      div.style.fontSize = "16px";
      div.style.paddingBottom = "10px";
      div.style.boxSizing = "border-box";
      div.style.textAlign = "center";
      var size = Math.round(
        30 + Math.pow(context.count / markers.length, 1 / 5) * 20//markers所有标点对象集合
      );
      context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
      context.marker.setContent(div);
      }

在这里插入图片描述

8.清除聚合

每次重新渲染设置聚合需要清除之前,不然数量会叠加

//cluster:聚合点实例
 cluster&&cluster.setMap(null);

9.打开窗体信息

   //新建一个标点
   let marker = new AMap.Marker({
        position:[116.397428, 39.90923], //位置
        offset: new AMap.Pixel(-13, -30),//偏移
        //icon:'', //图标可选,可以使用本地或者在线图标
      });
      
  //监听标点点击事件(显示窗体信息)
   marker.on('click',e=>{
       //创建窗体实例
      let infoWindow =new AMap.InfoWindow({
            content:'test',//窗体内容,支持插入dom.innerHTML 
            anchor:'top-right'//锚点,窗体相对鼠标点击位置
        });
        //显示窗体
        //map:地图实例,[lng,lat]:窗体在地图中位置
        infoWindow.open(map,[e.lnglat.lng,e.lnglat.lat])
  })

   //标点添加到地图上
   map.add(marker)
     
       

在这里插入图片描述

四、实战开发

需求要求

1.假设需要在地图上标注各种工程项目位置,工程项目分为3中类型,在建工程,已完成工程,延期工程不同类型分别对应不同图标
2.实现聚合功能,聚合图标自定义
3.点击对应工程项目弹窗显示项目信息
4.外部有搜索条件可以进行数据搜索,搜索完重新渲染地图,比如搜索xxxx至xxxx时间内在建工程,或者根据类型搜索等
5.大屏功能进行地图样式换肤
6.封装成通用组件方便下次开发使用

效果图如下:

在这里插入图片描述

封装思路分析

怎样封装才能方便使用呢?
对于组件封装我们可以采用倒推法,先写父组件里面的引用然后倒推实现子组件逻辑。
我们很容易想到在父组件内这样引用地图组件

<amap :center="mapCenter" :zoom="zoom" :markers="markers"></amap>

传入地图中心点(center)、层级(zoom)以及标点经纬度数组(markers)就能自动渲染,有了这个锥形后我们在继续扩展。

聚合样式和信息窗体要如何设计才能适应不同场景的自定义呢?

对于vue自定义内容首当其冲能想到的当然是slot,用插槽形式暴露给调用方就能自由diy

<amap :center="mapCenter" :zoom="zoom" :markers="markers">
       <!-- 聚合样式 -->
        <template v-slot:cluster>
        </template>
        <!-- 窗体样式 -->
        <template v-slot:infoWindow>
        </template>
</amap>

整个调用我们已经推导出来了,但还有一个问题,窗体或者聚合插槽中渲染数据要怎么样拿到?这个数据是和每个标点一一对应。我们可以通过标点参数(markers)传入数据在通过作用域插槽传出,最终成型为:

  <amap :center="mapCenter" :zoom="zoom" :markers="markers">
       <!-- 聚合样式 -->
        <template v-slot:cluster>
        </template>
        <!-- 窗体样式 -->
        <template v-slot:infoWindow="{ data }">
        </template>
  </amap>

很可惜经过研究聚合点个数数据无法通过作用域插槽传出,我们可以在封装的组件中通过dom操作直接在插槽节点内添加一个span节点写入个数居中显示,写死这个渲染节点,这样除了这个数字剩下图标样式都可以通过插槽自定义。

完整代码

先封装高德地图工具类
amap.js

/**
 * 高德地图工具类
 */
class amap {
    /**
     * 构造函数
     * @param  id :地图容器id
     * @param  params 地图配置参数
     */
    constructor(id, params) {
        this.markers = [];//所有标点数组集合
        this.cluster=null;//聚合点实例
        this.map = new AMap.Map(id, {
            ...params
        });

    }

    /**
    * 添加标点
    * @param markers:标点数组,item支持经纬度或者对象
    * @param clickEvent:标点点击事件回调
    */
    addMarkers(markers = [], clickEvent = () => { }) {
        for (let item of markers) {
            let params = {
                offset: new AMap.Pixel(-13, -30)
            };
            if (Array.isArray(item)) {
                params.position = item;
            } else if (typeof item === "object") {
                params = { ...item,...params };
            }
            //新建一个标点
            let marker = new AMap.Marker(params);
            //标点点击事件
            marker.on("click", (e) => {
                typeof clickEvent === 'function' && clickEvent({ ...params, lnglat: e.lnglat })
            });
            //标点添加到地图上
            this.map.add(marker);
            //保存到实例
            this.markers.push(marker)
        }
    }
    //清空地图覆盖物
    clearMap() {
        this.markers=[]
        this.map.clearMap();
    }
    /**
     * 聚合点
     * @param renderClusterMarker:聚合点自定义渲染函数
     */
    clusterMarker(renderClusterMarker) {
        //清除之前的聚合
        this.cluster&&this.cluster.setMap(null);  
        //设置聚合
        this.cluster= new AMap.MarkerClusterer(this.map, this.markers, {
            gridSize: 80,
            renderClusterMarker: renderClusterMarker
        });
    }
    //打开信息窗口
    showInfoWindow({ lng, lat, ...params }) {
        //创建窗体实例
        let infoWindow = new AMap.InfoWindow(params);
        //显示窗体
        //map:地图实例,[lng,lat]:窗体在地图中位置
        infoWindow.open(this.map, [lng, lat])
    }
    //关闭信息窗口
    closeInfoWindow() {
        this.map.clearInfoWindow();
    }

}

export default amap

高德地图组件
amap.vue

<template>
  <div id="amap-container" class="amap-container" :style="layoutStyle">
    <!-- 自定义渲染样式 -->
    <div class="cust-cluster-wrap">
      <slot name="cluster"></slot>
    </div>
    <div class="cust-infoWindow-wrap">
      <slot name="infoWindow" :data="currentMarkerData"></slot>
    </div>
  </div>
</template>

<script>
import amap from "./amap";
export default {
  name: "Amap",
  props: {
    //地图宽单位px
    width: {
      type: [Number, String],
      default: "100%",
    },
    //地图高单位px
    height: {
      type: [Number, String],
      default: "100%",
    },
    //地图实例化参数
    mapParams: {
      type: Object,
      default: () => {},
    },
    //地图中心点
    center: {
      type: Array,
      default: () => [116.397428, 39.90923],
    },
    //地图层级
    zoom: {
      type: Number,
      default: 11,
    },
    //标点
    markers: {
      type: Array,
      default: () => [],
    },
    //是否聚合点
    isCluster: {
      type: Boolean,
      default: true,
    },
    //点击标点是否显示信息窗口
    isShowInfoWindow: {
      type: Boolean,
      default: true,
    },
    //信息窗口配置参数
    infoWindowParams: {
      type: Object,
      default: () => {},
    },
    //是否点击地图关闭信息窗口
    closeIwOnClickMap: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      map: null, //地图实例
      cluster: null, //聚合点实例
      currentMarkerData: {},
    };
  },
  computed: {
    //设置地图容器宽高
    layoutStyle() {
      //%或者px兼容处理
      const getAttrVal = (val) =>
        val.toString().includes("%") ? val : `${val}px`;
      return {
        width: getAttrVal(this.width),
        height: getAttrVal(this.height),
      };
    },
    //是否自定义聚合点样式
    isCustcluster() {
      return this.$scopedSlots.cluster;
    },
    //是否自定义信息窗口
    isCustInfoWindow() {
      return this.$scopedSlots.infoWindow;
    },
  },
  watch: {
  //监听标点数据重新渲染
    markers: {
      handler(val) {
        if (this.map) {
          //清空地图标点
          this.map.clearMap();
          //重新渲染
          this.addMarkers(val);
          this.isCluster && this.clusterMarker(); //设置聚合点
        }
      },
      immediate: false,
      deep: true,
    },
  },
  mounted() {
    this.createMap(); //创建地图
    this.addMarkers(this.markers); //添加标点
    this.isCluster && this.clusterMarker(); //设置聚合点
  },
  beforeDestroy() {
    //销毁地图
    this.map && this.map.map.destroy();
  },
  methods: {
    //创建地图实例
    createMap() {
      this.map = new amap("amap-container", {
        ...this.mapParams,
        zoom: this.zoom,
        center: this.center,
      });
      //地图加载完成
      this.map.map.on("complete", () => {
        this.$emit("initComplete");
      });
      //地图点击事件
      this.map.map.on("click", (e) => {
        this.closeIwOnClickMap&&this.closeInfoWindow()
        this.$emit("mapClick", e);
      });
    },
    //标点
    addMarkers(markers = []) {
      this.map.addMarkers(markers, (e) => {
        this.currentMarkerData = e;
        //点击标点显示信息窗口
        if (this.isShowInfoWindow) {
          //等待currentMarkerData数据渲染更新完成在打开信息窗口
          this.$nextTick(() => {
            this.map.showInfoWindow({
              lat: e.lnglat.lat,
              lng: e.lnglat.lng,
              ...this.infoWindowParams,
              isCustom: this.isCustInfoWindow,
              content: this.getCustInfoWindowDom() || e.infoWindowContent || "",
            });
          });
        }
        //派发标点点击事件
        this.$emit("markerClick", e);
      });
    },
    //聚合标点
    clusterMarker() {
      //自定义渲染函数
      function renderClusterMarker(context) {
        //获取自定义聚合点DOM
        let custClusterDom =
          document.getElementsByClassName("cust-cluster-wrap")[0];
        let div = document.createElement("div");
        div.innerHTML = custClusterDom.innerHTML;
        let span = document.createElement("span");
        span.style.position = "absolute";
        span.style.top = "50%";
        span.style.left = "50%";
        span.style.transform = "translate(-50%,-50%)";
        span.style.zIndex = "99";
        //设置聚合数
        span.innerHTML = context.count;
        //插入聚合数量span节点
        div.children[0].appendChild(span);
        let size = Math.round(
          30 + Math.pow(context.count / this.map.markers.length, 1 / 5) * 20
        );
        context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
        context.marker.setContent(div);
      }

      //聚合
      this.map &&
        this.map.clusterMarker(
          this.isCustcluster ? renderClusterMarker.bind(this) : undefined
        );
    },
    //获取自定义窗口Dom
    getCustInfoWindowDom() {
      if (!this.isCustInfoWindow) return;
      return document.getElementsByClassName("cust-infoWindow-wrap")[0]
        .innerHTML;
    },
    //关闭信息窗口
    closeInfoWindow() {
      this.map.closeInfoWindow();
    },
  },
};
</script>

<style lang="scss" scoped>
.amap-container {
  width: 100%;
  height: 100%;
}
.cust-cluster-wrap {
  position: fixed;
  top: 0;
  left: 0;
  transform: translate(-100%, -100%);
}
.cust-infoWindow-wrap {
  position: fixed;
  top: 0;
  left: 0;
  transform: translate(-100%, -100%);
}
</style>

页面调用:
inde.vue

<template>
  <div class="container">
    <!-- 地图区域 -->
    <div class="map-wrap">
      <amap
        :center="mapCenter"
        :zoom="zoom"
        :mapParams="mapParams"
        :markers="markers"
        :infoWindowParams="infoWindowParams"
        isCluster
        @initComplete="onInitComplete"
        @mapClick="onMapClick"
      >
        <!-- 聚合样式 -->
        <template v-slot:cluster>
          <div class="cluster">
            <img class="icon" src="/static/images/icon.png" />
          </div>
        </template>
        <!-- 窗体样式 -->
        <template v-slot:infoWindow="{ data }">
          <div class="infoWindow">
            <div class="name">{{ data.projectName }}</div>
            <div class="row">电话:{{ data.phone }}</div>
            <div class="row">地址:{{ data.address }}</div>
          </div>
        </template>
      </amap>
    </div>
    <!-- 搜索按钮 -->
    <button class="search" @click="onSearch">搜索(模拟刷新数据)</button>
  </div>
</template>

<script>
import amap from "./component/amap/amap.vue";
export default {
  components: {
    amap,
  },
  data() {
    return {
      markers: [], //标点集合
      mapCenter: [116.397428, 39.90923],
      zoom: 13,
      mapParams: {
        mapStyle: "amap://styles/blue", //地图样式
      },
      infoWindowParams: {
        anchor: "top-right",
        offset: new AMap.Pixel(0, 15), //偏移
      },
    };
  },
  created() {
    this.onSearch();
  },
  mounted() {},
  methods: {
    //加载完成
    onInitComplete() {
      console.log("加载完成");
    },
    //点击地图
    onMapClick(e) {
      console.log(e, "点击地图");
    },
    //搜索
    onSearch() {
      this.markers = [];
      this.$nextTick(() => {
        //模拟接口生成数据
        for (let i = 0; i < parseInt(Math.random() * 20); i++) {
          let [lng, lat] = this.mapCenter;
          let position = [lng + i * Math.random() * 0.05, lat + i * 0.01];
          this.markers.push({
            position,//经纬度
            icon: `/static/images/map_icon${
              parseInt(Math.random() * 3) + 1
            }.png`,//标点图标
            projectName: `项目${i}`,//项目名称
            phone: "13333333333",//电话
            address: "北京市朝阳区望京阜荣街10号",//地址
          });
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.container {
  width: 100%;
  height: 100%;
}
.map-wrap {
  height: 90%;
  width: 100%;
  .cluster {
    height: 60px;
    width: 60px;
    border-radius: 50%;
    color: #fff;
    font-size: 16px;
    line-height: 50px;
    .icon {
      width: 100%;
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
    }
  }
  .infoWindow {
    padding: 20px;
    box-sizing: border-box;
    border-radius: 10px;
    background: #fff;
    .name {
      font-size: 18px;
      color: rgb(39, 130, 248);
    }
    .row {
      margin-top: 10px;
      font-size: 14px;
    }
  }
}
.search {
  margin-top: 10px;
  width: 150px;
  height: 40px;
}
</style>

效果

在这里插入图片描述

搜索刷新后
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pdf怎么合并在一起?这几个合并方法了解一下

pdf怎么合并在一起&#xff1f;在日常工作、学习和生活中&#xff0c;我们常常会遇到需要将多个PDF文件合并成一个文件的情况。比如&#xff0c;在学术论文写作中&#xff0c;我们可能需要将多篇论文合并成一个文件进行打印和提交。在工作中&#xff0c;我们可能需要将多个报告…

记录每日LeetCode 617.合并二叉树 Java实现

题目描述&#xff1a; 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要将这两棵树合并成一棵新二叉树。合并的规则是&#xff1a;…

如何从cpu改为gpu,pytorch,cuda

1.cmd输入nvcc -V 2.得到 cuda版本后&#xff0c;去pytorch官网 3.根据自己的cuda进行选择 4.复制上述链接&#xff0c;进入cmd 5.cmd中输入activate XXX,这里的"XXX"指代自己在工程中用到的环境 6.进入后&#xff0c;将刚才链接粘贴&#xff0c;回车等待下载结束 …

文心一言 VS 讯飞星火 VS chatgpt (76)-- 算法导论7.3 1题

一、如果用go语言&#xff0c;为什么我们分析随机化算法的期望运行时间&#xff0c;而不是其最坏运行时间呢? 文心一言&#xff1a; 在分析算法的性能时&#xff0c;期望运行时间是一个重要的指标&#xff0c;它描述了算法在平均情况下的表现。期望运行时间考虑了所有可能的…

spring(15) SpringBoot启动过程

目录 一、过程简介二、过程流程图三、源码分析1、运行 SpringApplication.run() 方法2、确定应用程序类型3、加载所有的初始化器4、加载所有的监听器5、设置程序运行的主类6、开启计时器7、将 java.awt.headless 设置为 true8、获取并启用监听器9、设置应用程序参数10、准备环境…

韦东山-电子量产工具项目:UI系统

代码结构 所有代码都已通过测试跑通&#xff0c;其中代码结构如下&#xff1a; 一、include文件夹 1.1 common.h #ifndef _COMMON_H #define _COMMON_Htypedef struct Region {int iLeftUpX; //区域左上方的坐标int iLeftUpY; //区域左下方的坐标int iWidth; //区域宽度…

安防监控视频云存储EasyCVR平台H.265转码功能更新:新增分辨率配置

安防视频集中存储EasyCVR视频监控综合管理平台可以根据不同的场景需求&#xff0c;让平台在内网、专网、VPN、广域网、互联网等各种环境下进行音视频的采集、接入与多端分发。在视频能力上&#xff0c;视频云存储平台EasyCVR可实现视频实时直播、云端录像、视频云存储、视频存储…

从零做软件开发项目系列之一综论软件项目开发

1 引言 有一个三个泥瓦匠的故事。 三个泥瓦匠在砌墙&#xff0c;一个人走过来&#xff0c;问他们在干什么。   第一个泥瓦匠没好气地说&#xff0c;你没看见吗&#xff1f;我在辛苦地砌墙呢。   第二个回答&#xff0c;我们正在建一座高楼。   第三个则洋溢着喜悦说&…

CSS:filter滤镜 详解(用法 + 代码 + 例子 + 效果)

文章目录 filter 滤镜blur() 模糊度例子 渐变光晕 brightness() 元素亮度contrast() 对比度grayscale() 元素灰度hue-rorate() 色相opacity() 透明度invert() 反转颜色saturate() 饱和度 backdrop-filter 蒙版&#xff0c;滤镜例子 卷轴展开 filter 滤镜 动图为效果添加前后对…

开源了一套基于springboot+vue+uniapp的商城,包含分类、sku、商户管理、分销、会员、适合企业或个人二次开发

RuoYi-Mall-JAVA商城-电商系统简介 开源了一套基于若依框架&#xff0c;SringBoot2MybatisPlusSpringSecurityjwtredisVueUniapp的前后端分离的商城系统&#xff0c; 包含分类、sku、商户管理、分销、会员、适合企业或个人二次开发。 前端采用Vue、Element UI&#xff08;ant…

视频汇聚/视频云存储/视频监控管理平台EasyCVR添加萤石云设备详细操作来啦!

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

贝锐蒲公英助力电子公交站牌联网远程运维,打造智慧出行新趋势

在现代城市公共交通系统中&#xff0c;我们随处可见电子公交站牌的身影。作为公共交通服务的核心之一&#xff0c;电子公交站牌的稳定运行至关重要&#xff0c;公交站台的实时公交状况、公共广告信息&#xff0c;是市民候车时关注的焦点。 某交通科技公司在承接某市智能电子站牌…

MR300C工业无线WiFi图传模块 内窥镜机器人图像传输有线无线的两种方式

MR300C无线WiFi图传模使用方法工业机器人图像高清传输 ⚫ MR300C图传模块基于MIPS处理器实现&#xff0c;电脑/手机连接模块的WIFI热点或网口即可查看视频流 ⚫ 模块的USB 2.0 Host接口&#xff0c;可接入USB uvc摄像头/内窥镜默认输出的视频格式必须是MJPG ⚫ 模块支持接入摄…

Python绘图系统6:自定义坐标列表控件

文章目录 自定义坐标列表控件显示和隐藏加载按钮坐标设置控件的显示和隐藏源代码 Python绘图系统&#xff1a; 基础&#xff1a;将matplotlib嵌入到tkinter &#x1f4c8;简单的绘图系统 &#x1f4c8;数据导入&#x1f4c8;三维绘图系统自定义控件&#xff1a;坐标设置控件&a…

【解决】Kafka Exception thrown when sending a message with key=‘null‘ 异常

问题原因&#xff1a; 如下图&#xff0c;kafka 中配置的是监听域名的方式&#xff0c;但程序里使用的是 ip:port 的连接方式。 解决办法&#xff1a; kafka 中配置的是域名的方式&#xff0c;程序里也相应配置成 域名:port 的方式&#xff08;注意&#xff1a;本地h…

计算机网络的性能指标

计算机网络的性能指标 1. 速率 速率是指数据在网络中传送的速度&#xff0c;通常用比特率或数据率来表示&#xff0c;单位是b/s&#xff0c;或bit/s&#xff0c;即比特每秒&#xff0c;或者bps(bit per second)。 速率单位&#xff1a;1 Ybps 10^24 bps(尧), 1 Zbps 10^21…

【面试八股文】每日一题:谈谈你对IO的理解

谈谈你对IO的理解 每日一题-Java核心-谈谈你对对IO的理解【面试八股文】 1.Java基础知识 Java IO&#xff08;Input/Output&#xff09;是Java编程语言中用于处理输入和输出的一组类和接口。它提供了一种在Java程序中读取和写入数据的方法。 Java IO包括两个主要的部分&#x…

【100天精通python】Day39:GUI界面编程_PyQt 从入门到实战(下)_图形绘制和动画效果,数据可视化,刷新交互

目录 专栏导读 6 图形绘制与动画效果 6.1 绘制基本图形、文本和图片 6.2 实现动画效果和过渡效果 7 数据可视化 7.1 使用 Matplotlib绘制图表 7.2 使用PyQtGraph绘制图表 7.3 数据的实时刷新和交互操作 7.3.1 数据的实时刷新 7.3.2 交互操作 7.4 自定义数据可视化…

LVS-DR模式以及其中ARP问题

目录 LVS_DR LVS_DR数据包流向分析 LVS-DR中ARP问题 问题一 问题二 解决ARP的两个问题的设置方法 LVS-DR特点 LVS-DR优缺点 优点 缺点 LVS-DR集群构建 1.配置负载调度器 2.部署共享存储 3.配置节点服务器 4.测试 LVS 群集 LVS_DR LVS_DR数据包流向分析 客户端…

【报错】git push --set-upstream origin XXXX重名

您在尝试将分支推送到远程仓库时遇到了错误。错误信息表明&#xff0c;由于已经存在名为 refs/heads/xingfan/demo 的文件夹&#xff0c;Git 无法创建分支 refs/heads/xingfan。 要解决此问题&#xff0c;您可以尝试重命名本地分支&#xff0c;然后将其推送到远程仓库。以下是…