【天地图】绘制、删除点线面

使用天地图绘制、删除点线面

  • 实现效果图
  • 地图组件完整代码
  • 使用地图组件完整代码

实现效果图

在这里插入图片描述

地图组件完整代码


// 天地图组件
<template>
  <div class="map-container">
    <div id="mapCon"></div>
  </div>
</template>

<script>
import markerIcon from "@/assets/images/marker-icon.png";
let handler;
export default {
  name: "MapEle",
  props: {
    mapData: {
      type: Object,
      default: () => {
        return {
          pointData: [],
          lineData: {},
          rangeData: {},
        };
      },
    },
  },
  data() {
    return {
      map: null,
      zoom: 14,
      longitude: 117.119529,
      latitude: 36.650396,
    };
  },
  watch: {
    // 只关注mapData数据源即可,监听mapData数据源改变清空地图,重新打点\线\面
    mapData: {
      handler(newV, oldV) {
        this.map.clearOverLays();
        this.drawMap();
      },
      deep: true,
    },
  },
  methods: {
    initMap() {
      this.map = new T.Map("mapCon");
      this.map.centerAndZoom(
        new T.LngLat(this.longitude, this.latitude),
        this.zoom
      );
      this.drawMap();
    },
    drawMap() {
      this.drawPoint();
      this.drawLine();
      this.drawRange();
    },
    // 绘制点
    drawPoint() {
      this.mapData?.pointData?.forEach((item) => {
        var marker = new T.Marker(new T.LngLat(item[0], item[1]));
        this.map.addOverLay(marker);
        var label = new T.Label({
          text: item[2],
          position: new T.LngLat(item[0], item[1]),
          offset: new T.Point(0, 0),
          style: {
            fontSize: "14px",
            color: "#000",
            backgroundColor: "rgba(255, 255, 255, 0.8)",
            padding: "5px",
            borderRadius: "5px",
            border: "1px solid #ccc",
          },
        });
        this.map.addOverLay(label);
      });
    },
    // 绘制线
    drawLine() {
      if (this.mapData.lineData) {
        let coordinates;
        if (
          this.mapData.lineData.length > 0 &&
          Array.isArray(this.mapData.lineData[0])
        ) {
          coordinates = this.mapData.lineData[0].map(
            (coord) => new T.LngLat(coord[0], coord[1])
          );
        } else {
          coordinates = this.mapData.lineData.map(
            (coord) => new T.LngLat(coord[0], coord[1])
          );
        }

        if (coordinates.length > 1) {
          const polyline = new T.Polyline(coordinates, {
            color: "#ff0000",
            weight: 3,
          });
          this.map.addOverLay(polyline);
          this.map.panTo(coordinates[0]);
        }
      }
    },
    // 绘制面
    drawRange() {
      if (this.mapData.rangeData) {
        let coordinates;
        if (
          this.mapData.rangeData.length > 0 &&
          Array.isArray(this.mapData.rangeData[0])
        ) {
          coordinates = this.mapData.rangeData[0].map(
            (coord) => new T.LngLat(coord[0], coord[1])
          );
        } else {
          coordinates = this.mapData.rangeData.map(
            (coord) => new T.LngLat(coord[0], coord[1])
          );
        }

        if (coordinates.length > 2) {
          var polygon = new T.Polygon(coordinates, {
            color: "green",
            weight: 3,
            opacity: 0.5,
            fillColor: "red",
            fillOpacity: 0.5,
            strokeStyle: "solid",
          });

          this.map.addOverLay(polygon);

          if (coordinates.length > 0) {
            const center = this.getPolygonCenter(coordinates);
            // this.map.panTo(center);
          }
        }
      }
    },
    // 打点
    async handlePoint(i) {
      if (handler) handler.close(); // 如果已有打点工具打开,先关闭
      handler = new T.MarkTool(this.map, {
        follow: true,
        icon: new T.Icon({
          iconUrl: markerIcon,
          iconSize: new T.Point(25, 41),
        }),
      });
      handler.open(); // 打开打点工具

      handler.addEventListener("mouseup", async (e) => {
        try {
          // 获取打点位置的名称
          const locationName = await this.getLocationName(
            e.currentLnglat.lng,
            e.currentLnglat.lat
          );
          // 通知父组件打点完成
          this.$emit(
            "finishPoint",
            [e.currentLnglat.lng, e.currentLnglat.lat, locationName],
            i
          );
        } catch (error) {
          console.error("获取位置名称失败:", error);
        } finally {
          handler.close(); // 关闭打点工具
        }
      });
    },
    // 画线
    handleLine() {
      if (this.handler) this.handler.close(); // 如果已有绘线工具打开,先关闭
      this.handler = new T.PolylineTool(this.map, {
        color: "#ff0000", // 线的颜色
        weight: 3, // 线的宽度
      });
      this.handler.open(); // 打开绘线工具

      this.handler.addEventListener("draw", (e) => {
        // 将绘制的线的坐标转换为二维数组
        const lineCoordinates = e.currentLnglats.map((item) => [
          item.lng,
          item.lat,
        ]);
        // 发射事件,通知父组件绘线完成
        this.$emit("finishLine", lineCoordinates);
      });
    },
    // 画范围
    handleRange() {
      if (this.handler) this.handler.close(); // 如果已有绘图工具打开,先关闭
      this.handler = new T.PolygonTool(this.map, {
        color: "#ff0000", // 多边形边框颜色
        weight: 3, // 多边形边框宽度
      });
      this.handler.open(); // 打开绘图工具

      this.handler.addEventListener("draw", (e) => {
        // 将绘制的多边形的坐标转换为二维数组
        const polygonCoordinates = e.currentLnglats.map((item) => [
          item.lng,
          item.lat,
        ]);
        // 通知父组件绘制完成
        this.$emit("finishRange", polygonCoordinates);
      });
    },
    // 计算多边形的中心点
    getPolygonCenter(coordinates) {
      let sumLng = 0;
      let sumLat = 0;
      coordinates.forEach((coord) => {
        sumLng += coord.lng;
        sumLat += coord.lat;
      });
      const centerLng = sumLng / coordinates.length;
      const centerLat = sumLat / coordinates.length;
      return new T.LngLat(centerLng, centerLat);
    },
    // 根据经纬度获取当前地名称
    getLocationName(lng, lat) {
      const geocoder = new T.Geocoder();
      return new Promise((resolve, reject) => {
        geocoder.getLocation(new T.LngLat(lng, lat), (result) => {
          if (result.getStatus() === 0) {
            const address = result.getAddress();
            resolve(address); // address即为当前点名称
          } else {
            reject(result.getMsg());
          }
        });
      });
    },
  },
  mounted() {
    this.initMap();
  },
};
</script>

