LSTM卫星轨道预测(一)

news2024/11/29 22:44:29

一.多文件预测

代码详细解析


1. 文件读取与数据处理

功能
  • .sp3 文件中读取卫星轨迹数据。
  • 提取包括 Satellite_ID, X, Y, Z 等字段的信息。
  • 计算派生特征(如速度和加速度),便于后续建模使用。
主要函数:extract_sp3_data(file_path)
  • 正则表达式提取数据

    • 使用 re.match() 提取每行中有关卫星编号、轨迹坐标和其他列的信息。
    • 匹配模式:^PG(\d{2})\s+([-]?\d+\.\d+)\s+([-]?\d+\.\d+)\s+([-]?\d+\.\d+)\s+([-]?\d+\.\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)
      • PG(\d{2}): 匹配卫星编号。
      • ([-]?\d+\.\d+): 匹配 X, Y, Z 坐标值。
      • 其他字段:数值或整数类型的列。
  • 计算时间特征

    • 周期性特征 sin_timecos_time
      data_df['sin_time'] = np.sin(2 * np.pi * np.arange(num_rows) / num_rows)
      data_df['cos_time'] = np.cos(2 * np.pi * np.arange(num_rows) / num_rows)
      
      • 模拟时间周期的特性,有助于模型捕捉卫星轨迹的周期性变化。
  • 计算速度和加速度

    • 速度 Speed:基于坐标的欧几里得距离差分计算:
      speed = np.sqrt(np.diff(data_df['X'])**2 + np.diff(data_df['Y'])**2 + np.diff(data_df['Z'])**2)
      
    • 加速度 Accel_X, Accel_Y, Accel_Z:坐标的二阶差分。

数据合并
  • 将所有 .sp3 文件解析后的数据合并为一个完整的 DataFrame
    all_data_df = pd.concat([all_data_df, data_df], ignore_index=True)
    
保存数据
  • 将合并数据保存为 CSV 文件:
    all_data_df.to_csv(output_csv_path, index=False)
    

2. 数据加载与选择

加载数据
  • 使用 @st.cache_data 缓存处理后的 CSV 数据:
    data_df = load_data()
    
用户选择
  • 用户通过 Streamlit 的 selectbox 选择感兴趣的卫星编号:
    satellite_id = st.selectbox("选择卫星编号", satellite_ids)
    satellite_data = data_df[data_df['Satellite_ID'] == satellite_id]
    
特征完整性检查
  • 确保所有特征列(如 X, Y, Z, Speed, sin_time, cos_time)完整,否则报错:
    missing_features = [feature for feature in features if feature not in satellite_data.columns]
    if missing_features:
        st.error(f"缺少以下特征列:{', '.join(missing_features)}")
    
归一化处理
  • 使用 MinMaxScaler 将特征归一化为 [0, 1] 区间,便于训练模型:
    scaler = MinMaxScaler()
    scaled_data = scaler.fit_transform(satellite_data[features])
    

3. 序列数据创建

功能
  • 将归一化后的数据转换为时间序列形式,方便 LSTM 模型处理。
主要代码
  • 滑动窗口生成序列

    def create_sequences(data, seq_length=20):
        X, y = [], []
        for i in range(len(data) - seq_length):
            X.append(data[i:i+seq_length])
            y.append(data[i + seq_length][:3])  # 仅预测 X, Y, Z
        return np.array(X), np.array(y)
    
  • 生成特征和目标数据

    • 特征:时间序列的多维特征。
    • 目标:序列末尾的 X, Y, Z 坐标。

4. 模型定义与训练

模型架构
  • LSTM 模型

    • 两层 LSTM 层(num_layers=2),具有 64 维隐藏层。
    • 输出层是一个全连接层,用于预测 X, Y, Z 坐标。
  • 代码实现

    class LSTMModel(nn.Module):
        def __init__(self, input_size, hidden_size, output_size, num_layers=2):
            super(LSTMModel, self).__init__()
            self.lstm = nn.LSTM(input_size, hidden_size, num_layers=num_layers, batch_first=True, dropout=0.2)
            self.fc = nn.Linear(hidden_size, output_size)
    
        def forward(self, x):
            lstm_out, (h_n, c_n) = self.lstm(x)
            out = self.fc(lstm_out[:, -1, :])  # 输出序列最后一个时刻的预测值
            return out
    

