对于geoserver发布数据后的开发应用

news2025/7/19 15:42:30

对于geoserver发布数据后的开发应用


文章目录

  • 对于geoserver发布数据后的开发应用
    • @[TOC](文章目录)
  • 前言
  • 一、geosever管理地理数据的后端实用方法
    • 后端进行登录geoserver并且发布一个矢量数据
      • 前置的domain数据准备
      • 后端内容
  • 总结

前言

首先,本篇文章仅进行技术分享,某些数据并不会公开。
目前其实还不太会用arcgis发布某些图层数据,但是知道怎么用。


一、geosever管理地理数据的后端实用方法

由于目前工作的局限性,之前的代码都是用geoserver来进行保存的,所以需要构建一个强大的后端处理技术来保证与前端交互的时候,某些服务能服务于非Gis人员。
我的geosever是由docker进行安装的 ,具体可以看下面的文章,用windows直接按照也是可以的,只是我好不容易装好docker不方便我用的话就很累。
docker搭建geoserver
启动下面的镜像
在这里插入图片描述
访问本地的8090端口,正常登录即可
在这里插入图片描述
查看一下数据预览
在这里插入图片描述
在这里插入图片描述
接下来要写一下仿照geoserver进行登录的操作,待会我去把这个遥感数据删除,用后端进行管理geoserver的发布。

后端进行登录geoserver并且发布一个矢量数据

因为我要写一个模块,专门用于发布矢量数据并且使用cesium去将这个数据的wms服务给请求下来加载到图层上去。
大致思路是mysql用于持久化系统数据,pgsql对于每一个shp数据进行创建表,用于存贮上传shp数据里的dbf表数据,至于为什么要存这玩意,其实是因为要导出为Excel表方便统计,并且做成功能。
首先是思考的是手动操作的流程,登录geosever,然后得到目标文件的文件路径,发布数据选择样式,发布成功后,获取它的wms服务链接,存到mysql数据库里,得到它的dbf数据,存到pgsql里,下面是这些步骤的代码。

前置的domain数据准备

先写一个实体类先

import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import java.util.Date;

/**
 * @Author chuxuan
 * @Date 2025/5/23
 * @Description TODO:这是用于shp数据管理的实体类 
 */
@Data
public class ShpDetail {
    private static final long serialVersionUID = 1L;

    /**
     * 主键id
     */
    private Long id;

    /**
     * shp名称
     */
    @Excel(name = "shp名称")
    private String name;

    /**
     * shp文件名称
     */
    @Excel(name = "shp文件名称")
    private String fileName;

    /**
     * geoserver的工作区
     */
    @Excel(name = "geoserver的工作区")
    private String geoserverWorkArea;


    /**
     * 数据库表名
     */
    @Excel(name = "数据库表名")
    private String tableName;

    /**
     * 数据库字段名,逗号分割
     */
    @Excel(name = "数据库字段名,逗号分割")
    private String tableField;

    /**
     * 数据时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "数据时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date dataTime;

    /**
     * 缩略图
     */
    @Excel(name = "缩略图")
    private String thumbUrl;

    /**
     * shp坐标编码
     */
    @Excel(name = "shp坐标编码")
    private String srs;

    /**
     * wms的url
     */
    @Excel(name = "wms的url")
    private String wmsUrl;

    /**
     * 图层名称
     */
    @Excel(name = "图层名称")
    private String layerName;

    /**
     * 图层样式名称
     */
    @Excel(name = "图层样式名称")
    private String sldName;

    /**
     * 边界
     */
    @Excel(name = "边界")
    private String box;

    /**
     * 图例id
     */
    @Excel(name = "图例id")
    private Long legendId;

    /**
     * 删除标志(0代表存在 2代表删除)
     */
    private String delFlag;

    /**
     * 中心点纬度
     */
    @Excel(name = "中心点纬度")
    private String viewCenterLat;

    /**
     * 中心点经度
     */
    @Excel(name = "中心点经度")
    private String viewCenterLong;

    /**
     * 级别,默认11
     */
    @Excel(name = "级别,默认11")
    private Integer viewZoom;