<style scoped lang="scss">
.map-container {
  position: relative;
  #mapCon {
    height: 70vh;
  }
}
</style>

使用地图组件完整代码

// 编辑地图信息弹窗
<template>
  <div class="container-box">
    <el-dialog
      v-if="visible"
      :title="title"
      :visible.sync="visible"
      width="90vw"
      custom-class="dialog-class"
    >
      <el-row :gutter="20">
        <el-col :span="12">
          <MapEle
            ref="mapEleRef"
            :mapData="mapData"
            @finishPoint="finishPoint"
            @finishLine="finishLine"
            @finishRange="finishRange"
          />
        </el-col>
        <el-col :span="12">
          <el-form ref="form" :model="form" :rules="rules" label-width="140px">
            <el-row :gutter="20">
              <el-col :span="24">
                <el-form-item label="名称" prop="name">
                  <el-input
                    v-model="form.name"
                    placeholder="请输入名称"
                  /> </el-form-item
              ></el-col>
              <el-col :span="24">
                <el-form-item label="起点位置" prop="startLocation">
                  <el-input
                    v-model="form.startLocation"
                    placeholder="请选择起点位置"
                    readonly
                    disabled
                  >
                    <template slot="append">
                      <el-button
                        icon="el-icon-location-outline"
                        @click="drawPoint(0)"
                      ></el-button>
                      <el-divider
                        direction="vertical"
                        class="divider-class"
                      ></el-divider>
                      <el-button
                        icon="el-icon-delete"
                        @click="delPoint(0)"
                      ></el-button> </template
                  ></el-input> </el-form-item
              ></el-col>
              <el-col :span="24">
                <el-form-item label="终点位置" prop="endLocation">
                  <el-input
                    v-model="form.endLocation"
                    placeholder="请选择终点位置"
                    readonly
                    disabled
                  >
                    <template slot="append">
                      <el-button
                        icon="el-icon-location-outline"
                        @click="drawPoint(1)"
                      ></el-button>
                      <el-divider
                        direction="vertical"
                        class="divider-class"
                      ></el-divider>
                      <el-button
                        icon="el-icon-delete"
                        @click="delPoint(1)"
                      ></el-button>
                    </template> </el-input></el-form-item
              ></el-col>
              <el-col :span="24">
                <el-form-item label="线" prop="pipelayer">
                  <el-input
                    v-model="form.pipelayer"
                    disabled
                    placeholder="请绘制线"
                  >
                    <template slot="append">
                      <el-button
                        icon="el-icon-edit-outline"
                        @click="drawLine"
                      ></el-button>
                      <el-divider
                        direction="vertical"
                        class="divider-class"
                      ></el-divider>
                      <el-button
                        icon="el-icon-delete"
                        @click="delLine"
                      ></el-button>
                    </template> </el-input></el-form-item
              ></el-col>
              <el-col :span="24">
                <el-form-item label="区域" prop="piperange">
                  <el-input
                    v-model="form.piperange"
                    disabled
                    placeholder="请绘制区域"
                    ><template slot="append">
                      <el-button
                        icon="el-icon-edit-outline"
                        @click="drawRange"
                      ></el-button>
                      <el-divider
                        direction="vertical"
                        class="divider-class"
                      ></el-divider>
                      <el-button
                        icon="el-icon-delete"
                        @click="delRange"
                      ></el-button>
                    </template>
                  </el-input> </el-form-item
              ></el-col>
              <el-col :span="24">
                <el-form-item label="高度差" prop="altitude">
                  <el-input
                    v-model="form.altitude"
                    placeholder="请输入高度差"
                  /> </el-form-item
              ></el-col>
              <el-col :span="24">
                <el-form-item label="面积(㎡)" prop="heatArea">
                  <el-input
                    v-model="form.heatArea"
                    placeholder="请输入面积"
                  /> </el-form-item
              ></el-col>
            </el-row>
          </el-form>
        </el-col>
      </el-row>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" v-if="!enterprise" @click="submitForm"
          >确 定</el-button
        >
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { cloneDeep as _cloneDeep } from "lodash";
import { updateApi, getGateway } from "@/api/basicData/mainPipeNetwork.js";
import MapEle from "@/components/MapEle";
export default {
  components: { MapEle },
  data() {
    return {
      title: "",
      visible: false,
      defaultForm: {
        name: undefined,
        startLocation: undefined,
        endLocation: undefined,
        startLongitude: undefined,
        startLatitude: undefined,
        endLongitude: undefined,
        endLatitude: undefined,
        altitude: undefined,
        heatArea: undefined,
        pipelayer: undefined,
        piperange: undefined,
      },
      rules: {
        name: [
          { required: true, message: "主网名称不能为空", trigger: "blur" },
        ],
        startLocation: [
          { required: true, message: "起点位置不能为空", trigger: "blur" },
        ],
        endLocation: [
          { required: true, message: "终点位置不能为空", trigger: "blur" },
        ],
        pipelayer: [{ required: true, message: "线不能为空", trigger: "blur" }],
        piperange: [
          { required: true, message: "区域不能为空", trigger: "blur" },
        ],
        altitude: [
          { required: true, message: "高度差不能为空", trigger: "blur" },
        ],
        heatArea: [
          { required: true, message: "面积不能为空", trigger: "blur" },
        ],
      },
      form: {},
      enterprise: false, // 企业标识
      mapVisible: false,
      mapFlag: 1,
      mapData: {
        pointData: [],
        lineData: {
          coordinates: [],
        },
        rangeData: {
          coordinates: [],
        },
      },
    };
  },
  created() {
    // 判斷當前用戶是否有企业标识 qiye
    if (
      this.$store.state.user?.roles.length &&
      this.$store.state.user?.roles.indexOf("qiye") >= 0
    ) {
      this.enterprise = true;
    }
  },
  methods: {
    // 绘制点,这里的i标识起点(0)和终点(1)(根据个人情况使用)
    drawPoint(i) {
      // 绘制当前点时先将之前点清空,再绘制
      this.delPoint(i);
      this.$nextTick(() => {
        this.$refs.mapEleRef.handlePoint(i);
      });
    },
    // 绘制线
    drawLine() {
      this.delLine();
      this.$nextTick(() => {
        this.$refs.mapEleRef.handleLine();
      });
    },
    // 绘制面
    drawRange() {
      this.delRange();
      this.$nextTick(() => {
        this.$refs.mapEleRef.handleRange();
      });
    },
    // 删除点
    delPoint(i) {
      // 获取要删除的点的经纬度
      const { longitude, latitude } =
        i === 1
          ? {
              longitude: this.form.endLongitude,
              latitude: this.form.endLatitude,
            }
          : {
              longitude: this.form.startLongitude,
              latitude: this.form.startLatitude,
            };

      // 从 mapData.pointData 中移除对应的点
      this.mapData.pointData = this.mapData.pointData.filter((item) => {
        return !(item[0] === longitude && item[1] === latitude);
      });

      // 清空表单中的位置信息
      if (i === 1) {
        this.form.endLocation = "";
        this.form.endLongitude = "";
        this.form.endLatitude = "";
      } else {
        this.form.startLocation = "";
        this.form.startLongitude = "";
        this.form.startLatitude = "";
      }
    },
    // 删除线
    delLine() {
      this.form.pipelayer = "";
      this.$forceUpdate();
      this.mapData.lineData = [];
    },
    // 删除面
    delRange() {
      this.form.piperange = "";
      this.$forceUpdate();
      this.mapData.rangeData = [];
    },
    // 绘制完点后触发的方法
    finishPoint(arr, i) {
      // 将点的坐标和名称保存到 mapData.pointData 中
      this.mapData.pointData.push(arr);

      // 根据索引 i 更新表单中的起点或终点信息
      const updateForm = (location, longitude, latitude) => {
        this.form[location] = arr[2];
        this.form[longitude] = arr[0];
        this.form[latitude] = arr[1];
      };

      if (i === 1) {
        updateForm("endLocation", "endLongitude", "endLatitude");
      } else {
        updateForm("startLocation", "startLongitude", "startLatitude");
      }
    },
    // 绘制完线后触发的方法
    finishLine(arr) {
      this.mapData.lineData = [arr];
      this.form.pipelayer = JSON.stringify(arr);
      this.$forceUpdate();
    },
    // 绘制完面后触发的方法
    finishRange(arr) {
      this.mapData.rangeData = [arr];
      this.form.piperange = JSON.stringify(arr);
      this.$forceUpdate();
    },
    // 打开编辑页面
    async open(row) {
      try {
        // 获取地图数据
        const res = await this.getMapData(row);
        const tempData = JSON.parse(res?.data);

        // 初始化地图数据
        this.mapData = {
          pointData: [
            [row.startLongitude, row.startLatitude, row.startLocation],
            [row.endLongitude, row.endLatitude, row.endLocation],
          ],
          lineData: tempData?.features?.[0]?.pipelayer?.coordinates,
          rangeData: tempData?.features?.[0]?.piperange?.coordinates,
        };

        // 初始化表单数据
        this.form = _cloneDeep(this.defaultForm);
        this.form = { ...row };
        this.form.pipelayer = JSON.stringify(
          tempData?.features?.[0]?.pipelayer?.coordinates[0] || []
        );
        this.form.piperange = JSON.stringify(
          tempData?.features?.[0]?.piperange?.coordinates[0] || []
        );

        // 设置对话框标题和可见性
        this.title = "修改";
        this.visible = true;
      } catch (error) {
        console.error("打开对话框时出错:", error);
      }
    },
    // 获取地图线和区域数据
    getMapData(row) {
      return new Promise((resolve, reject) => {
        getGateway({ bh: row.code })
          .then((response) => {
            resolve(response);
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
    // 关闭弹窗页`
    cancel() {
      this.visible = false;
    },
    // 提交
    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          // 构建提交参数
          const params = {
            ...this.form,
            layer: {
              pipeLayerVar: this.form.pipelayer,
              pipeRangeVar: `[${this.form.piperange}]`,
            },
          };

          // 调用更新接口
          updateApi(params)
            .then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.cancel();
              this.$emit("refreshList");
            })
            .catch((error) => {
              this.$modal.msgError("修改失败:" + error.message);
            });
        } else {
          this.$modal.msgWarning("表单验证失败,请检查输入内容");
        }
      });
    },
  },
};
</script>