训练过程
  • 损失函数与优化器

    • 使用均方误差(MSELoss)作为损失函数。
    • 使用 AdamW 优化器更新权重。
    • 使用 ReduceLROnPlateau 动态调整学习率。
  • 训练逻辑

    • 每个 epoch 记录训练损失值(loss_values),用于可视化。
    • 保存当前最佳模型参数:
      if avg_loss < best_loss:
          best_loss = avg_loss
          torch.save(model.state_dict(), 'best_lstm_model.pth')
      
损失值可视化
  • 使用 Matplotlib 绘制训练损失曲线:
    plt.figure(figsize=(10, 6))
    plt.plot(range(1, num_epochs + 1), loss_values, marker='o', linestyle='-', color='blue', label='Training Loss')
    plt.title("Training Loss over Epochs")
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.grid()
    plt.legend()
    st.pyplot(plt)
    

5. 预测与误差评估

预测
  • 加载最佳模型权重:
    model.load_state_dict(torch.load('best_lstm_model.pth'))
    model.eval()
    
  • 使用模型预测坐标并反归一化,得到实际坐标。
误差评估
  • 使用 mean_squared_error, mean_absolute_error, 和 r2_score 等指标评估模型性能:
    mse = mean_squared_error(true_coordinates, predicted_df[['X', 'Y', 'Z']].values)
    rmse = np.sqrt(mse)
    mae = mean_absolute_error(true_coordinates, predicted_df[['X', 'Y', 'Z']].values)
    r2 = r2_score(true_coordinates, predicted_df[['X', 'Y', 'Z']].values)
    

6. 轨迹可视化

功能
  • 使用 Plotly 绘制 3D 图形,直观展示历史轨迹与预测轨迹的对比。
代码实现
  • 历史轨迹(青色线条)

    fig.add_trace(go.Scatter3d(
        x=satellite_data['X'], y=satellite_data['Y'], z=satellite_data['Z'],
        mode='lines',
        line=dict(color='cyan', width=4)
    ))
    
  • 预测轨迹(红色线条)

    fig.add_trace(go.Scatter3d(
        x=predicted_coordinates[:, 0], y=predicted_coordinates[:, 1], z=predicted_coordinates[:, 2],
        mode='lines',
        line=dict(color='red', width=4)
    ))
    
  • 更新布局
    设置图形标题和坐标轴标签:

    fig.update_layout(
        title="历史轨迹与预测轨迹对比",
        scene=dict(xaxis_title='X', yaxis_title='Y', zaxis_title='Z'),
        margin=dict(r=0, l=0, b=0, t=0)
    )
    

关键输出

  1. 训练损失曲线
    • 展示损失值随训练迭代的变化趋势。
  2. 预测结果表
    • 显示预测的 X, Y, Z 坐标值。
  3. 误差评估指标
    • 输出 MSE、RMSE、MAE 和 R² 值。
  4. 轨迹对比图
    • 3D 轨迹图对比历史
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

精度评定:
均方误差 (MSE):150749.9629
均方根误差 (RMSE): 388.2653
平均绝对误差 (MAE): 286.9628
R²:0.9994
在这里插入图片描述
在这里插入图片描述

完整代码

import re
import streamlit as st
import pandas as pd
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import plotly.graph_objects as go

# 文件路径
sp3_file_paths = ['igs16370.sp3', 'igs16371.sp3', 'igs16372.sp3']
output_csv_path = 'output_data.csv'