    /**
     * 备注
     */
    @Excel(name = "备注")
    private String remark;

    /**
     * 创建者
     */
    private String createBy;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 更新者
     */
    private String updateBy;

    /**
     * 更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    /**
     * 是否包含必要字段
     */
    private Boolean needfulStatus;

    /**
     * 特别排除的字段,有些字段无法保存的需要排除掉
     */
    private String excludeFields;

    /**
     * 图例名曾
     */
    @TableField(exist = false)
    private String legendName;
}

shp数据添加的AddDTO,作用是在我们上传的时候将发布图层的style等参数都放进去,以及一个简单是shp数据。
由此可以设计DTO

import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import java.util.Date;
import java.util.List;
import lombok.Data;
/**
 * @Author chuxuan
 * @Date 2025/5/23
 * @Description TODO:这是用于shp数据上传的DTO类 
 */
@Data
public class ShpDetailAddDTO {
    private static final long serialVersionUID = 1L;
    /** 主键id */
    @Excel(name = "主键id")
    private Long id;

    /** shp文件名称 */
    @Excel(name = "shp文件名称")
    private String fileName;

    /** shp中文简称 */
    @Excel(name = "shp中文简称")
    private String name;

    /** 数据时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "数据时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date dataTime;

    /** 数据库表名 */
    @Excel(name = "数据库表名")
    private String tableName;

    /** 图层样式名称 */
    @Excel(name = "图层样式名称")
    private String sldName;

    /** 图例id */
    @Excel(name = "图例id")
    private Long legendId;

    /** geoserver的工作区 */
    @Excel(name = "geoserver的工作区")
    private String geoserverWorkArea;

    /** 图层名称 */
    @Excel(name = "图层名称")
    private String layerName;


    /** 级别,默认11 */
    @Excel(name = "级别,默认11")
    private Integer viewZoom;

    /** 备注 */
    @Excel(name = "备注")
    private String remark;

    /** 中心点纬度 */
    @Excel(name = "中心点纬度")
    private String viewCenterLat;

    /** 中心点经度 */
    @Excel(name = "中心点经度")
    private String viewCenterLong;

    /** 缩略图 */
    @Excel(name = "缩略图")
    private String thumbUrl;


    /** shp坐标编码 */
    @Excel(name = "shp坐标编码")
    private String srs = "4326";

    /** 数据归属区域(可多选) */
    @Excel(name = "数据归属区域(可多选)")
    private List<Long> areaList;

    /** 数据归属分类(可多选) */
    @Excel(name = "数据归属分类(可多选)")
    private List<Long> classifyList;

    @Excel(name = "是否包含必要字段")
    private Boolean needfulStatus;

    @Excel(name = "特别排除的字段")
    private String excludeFields;
}

然后是一个获取geoserver的配置类,需要从数据库中获取,这个类我已经写好了,只需要去写一下方法即可
先指导AI干活,帮我把某个配置类的注解和注释都写正规一点
写好对应的获取geosever的配置
geoserver获取配置
然后因为配置化的原因,写了很久的代码,系统太复杂了,光理解代码都要了很长时间

后端内容

  1. geoserver的登录
  2. 数据的上传以及解包
  3. geoserver的上传参数配置以及相关的数据库配置字段,pgsql的shp数据建表
  4. geoserver上的以及数据库上的相关增删改查
  5. 总结来说,3个服务并且使用多个DTO才能组成后端服务

geosever登录
首先是Geosever的Utils工具,写在common里utils里去

import it.geosolutions.geoserver.rest.GeoServerRESTManager;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.GeoServerRESTReader;
import it.geosolutions.geoserver.rest.decoder.RESTLayer;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.datastore.GSShapefileDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Base64;
public class GeoServerUtils {