<style scoped lang="scss">
.container-box {
  ::v-deep .el-dialog.dialog-class {
    height: auto;
    height: 90vh;
    overflow-y: auto;
  }
  ::v-deep .el-dialog__body {
    height: 75vh !important;
  }
}

.divider-class {
  margin: 0 20px;
}
</style>

文档:http://lbs.tianditu.gov.cn/api/js4.0/examples.html

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

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

相关文章

【MySQL】高频 SQL 50 题(基础版)

高频SQL50题&#xff08;基础版&#xff09; 1.查询 2.连接 MySQL多表查询&#xff08;联合查询、连接查询、子查询&#xff09; left join 左连接 我们首先执行LEFT JOIN操作&#xff0c;将两个表的数据基于 id 列进行组合。同样&#xff0c;我们使用 LEFT JOIN 来确保将所…

什么是网关?网关有什么作用?API网关的主要功能,SpringCloud可以选择有哪些API网关?什么是限流算法?网关如何实现限流?一篇文章读懂网关的前世今生

1、什么是网关&#xff1f; API网关&#xff08;API Gateway&#xff09;是一种中间层服务器&#xff0c;用于集中管理&#xff0c;保护和路由对后端服务的访问。它充当了客户端与后端服务之间的入口点&#xff0c;提供了一组统一的接口管理和控制API的访问。 2、网关示意图 3…