# 解析 SP3 文件,提取所有数据列
def extract_sp3_data(file_path):
    satellite_data_pattern = r"^PG(\d{2})\s+([-]?\d+\.\d+)\s+([-]?\d+\.\d+)\s+([-]?\d+\.\d+)\s+([-]?\d+\.\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)"
    satellite_ids, timestamps, x_coords, y_coords, z_coords = [], [], [], [], []
    col_5, col_6, col_7, col_8 = [], [], [], []  # 额外四列

    with open(file_path, 'r') as file:
        for line in file:
            match = re.match(satellite_data_pattern, line)
            if match:
                satellite_id = match.group(1)
                x = float(match.group(2))
                y = float(match.group(3))
                z = float(match.group(4))
                col_5_value = float(match.group(5))
                col_6_value = int(match.group(6))
                col_7_value = int(match.group(7))
                col_8_value = int(match.group(8))

                satellite_ids.append(satellite_id)
                x_coords.append(x)
                y_coords.append(y)
                z_coords.append(z)
                col_5.append(col_5_value)
                col_6.append(col_6_value)
                col_7.append(col_7_value)
                col_8.append(col_8_value)

    data_df = pd.DataFrame({
        "Satellite_ID": satellite_ids,
        "X": x_coords,
        "Y": y_coords,
        "Z": z_coords,
        "Col5": col_5,
        "Col6": col_6,
        "Col7": col_7,
        "Col8": col_8,
    })

    # 计算周期性时间特征
    num_rows = len(data_df)
    data_df['sin_time'] = np.sin(2 * np.pi * np.arange(num_rows) / num_rows)
    data_df['cos_time'] = np.cos(2 * np.pi * np.arange(num_rows) / num_rows)

    # 计算速度(X, Y, Z 差分)
    speed = np.sqrt(np.diff(data_df['X'])**2 + np.diff(data_df['Y'])**2 + np.diff(data_df['Z'])**2)
    speed = np.append(speed, np.nan)  # 确保列长度一致
    data_df['Speed'] = speed

    # 计算加速度(X, Y, Z 的二阶差分)
    acc_x = np.diff(data_df['X'], n=2)
    acc_y = np.diff(data_df['Y'], n=2)
    acc_z = np.diff(data_df['Z'], n=2)
    acc_x = np.append(acc_x, [np.nan, np.nan])  # 补充 NaN 保持长度一致
    acc_y = np.append(acc_y, [np.nan, np.nan])
    acc_z = np.append(acc_z, [np.nan, np.nan])
    data_df['Accel_X'] = acc_x
    data_df['Accel_Y'] = acc_y
    data_df['Accel_Z'] = acc_z

    return data_df

# 提取所有文件的数据并合并
all_data_df = pd.DataFrame()
for file_path in sp3_file_paths:
    data_df = extract_sp3_data(file_path)
    all_data_df = pd.concat([all_data_df, data_df], ignore_index=True)

# 保存合并后的数据到 CSV
all_data_df.to_csv(output_csv_path, index=False)
print("数据已提取并保存到 CSV 文件。")

# 加载数据
@st.cache_data
def load_data():
    data_path = output_csv_path
    data_df = pd.read_csv(data_path)
    return data_df

# 加载并筛选数据
data_df = load_data()
satellite_ids = data_df['Satellite_ID'].unique()
st.title("卫星轨道预测与轨迹展示")
satellite_id = st.selectbox("选择卫星编号", satellite_ids)
satellite_data = data_df[data_df['Satellite_ID'] == satellite_id]

# 使用历史数据作为真实轨迹数据进行对比
real_satellite_data = satellite_data

# 特征列表
features = ['X', 'Y', 'Z', 'sin_time', 'cos_time', 'Speed', 'Accel_X', 'Accel_Y', 'Accel_Z']

missing_features = [feature for feature in features if feature not in satellite_data.columns]
if missing_features:
    st.error(f"缺少以下特征列:{', '.join(missing_features)}")