    /**
     * shp数据发布
     * 图层 发布
     *
     * @param url
     * @param userName
     * @param passWord
     * @param FilePath    文件路径
     * @param workSpace   工作区名称
     * @param dataSetName 数据存储名称
     * @param layerName   图层名称
     */
    public static void publishShape(String url, String userName, String passWord, String FilePath, String workSpace, String dataSetName, String layerName, String type) throws IOException {
        File file = new File(FilePath);
        // 连接geoServer
        GeoServerRESTManager geoServerRESTManager = null;
        try {
            geoServerRESTManager = new GeoServerRESTManager(new URL(url), userName, passWord);
        } catch (Exception e) {
            System.out.println("远程连接GeoServer失败...");
            e.printStackTrace();
        }
        // shp读写和发布
        assert geoServerRESTManager != null;
        GeoServerRESTReader restReader = geoServerRESTManager.getReader();
        GeoServerRESTPublisher restPublisher = geoServerRESTManager.getPublisher();

        // 存在相应的工作区
        if (!restReader.existsWorkspace(workSpace)) {
            restPublisher.createWorkspace(workSpace);
        } else {
            System.out.println("workSpace已经存在了,workSpace :" + workSpace);
        }

        if (!restReader.existsDatastore(workSpace, dataSetName)) {
            //创建shape文件存储
            try {
                //shp文件所在的位置
                String urlDataStorePath = file.getPath();
                // 数据存储需要的文件
                String shpFilePath = String.format("file://%s", urlDataStorePath);
                URL urlShapeFile = new URL(shpFilePath);
                // 创建数据集
                GSShapefileDatastoreEncoder datastoreEncoder = new GSShapefileDatastoreEncoder(dataSetName, urlShapeFile);
                datastoreEncoder.setCharset(Charset.forName("UTF-8"));
                geoServerRESTManager.getStoreManager().create(workSpace, datastoreEncoder);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }

        // 图层layer
        if (!restReader.existsLayer(workSpace, layerName)) {
            try {
                GSFeatureTypeEncoder gsFeatureTypeEncoder = new GSFeatureTypeEncoder();
                gsFeatureTypeEncoder.setTitle(layerName);
                gsFeatureTypeEncoder.setName(layerName);
                gsFeatureTypeEncoder.setSRS(GeoServerRESTPublisher.DEFAULT_CRS);
                GSLayerEncoder gsLayerEncoder = new GSLayerEncoder();
//                 gsLayerEncoder.addStyle("grass");
                boolean layer = restPublisher.publishDBLayer(workSpace, dataSetName, gsFeatureTypeEncoder, gsLayerEncoder);
                System.out.println("publish layer : " + layer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //绑定样式sld
        if (!StringUtils.isEmpty(type)){
            styleBinding(url,workSpace,layerName,type,userName,passWord);
        }
//        styleBinding(url,workSpace,layerName,type+"_style",userName,passWord);


    }


    public static String GeoServerReader(String url, String userName, String passWord, String workspaceName, String workspaceLayerName) throws IOException {
        GeoServerRESTReader restReader = new GeoServerRESTReader(url, userName, passWord);

        OkHttpClient client = new OkHttpClient();
        String bbox = null;
        try {
            // 构建请求
            Request request = new Request.Builder()
                    .url(url + "/wms?request=GetCapabilities&service=WMS&version=1.3.0")
                    .build();
            // 发送请求并获取响应
            Response response = client.newCall(request).execute();
            String responseBody = response.body().string();

            // 解析 GetCapabilities 响应
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new InputSource(new StringReader(responseBody)));
            // 查找指定图层的边界框信息
            NodeList layerNodes = doc.getElementsByTagName("Layer");
            for (int i = 0; i < layerNodes.getLength(); i++) {
                Element layerElement = (Element) layerNodes.item(i);
                //旧逻辑
                String layerWorkspace = layerElement.getAttribute("queryable");
                String layerTitle = layerElement.getElementsByTagName("Name").item(0).getTextContent();
                //新逻辑
//                String layerWorkspace = workspaceName;
//                String layerTitle = workspaceLayerName;
//                if (layerWorkspace.equals(workspaceName) || layerTitle.equals(workspaceLayerName)) {
                    bbox = layerElement.getElementsByTagName("EX_GeographicBoundingBox").item(0).getTextContent();
                    break;
//                }
            }
            // 关闭响应
            response.close();
        } catch (IOException | ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }
        String formatting = GeoServerUtils.formatting(bbox);
        return formatting;
    }

    /**
     * 数据格式处理方法
     *
     * @param data
     * @return
     */
    public static String formatting(String data) {
        data = data.replaceAll("\\s+(?=\\d)", ",");
        data = String.join(",", data.replace("\n", ","));
        // 去除逗号后的空格
        data = data.replaceAll(",\\s+", ",");
        data = data.replaceFirst(",", "");
        data = data.replaceAll(",$", "");
        String[] parts = data.split(",");
        String output = null;
        if (parts.length >= 4) {
            // 交换第一个逗号后面的数和第二个逗号后面的数
            String temp = parts[1];
            parts[1] = parts[2];
            parts[2] = temp;
            // 重新组合成一个新的字符串
            output = String.join(",", parts);
        }
        return output;
    }

    /**
     * 图层样式绑定
     *
     * @param geoServerUrl
     * @param workspace
     * @param layerName
     * @param styleName
     * @param username
     * @param password
     * @throws IOException
     */
    public static void styleBinding(String geoServerUrl, String workspace, String layerName, String styleName, String username, String password) throws IOException {
        // 构建REST API请求URL
        String urlStr = geoServerUrl + "rest/layers/" + workspace + ":" + layerName;
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        // 设置HTTP方法为PUT
        conn.setRequestMethod("PUT");
        conn.setDoOutput(true);

        // 设置基本认证
        String auth = username + ":" + password;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
        conn.setRequestProperty("Authorization", "Basic " + encodedAuth);

        // 设置Content-Type为application/xml
        conn.setRequestProperty("Content-Type", "application/xml");

        // 构建XML数据
        String xmlData = "<layer>" +
                "<defaultStyle>" +
                "<name>" + styleName + "</name>" +
                "</defaultStyle>" +
                "</layer>";

        // 发送请求数据
        OutputStream os = conn.getOutputStream();
        os.write(xmlData.getBytes());
        os.flush();
        // 获取响应码
        int responseCode = conn.getResponseCode();
        if (responseCode == 200) {
            System.out.println("样式绑定成功!");
        } else {
            System.out.println("样式绑定失败,响应码:" + responseCode);
        }
    }

    public static void deleteLayer(String geoServerUrl, String username, String password, String workspace, String layerName) throws MalformedURLException {
        // 创建 GeoServer REST 管理器
        URL url = new URL(geoServerUrl);
        GeoServerRESTManager manager = new GeoServerRESTManager(url, username, password);
        GeoServerRESTPublisher publisher = manager.getPublisher();
        // 删除图层
        boolean deleted = publisher.unpublishFeatureType(workspace, layerName, layerName);
        //删除数据集
        boolean deletedData = publisher.removeDatastore(workspace,layerName,true);
        if (deleted && deletedData) {
            System.out.println("Layer '" + layerName + "' deleted successfully.");
        } else {
            System.out.println("Failed to delete layer '" + layerName + "'.");
        }
    }

}

然后通过引用这些数据就能实现连接geoserver并进行管理增删改查

String url = hsSysConfigService.getGeoserverUrl();//获取url配置
String username = hsSysConfigService.getGeoserverUsername();//获取geoserver的用户名
String password = hsSysConfigService.getGeoserverPassword();//获取geoserver的密码
String uploadDir = hsSysConfigService.getUploadUrl()+"/"+dto.getFileName()+"/"; // 文件保存的路径
String filePath = file.getPath();
File file = new File(uploadDir +dto.getFileName()+".shp");
// 如果存在".",则截取文件名的子串
String filenameWithoutExtension = dto.getFileName();
try {
		//这个是一个上传到geoserver的例子
		//1.模拟首先是登录
		//2.然后文件路径必须是shp矢量数据的路径,
		//然后dto的getGeoserverWorkArea是工作空间,
		//filenameWithoutExtension是文件前缀
		//最后hsLegend.getSldStyle()是geoserver里的样式
        GeoServerUtils.publishShape(url, username, password, filePath, dto.getGeoserverWorkArea(), filenameWithoutExtension, filenameWithoutExtension,hsLegend.getSldStyle());
        } catch (IOException e) {
            e.printStackTrace();
        }

上传就不多写了,其实如果说,上传的数据是需要合并的数据的话,那就上传一个压缩包,最大大小自己注意即可
读取矢量数据的工具库
首先是建立一些有用的,要做到的有合并矢量数据以及读取矢量数据

import java.util.*;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
/**
     * 矢量数据合并
     *
     * @param list       矢量文件集合
     * @param outputFile 文件输出路径
     */
    public static void mergeShapeFiles(List<String> list, String outputFile) throws IOException {
        List<SimpleFeatureCollection> featureCollections = new ArrayList<>();
        // 读取所有输入的Shapefile文件
        for (String filePath : list) {
            File file = new File(filePath);
            ShapefileDataStore dataStore = new ShapefileDataStore(file.toURI().toURL());
            SimpleFeatureSource featureSource = dataStore.getFeatureSource();
            featureCollections.add(featureSource.getFeatures());
            dataStore.dispose();
        }
        // 获取Shapefile的Feature类型
        SimpleFeatureType schema = featureCollections.get(0).getSchema();
        // 使用DefaultFeatureCollection来存储合并后的数据
        DefaultFeatureCollection mergedCollection = new DefaultFeatureCollection(null, schema);
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(schema);
        // 合并所有FeatureCollection中的数据
        for (SimpleFeatureCollection featureCollection : featureCollections) {
            try (SimpleFeatureIterator iterator = featureCollection.features()) {
                while (iterator.hasNext()) {
                    SimpleFeature feature = iterator.next();
                    featureBuilder.addAll(feature.getAttributes());
                    mergedCollection.add(featureBuilder.buildFeature(null));
                }
            }
        }
        File dir = new File(outputFile);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        outputFile = outputFile + "/result.shp";
        // 准备ShapefileDataStoreFactory所需的参数
        File newFile = new File(outputFile);

        Map<String, Serializable> params = new HashMap<>();
        params.put("url", newFile.toURI().toURL());
        params.put("create spatial index", Boolean.TRUE); // 可选:创建空间索引

        // 创建新的Shapefile数据存储
        ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
        ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
        newDataStore.createSchema(schema);

        Transaction transaction = new DefaultTransaction("create");
        SimpleFeatureSource featureSource = newDataStore.getFeatureSource(newDataStore.getTypeNames()[0]);
        if (featureSource instanceof SimpleFeatureStore) {
            SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
            featureStore.setTransaction(transaction);
            featureStore.addFeatures(mergedCollection);
            transaction.commit();
            transaction.close();
        } else {
            System.out.println("无法写入: " + outputFile);
        }
        newDataStore.dispose();
    }
}

读取矢量信息中的属性

    public static List<Map<String, Object>> shpDataInfo(File file) throws IOException {
        List<Map<String, Object>> featuresList = new ArrayList<>();
        // 创建FileDataStore并获取FeatureSource
        ShapefileDataStore store = (ShapefileDataStore) FileDataStoreFinder.getDataStore(file);
        store.setCharset(Charset.forName("UTF-8")); // 设置字符编码
        SimpleFeatureSource featureSource = store.getFeatureSource();
        store.dispose();
        // 获取Shapefile的FeatureType
        SimpleFeatureType schema = featureSource.getSchema();
        // 遍历每个要素并读取其属性
        try (FeatureIterator<SimpleFeature> features = featureSource.getFeatures().features()) {
            while (features.hasNext()) {
                HashMap map = new HashMap();
                SimpleFeature feature = features.next();
                for (AttributeDescriptor attr : schema.getAttributeDescriptors()) {
                    String attrName = attr.getName().toString();
                    Object attrValue = feature.getAttribute(attrName);
                    map.put(attrName, attrValue);
                }
                featuresList.add(map);
            }
            return featuresList;
        }
    }

对应需要使用的maven库

<!--GeoServer-->
        <dependency>
            <groupId>it.geosolutions</groupId>
            <artifactId>geoserver-manager</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>23-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>23-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>23-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.25</version>
        </dependency>

至此很多路线就打通了
还没写Pgsql管理里面的shp数据,以后再写了


总结

后面会出一下cesium加载模型并变色的教程的。

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

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

相关文章

基于Qlearning强化学习的二阶弹簧动力学模型PID控制matlab性能仿真

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1 传统PID控制器 2.2 Q-Learning强化学习原理 2.3 Q-Learning与PID控制器的融合架构 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2024B仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&a…

【AS32X601驱动系列教程】SMU_系统时钟详解

在现代嵌入式系统中&#xff0c;时钟与复位管理是确保系统稳定运行的关键。我们的SMU&#xff08;系统管理单元&#xff09;模块专注于此核心任务&#xff0c;通过精准的时钟配置和复位控制&#xff0c;为整个系统提供可靠的时序保障。 SMU模块的主要功能是完成时钟和复位的管…

09 接口自动化-用例管理框架pytest之allure报告定制以及数据驱动

文章目录 一、企业级的Allure报告的定制左边的定制&#xff1a;右边的定制&#xff1a;1.用例的严重程度/优先级2.用例描述3.测试用例连接的定制4.测试用例步骤的定制5.附件的定制 二、企业中真实的定制有哪些&#xff1f;三、allure报告如何在本地访问四、allure中的数据驱动装…

React笔记-Ant Design X样本间对接智谱AI

目标 后端对接是智谱AI。 过程 先把Ant Design X样本间搭建好&#xff0c;通过此篇博文获得智谱AI的URL等 智谱AI开放平台 看下此篇博文的“使用API接入” 通义千问 - Ant Design X 将样本间代码的&#xff1a; const [agent] useXAgent({request: async ({ message }, { …

网络安全-等级保护(等保) 3-2 GB/T 28449-2019《信息安全技术 网络安全等级保护测评过程指南》-2018-12-28发布【现行】

################################################################################ GB/T 28448-2019 《信息安全技术 网络安全等级保护测评要求》规定了1~4及的测评要求以及对应级别云大物移工的测评扩展要求&#xff0c;与GB/T 22239-2019 《信息安全技术 网络安全等级保护…

【Bug】--node命令加载失败

环境&#xff1a;本地已经安装好了nodejs&#xff0c;并且已经加入了环境变量path 报错&#xff1a; (解释器) PS D:\桌面文件\pythonProject\vue-fastapi-admin\web> npm i -g pnpm npm : 无法加载文件 D:\桌面文件\node-v22.14.0-win-x64\node-v22.14.0-win-x64\npm.p…

Java 大视界 -- 基于 Java 的大数据分布式存储在视频会议系统海量视频数据存储与回放中的应用(263)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

ROS云课三分钟-3D性能测试supertuxkart和游戏推荐等-国际象棋

ROS云课三分钟-破壁篇GCompris-一小部分支持Edu应用列表-2025-CSDN博客 很多时候&#xff0c;有一种思维定势&#xff0c;将人锁住&#xff0c;人口就是囚。 口人囚~口加人等于囚-CSDN博客 如果突破&#xff0c;跳出问题&#xff0c;再看问题。 这门课程&#xff0c;或者这个平…

汽车零部件行业PLM案例:得瑞客汽车(Dereik) 部署国产PLM

2024年&#xff0c;昆山得瑞客汽车零部件有限公司&#xff08;以下简称“得瑞客汽车”&#xff09;签约智橙云PLM&#xff08;智橙PLM&#xff09;&#xff0c;近日&#xff0c;双方启动了PLM项目评估会&#xff0c;商讨在汽车零部件行业研发数字化转型领域进行更深层的合作。 …

Web攻防-SQL注入数据格式参数类型JSONXML编码加密符号闭合

知识点&#xff1a; 1、Web攻防-SQL注入-参数类型&参数格式 2、Web攻防-SQL注入-XML&JSON&BASE64等 3、Web攻防-SQL注入-数字字符搜索等符号绕过 案例说明&#xff1a; 在应用中&#xff0c;存在参数值为数字&#xff0c;字符时&#xff0c;符号的介入&#xff0c…

医疗AI项目文档编写核心要素硬核解析:从技术落地到合规实践

一、引言&#xff1a;医疗AI项目文档的核心价值 1.1 行业演进与文档范式变革 全球医疗AI产业正经历从技术验证&#xff08;2021-2025&#xff09;向临床落地&#xff08;2026-2030&#xff09;的关键转型期。但是目前医疗AI正在逐步陷入"技术繁荣-应用滞后"的悖论&…

voc怎么转yolo,如何分割数据集为验证集,怎样检测CUDA可用性 并使用yolov8训练安全帽数据集且构建基于yolov8深度学习的安全帽检测系统

voc怎么转yolo&#xff0c;如何分割数据集为验证集&#xff0c;怎样检测CUDA可用性 安全帽数据集&#xff0c;5000张图片和对应的xml标签&#xff0c; 五千个yolo标签&#xff0c;到手即可训练。另外附四个常用小脚本&#xff0c;非常实用voc转yolo代码.py 分割数据集为验证集…

vllm server返回404的一种可能得解决方案

我的 server 启动指令 CUDA_VISIBLE_DEVICES0,1,2,3,4,5,6,7 PYTHONPATH${PYTHONPATH}:/root/experiments/vllm vllm serve ./models/DeepSeek-V3-awq --tensor-parallel-size 8 --trust-remote-code --disable-log-requests --load-format dummy --port 8040 client 端访访…

kafka之操作示例

一、常用shell命令 #1、创建topic bin/kafka-topics.sh --create --zookeeper localhost:2181 --replications 1 --topic test#2、查看创建的topic bin/kafka-topics.sh --list --zookeeper localhost:2181#3、生产者发布消息命令 &#xff08;执行完此命令后在控制台输入要发…

车载网关策略 --- 车载网关通信故障处理机制深度解析

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

三天掌握PyTorch精髓:从感知机到ResNet的快速进阶方法论

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 一、分析式AI基础与深度学习核心概念 1.1 深度学习三要素 数学基础&#xff1a; f(x;W,b)σ(Wxb)(单层感知机) 1.2 PyTorch核心组件 张量操作示例…

分布式缓存:三万字详解Redis

文章目录 缓存全景图PreRedis 整体认知框架一、Redis 简介二、核心特性三、性能模型四、持久化详解五、复制与高可用六、集群与分片方案 Redis 核心数据类型概述1. String2. List3. Set4. Sorted Set&#xff08;有序集合&#xff09;5. Hash6. Bitmap7. Geo8. HyperLogLog Red…

BiLSTM与Transformer:位置编码的隐式vs显式之争

BiLSTM 与使用位置编码的LLM(如Transformer)的核心区别 一、架构原理对比 维度BiLSTM带位置编码的LLM(如Transformer)基础单元LSTM单元(记忆细胞、门控机制)自注意力机制(Self-Attention)信息传递双向链式传播(前向+后向LSTM)并行多头注意力,全局上下文关联位置信息…

html5视频播放器和微信小程序如何实现视频的自动播放功能

在HTML5中实现视频自动播放需设置autoplay和muted属性&#xff08;浏览器策略要求静音才能自动播放&#xff09;&#xff0c;并可添加loop循环播放、playsinline同层播放等优化属性。微信小程序通过<video>组件的autoplay属性实现自动播放&#xff0c;同时支持全屏按钮、…

关于vue结合elementUI输入框回车刷新问题

问题 vue2项目结合elementUI&#xff0c;使用el-form表单时&#xff0c;第一次打开浏览器url辞职&#xff0c;并且是第一次打开带有这个表单的页面时&#xff0c;输入框输入内容&#xff0c;回车后会意外触发页面自动刷新。 原因 当前 el-form 表单只有一个输入框&#xff0…