Jenkins 配置 Git Repository 五

Jenkins 配置 Git Repository 五 这里包含了 Freestyle project 任务类型 和 Pipeline 任务类型 关于 Git 仓库的配置&#xff0c;如下 不同的任务类型&#xff0c;只是在不同的模块找到 配置 Git 仓库 找到 Git 仓库配置位置之后&#xff0c;所有的任务类型配置都是一样的 …

制作一个项目用于研究elementUI的源码

需求&#xff1a;修改el-tooltip的颜色&#xff0c;发现传递参数等方法都不太好用&#xff0c;也可以使用打断点的方式&#xff0c;但也有点麻烦&#xff0c;因此打算直接修改源码&#xff0c;把组件逻辑给修改了 第一步下载源码 源码地址 GitHub - ElemeFE/element: A Vue.j…

鸿蒙开发:了解@Builder装饰器

前言 本文代码案例基于Api13&#xff0c;温馨提示&#xff1a;内容相对来说比较简单&#xff0c;如果您已掌握&#xff0c;略过即可。 如果说一个页面中组件有很多&#xff0c;我们都统一写到build函数中&#xff0c;显而易见&#xff0c;会导致build函数代码非常冗余&#xff…

LabVIEW 中dde.llbDDE 通信功能

在 LabVIEW 功能体系中&#xff0c;位于 C:\Program Files (x86)\National Instruments\LabVIEW 2019\vi.lib\Platform\dde.llb 的 dde.llb 库占据着重要的地位。作为一个与动态数据交换&#xff08;DDE&#xff09;紧密相关的库文件&#xff0c;它为 LabVIEW 用户提供了与其他…