else:
    # 数据预处理
    scaler = MinMaxScaler()
    scaled_data = scaler.fit_transform(satellite_data[features])

    # 创建训练序列
    def create_sequences(data, seq_length=20):
        X, y = [], []
        for i in range(len(data) - seq_length):
            X.append(data[i:i+seq_length])
            y.append(data[i + seq_length][:3])  # 仅预测 X, Y, Z
        return np.array(X), np.array(y)

    seq_length = 20
    X, y = create_sequences(scaled_data, seq_length)

    # 转换为 PyTorch 张量
    X_tensor = torch.tensor(X, dtype=torch.float32)
    y_tensor = torch.tensor(y, dtype=torch.float32)

    # 创建 DataLoader
    batch_size = 32
    dataset = TensorDataset(X_tensor, y_tensor)
    train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

    # 定义 PyTorch LSTM 模型
    class LSTMModel(nn.Module):
        def __init__(self, input_size, hidden_size, output_size, num_layers=2):
            super(LSTMModel, self).__init__()
            self.lstm = nn.LSTM(input_size, hidden_size, num_layers=num_layers, batch_first=True, dropout=0.2)
            self.fc = nn.Linear(hidden_size, output_size)

        def forward(self, x):
            lstm_out, (h_n, c_n) = self.lstm(x)
            out = self.fc(lstm_out[:, -1, :])
            return out

    # 初始化模型
    input_size = X.shape[2]
    hidden_size = 64
    output_size = 3
    model = LSTMModel(input_size, hidden_size, output_size)

    # 损失函数与优化器
    criterion = nn.MSELoss()
    optimizer = torch.optim.AdamW(model.parameters(), lr=0.001)

    # 学习率调度器
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'min', patience=10, verbose=True)

    # 存储每个 epoch 的损失值
    loss_values = []

    # 训练模型
    st.write("训练模型中,请稍等...")
    num_epochs = 50
    best_loss = float('inf')
    for epoch in range(num_epochs):
        model.train()
        total_loss = 0
        for batch_X, batch_y in train_loader:
            optimizer.zero_grad()
            output = model(batch_X)
            loss = criterion(output, batch_y)
            loss.backward()
            optimizer.step()
            total_loss += loss.item()

        avg_loss = total_loss / len(train_loader)
        loss_values.append(avg_loss)  # 保存每个 epoch 的平均损失值
        scheduler.step(avg_loss)

        if avg_loss < best_loss:
            best_loss = avg_loss
            torch.save(model.state_dict(), 'best_lstm_model.pth')

        if (epoch + 1) % 10 == 0:
            st.write(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {avg_loss:.4f}")

    # 绘制损失值的可视化图
    st.subheader("训练损失值变化图:")
    import matplotlib.pyplot as plt

    plt.figure(figsize=(10, 6))
    plt.plot(range(1, num_epochs + 1), loss_values, marker='o', linestyle='-', color='blue', label='Training Loss')
    plt.title("Training Loss over Epochs")
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.grid()
    plt.legend()
    st.pyplot(plt)


    # 最佳模型
    model.load_state_dict(torch.load('best_lstm_model.pth'))
    model.eval()

    # 预测结果
    with torch.no_grad():
        predicted_scaled = model(X_tensor).numpy()

    # 反标准化预测结果
    predicted_df = pd.DataFrame(predicted_scaled, columns=['X_scaled', 'Y_scaled', 'Z_scaled'])

    # 拼接其他特征
    predicted_sin_time = np.tile(satellite_data['sin_time'].iloc[-1], (predicted_df.shape[0], 1))
    predicted_cos_time = np.tile(satellite_data['cos_time'].iloc[-1], (predicted_df.shape[0], 1))
    predicted_speed = np.tile(satellite_data['Speed'].iloc[-1], (predicted_df.shape[0], 1))
    predicted_accel_x = np.tile(satellite_data['Accel_X'].iloc[-1], (predicted_df.shape[0], 1))
    predicted_accel_y = np.tile(satellite_data['Accel_Y'].iloc[-1], (predicted_df.shape[0], 1))
    predicted_accel_z = np.tile(satellite_data['Accel_Z'].iloc[-1], (predicted_df.shape[0], 1))

    predicted_full_features = np.hstack((
        predicted_df[['X_scaled', 'Y_scaled', 'Z_scaled']].values,
        predicted_sin_time,
        predicted_cos_time,
        predicted_speed,
        predicted_accel_x,
        predicted_accel_y,
        predicted_accel_z
    ))

    predicted_full_features_inverse = scaler.inverse_transform(predicted_full_features)

    predicted_coordinates = predicted_full_features_inverse[:, :3]
    predicted_df[['X', 'Y', 'Z']] = predicted_coordinates

    st.subheader("预测结果:")
    st.write(predicted_df[['X', 'Y', 'Z']])

    # 计算误差
    true_coordinates = real_satellite_data[['X', 'Y', 'Z']].iloc[seq_length:].values  # 使用真实的坐标数据

    mse = mean_squared_error(true_coordinates, predicted_df[['X', 'Y', 'Z']].values)
    rmse = np.sqrt(mse)
    mae = mean_absolute_error(true_coordinates, predicted_df[['X', 'Y', 'Z']].values)
    r2 = r2_score(true_coordinates, predicted_df[['X', 'Y', 'Z']].values)

    st.subheader("精度评定:")
    st.write(f"均方误差 (MSE): {mse:.4f}")
    st.write(f"均方根误差 (RMSE): {rmse:.4f}")
    st.write(f"平均绝对误差 (MAE): {mae:.4f}")
    st.write(f"R²: {r2:.4f}")

    # 可视化预测轨迹与历史数据对比
    fig = go.Figure()

    # 绘制历史轨迹,仅有一条轨迹
    fig.add_trace(go.Scatter3d(
        x=satellite_data['X'], y=satellite_data['Y'], z=satellite_data['Z'],
        mode='lines',
        line=dict(color='cyan', width=4)
    ))

    fig.add_trace(go.Scatter3d(
        x=predicted_coordinates[:, 0], y=predicted_coordinates[:, 1], z=predicted_coordinates[:, 2],
        mode='lines',
        line=dict(color='red', width=4)
    ))

    # 更新布局,设置标题和坐标轴标签
    fig.update_layout(
        title="历史轨迹与预测轨迹对比",
        scene=dict(xaxis_title='X', yaxis_title='Y', zaxis_title='Z'),
        margin=dict(r=0, l=0, b=0, t=0)
    )

    # 显示图表
    st.plotly_chart(fig)

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

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

相关文章

如何通过智能生成PPT,让演示文稿更高效、更精彩?

在快节奏的工作和生活中&#xff0c;我们总是追求更高效、更精准的解决方案。而在准备演示文稿时&#xff0c;PPT的制作往往成为许多人头疼的问题。如何让这项工作变得轻松且富有创意&#xff1f;答案或许就在于“AI生成PPT”这一智能工具的广泛应用。我们就来聊聊如何通过这些…

格网法计算平面点云面积(matlab版本)

1、原理介绍 格网法计算平面点云面积&#xff0c;其思想类似高中油膜法计算面积。其将点云投影到水平面&#xff0c;再将点云划分成尺寸相同的格网。最后&#xff0c;统计格网内包含点的数量number&#xff0c;那么可利用如下公式计算得到点云的面积&#xff1a; Aeranumber*L…

无代码实现可视化GIS+模型+三维

现在的工具是越来越方便了&#xff0c;本来不是做前端的。可以节省很多的人力和时间&#xff0c;更快的搭建自己想要的可视化大屏&#xff0c;看例子 主要由三维的gis地图和模型加上二维的数据表格分析来实现这个可视化界面。 gis地图的设置 每一个gis都要设置世界远点&#x…

Jmeter中的监听器

3&#xff09;监听器 1--查看结果树 用途 调试测试计划&#xff1a;查看每个请求的详细信息&#xff0c;帮助调试和修正测试计划。分析响应数据&#xff1a;查看服务器返回的响应数据&#xff0c;验证请求是否成功。检查错误&#xff1a;识别和分析请求失败的原因。 配置步骤…

kafka进阶_3.消费消息

文章目录 一、消费消息概览1.1、消费示例代码1.2、消费过程 二、消费者组2.1、push & pull2.2、消费者组 三、调度器Coordinator四、消费者分配策略4.1、引言4.2、分配基本流程4.3、分配策略4.3.1、轮询分配策略4.3.2、轮询分配策略 五、消费偏移量5.1、起始偏移量5.2、指定…

用VC2019+MFC 创建一个DLL封装MD工业相机库然后用EXE调用这个相机库采图并且显示

主要描述&#xff1a; 用VC2019MFC 创建一个DLL封装MD工业相机库&#xff0c;再建一个EXE调用这个相机库采图并且显示。 先创建库工程&#xff1a; 新建一个库工程&#xff0c; 创建完成&#xff0c;添加一个DllFunction.h头文件&#xff0c;一个DllFunction.cpp 源文件 拷贝…

ODB 框架

目录 概述 基本工作原理 映射C对象到数据库表 从数据库中加载对象 持久化C对象到数据库 ODB常用接口 表创建预处理 #pragma db Object table 数据表属性 id auto column&#xff08;“xxx”&#xff09; type("xxx") unique index null default&…

ModuleNotFoundError: No module named ‘_ssl‘ centos中的Python报错

1、检查系统有没有openssl&#xff0c;有的话&#xff0c;就是python安装时没有指定openssl openssl version&#xff0c;有输出版本号就有&#xff0c;没有的话&#xff0c;需要手动安装 下载地址 参见https://www.openssl.org/&#xff0c;包括以下版本&#xff1a; https:/…

小程序-基于java+SpringBoot+Vue的微信小程序养老院系统设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

linux高级系统编程之进程

进程 一个正在进行的程序 并行与并发 并行:执行的程序在不同CPU上同时执行 并发:一个CPU,多个进程交替执行,因为交替速度很快,所以从宏观上来看是同时执行的,但是从围观的角度是交替执行的 单道与多道 单道程序设计:所有进程一个一个排队执行,若A阻塞,B只能等待,,即使CPU处于空…

GitHub Copilot革命性更新:整合顶尖AI模型,如何重塑开发体验?

在技术快速发展的今天&#xff0c;代码辅助工具已成为提升开发效率的利器。今天&#xff0c;我们带来了一个激动人心的消息——GitHub Copilot宣布引入多模型选择功能&#xff0c;这不仅是技术上的一次飞跃&#xff0c;更是对开发者工作流程的一次革新。 多模型选择&#xff1a…

AppFlow:支持飞书机器人调用百炼应用

AppFlow&#xff1a;支持飞书机器人调用百炼应用 简介&#xff1a; 本文介绍了如何创建并配置飞书应用及机器人&#xff0c;包括登录飞书开发者后台创建应用、添加应用能力和API权限&#xff0c;以及通过AppFlow连接流集成阿里云百炼服务&#xff0c;最后详细说明了如何将机器…

华为E9000刀箱(HWE9000V2)服务器硬件监控指标解读

随着数据中心规模的不断扩大&#xff0c;服务器的稳定性和可靠性变得尤为重要。华为E9000刀箱&#xff08;HWE9000V2&#xff09;作为一款高性能的服务器设备&#xff0c;其硬件状态的实时监控对于保障业务的连续性和系统的稳定运行至关重要。 监控易作为一款专业的IT基础设施监…

GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解

GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解 目录 GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GWO-SVMD灰狼算法优化逐次变分模态分解 内有15种用以优化svmd的适应度函数&#…

景联文科技:高质量数据采集标注服务引领AI革新

在当今这个数字化时代&#xff0c;数据已经成为推动社会进步和产业升级的关键资源。特别是在人工智能领域&#xff0c;高质量的数据是训练出高效、精准的AI模型的基础。景联文科技是一家专业的数据采集与标注公司&#xff0c;致力于为客户提供高质量的数据处理服务&#xff0c;…

pycharm添加gitee插件

一、拉取gitee上托管的代码到本地&#xff0c;用pycharm运行 前置条件 1.安装python运行环境 2.安装pycharm 安装&#xff1a;https://blog.csdn.net/m0_65482549/article/details/141394352 1.3.安装git git config --global user.name “" git config --global user.em…

Echarts 绘制地图

一、Apache Echarts 官网地址&#xff1a;https://echarts.apache.org/ npm install echarts --save 二、获取地图的GeoJSON 地址&#xff1a;DataV.GeoAtlas地理小工具系列 左侧是地图&#xff0c;右侧是JSON数据路径&#xff0c;点击你想要生成的地图省市、地级&#xff0…

DHCP服务(包含配置过程)

目录 一、 DHCP的定义 二、 使用DHCP的好处 三、 DHCP的分配方式 四、 DHCP的租约过程 1. 客户机请求IP 2. 服务器响应 3. 客户机选择IP 4. 服务器确定租约 5. 重新登录 6. 更新租约 五、 DHCP服务配置过程 一、 DHCP的定义 DHCP&#xff08;Dynamic Host Configur…

html+css+js网页设计 旅游 厦门旅游网14个页面

htmlcssjs网页设计 旅游 厦门旅游网14个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&am…

springboot(20)(删除文章分类。获取、更新、删除文章详细)(Validation分组校验)

目录 一、删除文章分类功能。 &#xff08;1&#xff09;接口文档。 1、请求路径、请求参数。 2、请求参数。 3、响应数据。 &#xff08;2&#xff09;实现思路与代码书写。 1、controller层。 2、service接口业务层。 3、serviceImpl实现类。 4、mapper层。 5、后端接口测试。…