【Linux】Socket编程—TCP

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

001 SpringCloudAlibaba整合 - Nacos注册配置中心、Sentinel流控、Zipkin链路追踪、Admin监控

SpringCloudAlibaba 文章目录 SpringCloudAlibaba1.版本依赖关系2022.x 分支2021.x 分支2.2.x 分支 组件版本关系 2.基础项目构建1.引入全局pom文件2.创建对应的模块 3.SpringBootAdmin监控服务整合1.cloud-admin服务搭建1.导入服务端依赖2.主启动类添加EnableAdminServer注解启…

电动汽车电池监测平台系统设计(论文+源码+图纸)

1总体设计 本次基于单片机的电池监测平台系统设计&#xff0c;其整个系统架构如图2.1所示&#xff0c;其采用STC89C52单片机作为控制器&#xff0c;结合ACS712电流传感器、TLC1543模数转换器、LCD液晶、DS18B20温度传感器构成整个系统&#xff0c;在功能上可以实现电压、电流、…

DeepSeek从入门到精通:提示词设计的系统化指南

目录 引言&#xff1a;AIGC时代的核心竞争力 第一部分 基础篇&#xff1a;提示词的本质与核心结构 1.1 什么是提示词&#xff1f; 1.2 提示词的黄金三角结构 第二部分 类型篇&#xff1a;提示词的六大范式 2.1 提示语的本质特征 2.2 提示语的类型 2.2.1 指令型提示词 …

【VB语言】EXCEL中VB宏的应用

【VB语言】EXCEL中VB宏的应用 文章目录 [TOC](文章目录) 前言一、EXCEL-VB1.实验过程2.代码 二、EXCEL-VB 生成.c.h文件1.实验过程2.代码 四、参考资料总结 前言 1.WPS-VB扩展包 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、EXCEL-VB 1.实验过…

Redis7.0八种数据结构底层原理

导读 本文介绍redis应用数据结构与物理存储结构,共八种应用数据结构和 一. 内部数据结构 1. sds sds是redis自己设计的字符串结构有以下特点: jemalloc内存管理预分配冗余空间二进制安全(c原生使用\0作为结尾标识,所以无法直接存储\0)动态计数类型(根据字符串长度动态选择…

NixHomepage - 简单的个人网站

&#x1f4bb; NixHomepage - 简单的个人网站 推荐下个人的开源项目&#xff0c;演示网站&#xff0c;项目链接 https://github.com/nixgnauhcuy/NixHomepage&#xff0c;喜欢的话可以为我的项目点个 Star~ &#x1f4f7; 预览 ⚙️ 功能特性 多平台适配 明亮/暗黑模式切换 W…

给压缩文件加密码的5种方法(win/mac/手机/网页端)

把文件加密压缩&#xff0c;一方面能有效保护个人隐私与敏感信息&#xff0c;防止数据在传输或存储过程中被窃取、篡改。另一方面&#xff0c;压缩文件可减少存储空间占用&#xff0c;提升传输速度&#xff0c;方便数据的存储与分享。以下为你介绍5种常见的加密压缩方法。 一、…

如何通过AI轻松制作PPT?让PPT一键生成变得简单又高效

如何通过AI轻松制作PPT&#xff1f;让PPT一键生成变得简单又高效&#xff01;在这个信息化飞速发展的时代&#xff0c;PPT已经成为我们日常工作、学习和生活中不可或缺的一部分。无论是公司会议、学术报告&#xff0c;还是个人展示&#xff0c;PPT的作用都不容忽视。很多人对于…

Linux之【网络I/O】前世今生(二)

前文回顾 通过学习 Linux之【网络I/O】前世今生&#xff08;一&#xff09;&#xff0c;我们知道了I/O 请求可以分为两个阶段&#xff0c;分别为 I/O 调用和 I/O 执行&#xff1a; I/O 调用 即用户进程向内核发起系统调用(通过 0x80 中断)。 I/O 执行 内核等待 I/O 请求处理完…

Redis未授权访问漏洞导致getshell

一、漏洞信息 redis默认情况下会绑定在本地6379端口&#xff0c;如果没有进行采用相关的策略&#xff0c;就会将redis服务暴露到公网上&#xff0c;如果再没有设置密码认证(一般为空)的情况下&#xff0c;会导致任意用户可以访问到目标服务器的情况下未授权访问redis以及读取r…

伯克利 CS61A 课堂笔记 08 —— Strings and Dictionaries

本系列为加州伯克利大学著名 Python 基础课程 CS61A 的课堂笔记整理&#xff0c;全英文内容&#xff0c;文末附词汇解释。 目录 01 Strings 字符串 Ⅰ Strings are An Abstraction. Ⅱ Strings Literals have Three Forms Ⅲ String are Sequences 02 Dictionaries 字典 …

【Stable Diffusion模型测试】测试ControlNet,没有线稿图?

相信很多小伙伴跟我一样&#xff0c;在测试Stable Diffusion的Lora模型时&#xff0c;ControlNet没有可输入的线稿图&#xff0c;大家的第一反应就是百度搜&#xff0c;但是能从互联网上搜到的高质量线稿图&#xff0c;要么收费&#xff0c;要么质量很差。 现在都什么年代了&a…

智能手表表带圆孔同心度检测

在智能手表的制造工艺中&#xff0c;表带圆孔同心度检测是确保产品品质的关键环节。精准的同心度不仅关乎表带与表体的完美适配&#xff0c;更直接影响用户的佩戴舒适度和产品的整体美观度。稍有偏差&#xff0c;就可能导致表带安装困难、佩戴时出现晃动&#xff0c;甚至影响智…