Java项目实战记录:雷达数据渲染

目录

  • Java项目实战记录:雷达数据渲染
    • 业务背景
    • 代码逻辑
      • 数据结构
      • 颜色渲染
      • MapContent加载数据并输出截图
    • 完整代码
      • GenerateMapImage地图渲染工具
      • 测试代码
    • 渲染效果

Java项目实战记录:雷达数据渲染

业务背景

我之前已经成功使用Java语言解析了C++处理的雷达数据文件,并提取了其中的经纬度点数据。这些文件中的点数据量相当庞大,每个雷达产品文件通常包含超过20万个数据点,有时甚至更多。

目前面临着如何在前端展示这20万个点数据的挑战。有两种可行的解决方案:一种是直接将所有点数据传输到前端进行渲染;另一种则是在后端将点数据渲染成PNG图片,然后再将图片传输到前端展示。经过考虑,决定采用第二种方案,即在后端进行数据的渲染处理。这样不仅可以有效减轻前端的负担,提高数据处理和展示的效率,而且还可以通过优化渲染过程来提高整体的展示质量。

代码逻辑

这里,选用了GeoTools这个强大的开源Java库来执行雷达数据的渲染任务。GeoTools是专为地理空间数据处理设计的工具集,它提供了丰富的API来支持地理数据的读取、查询、分析和展示。利用GeoTools,能够高效地将雷达扫描得到的点数据转换为图像,并以PNG格式保存。

数据结构

雷达数据结构如下所示:

import lombok.Data;

/**
 * 雷达点数据信息
 */
@Data
public class LonLatData {
    private float lon; // 经度
    private float lat;  // 纬度
    private double val;     // 回拨强度 (等于value/100)
}

image-20240316095554008

颜色渲染

根据回拨强度需要渲染不同颜色,定义一个Style样式,具体分类如下所示:

   /* * 根据数值创建基于值的点样式。
     *
     * @return 样式对象,根据不同的值范围应用不同的颜色。
     */
    public static Style createValueBasedPointStyle() {
        // 创建一个黑色描边,宽度为1。
        Stroke stroke = styleFactory.createStroke(filterFactory.literal(Color.BLACK), filterFactory.literal(1));
        FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle();

        // 定义值的范围及其对应的颜色(十六进制表示)。
        Object[][] valueRanges = {
                {-5, Double.NEGATIVE_INFINITY, "#00acb8"},
                {0, -5, "#c1c0ac"},
                {10, 0, "#7a71fe"},
                {15, 10, "#1e26e3"},
                {20, 15, "#a6fcbb"},
                {25, 20, "#00ea15"},
                {30, 25, "#10932d"},
                {35, 30, "#fcf477"},
                {40, 35, "#c9c815"},
                {45, 40, "#8c8c12"},
                {50, 45, "#feadc0"},
                {55, 50, "#ff6370"},
                {60, 55, "#ee0244"},
                {65, 60, "#d48eff"},
                {Double.POSITIVE_INFINITY, 65, "#ab23ff"}
        };

        // 遍历每个值范围,为每个范围创建一个规则并添加到FeatureTypeStyle。
        for (Object[] range : valueRanges) {
            fts.rules().add(createRuleForRange(Double.parseDouble(range[1].toString()), Double.parseDouble(range[0].toString()), range[2].toString()));
        }

        // 创建样式并添加FeatureTypeStyle。
        Style style = styleFactory.createStyle();
        style.featureTypeStyles().add(fts);
        return style;
    }

image-20240316101134737

MapContent加载数据并输出截图

首先创建了一个MapContent对象,用它作为整个地图的内容载体。接着,创建了一个包含所有雷达数据点的图层,并为这些点指定了样式,这样做旨在通过视觉上的区分,提高数据的可读性。然后,将这个图层添加到MapContent中,最后使用GeoTools的功能,将这些内容渲染成一张清晰展示雷达数据的PNG图片。

    /**
     * 根据坐标和值创建地图图像。
     *
     * @param coordinates 坐标对象列表,每个对象包含坐标点和与之相关联的值。
     * @param outputPath  图像输出路径,指定生成的地图图像保存的位置。
     * @throws Exception 抛出异常,处理文件操作或渲染过程中可能出现的错误。
     */
    public static void createMapImageVal(ArrayList<CoordinatePojo> coordinates, String outputPath) throws Exception {
        // 步骤1: 定义SimpleFeatureType
        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("Point");
        typeBuilder.setCRS(DefaultGeographicCRS.WGS84); // 坐标参考系统
        typeBuilder.add("location", Point.class); // 添加位置字段
        typeBuilder.add("value", Double.class); // 添加值字段
        SimpleFeatureType TYPE = typeBuilder.buildFeatureType(); // 构建特征类型

        // 步骤2: 创建SimpleFeatureCollection
        DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);

        // 为每个坐标点创建特征并添加到集合中
        for (CoordinatePojo data : coordinates) {
            Point point = geometryFactory.createPoint(data.getCoordinate()); // 根据坐标创建点
            // 根据点的值创建SimpleFeature
            SimpleFeature feature = SimpleFeatureBuilder.build(TYPE, new Object[]{point, data.getValue()}, null);
            featureCollection.add(feature); // 将特征添加到集合
        }

        // 创建基于值的点样式
        Style style = createValueBasedPointStyle(); // 假设这是一个自定义方法创建基于值的样式

        // 步骤3: 定义样式
        // 这里我们使用了自定义的创建样式方法,而不是SLD.createPointStyle

        // 步骤4: 渲染图像
        MapContent mapContent = new MapContent();
        mapContent.setTitle("Sample Map"); // 设置地图标题
        Layer layer = new FeatureLayer(featureCollection, style); // 创建图层
        mapContent.addLayer(layer); // 将图层添加到地图内容

        GTRenderer renderer = new StreamingRenderer();
        renderer.setMapContent(mapContent); // 设置地图内容

        Rectangle imageBounds = null;
        ReferencedEnvelope mapBounds = null;
        try {
            mapBounds = mapContent.getMaxBounds(); // 获取最大边界
            double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0); // 计算高宽比
            imageBounds = new Rectangle(0, 0, 800, (int) Math.round(800 * heightToWidth)); // 设置图像边界
        } catch (Exception e) {
            // 处理可能的异常
        }

        BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gr = image.createGraphics();
        gr.setPaint(Color.WHITE);
        gr.fill(imageBounds); // 填充背景色

        renderer.paint(gr, imageBounds, mapBounds); // 渲染图像

        File file = new File(outputPath); // 创建文件
        ImageIO.write(image, "png", file); // 写入图像文件

        gr.dispose(); // 释放资源
        mapContent.dispose(); // 释放地图内容
    }

完整代码

GenerateMapImage地图渲染工具

import com.zykj.radar_server.datahandle.RadarDataParser;
import com.zykj.radar_server.datahandle.pojo.LonLatData;
import com.zykj.radar_server.entity.pojo.CoordinatePojo;
import com.zykj.radar_server.entity.pojo.RadarDataPojo;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.renderer.GTRenderer;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.SLD;
import org.geotools.styling.Stroke;
import org.geotools.styling.Style;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.geotools.styling.*;
import org.opengis.filter.FilterFactory2;

public class GenerateMapImage {
    /**
     * 根据坐标和值创建地图图像。
     *
     * @param coordinates 坐标对象列表,每个对象包含坐标点和与之相关联的值。
     * @param outputPath  图像输出路径,指定生成的地图图像保存的位置。
     * @throws Exception 抛出异常,处理文件操作或渲染过程中可能出现的错误。
     */
    public static void createMapImageVal(ArrayList<CoordinatePojo> coordinates, String outputPath) throws Exception {
        // 步骤1: 定义SimpleFeatureType
        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("Point");
        typeBuilder.setCRS(DefaultGeographicCRS.WGS84); // 坐标参考系统
        typeBuilder.add("location", Point.class); // 添加位置字段
        typeBuilder.add("value", Double.class); // 添加值字段
        SimpleFeatureType TYPE = typeBuilder.buildFeatureType(); // 构建特征类型

        // 步骤2: 创建SimpleFeatureCollection
        DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);

        // 为每个坐标点创建特征并添加到集合中
        for (CoordinatePojo data : coordinates) {
            Point point = geometryFactory.createPoint(data.getCoordinate()); // 根据坐标创建点
            // 根据点的值创建SimpleFeature
            SimpleFeature feature = SimpleFeatureBuilder.build(TYPE, new Object[]{point, data.getValue()}, null);
            featureCollection.add(feature); // 将特征添加到集合
        }

        // 创建基于值的点样式
        Style style = createValueBasedPointStyle(); // 假设这是一个自定义方法创建基于值的样式

        // 步骤3: 定义样式
        // 这里我们使用了自定义的创建样式方法,而不是SLD.createPointStyle

        // 步骤4: 渲染图像
        MapContent mapContent = new MapContent();
        mapContent.setTitle("Sample Map"); // 设置地图标题
        Layer layer = new FeatureLayer(featureCollection, style); // 创建图层
        mapContent.addLayer(layer); // 将图层添加到地图内容

        GTRenderer renderer = new StreamingRenderer();
        renderer.setMapContent(mapContent); // 设置地图内容

        Rectangle imageBounds = null;
        ReferencedEnvelope mapBounds = null;
        try {
            mapBounds = mapContent.getMaxBounds(); // 获取最大边界
            double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0); // 计算高宽比
            imageBounds = new Rectangle(0, 0, 800, (int) Math.round(800 * heightToWidth)); // 设置图像边界
        } catch (Exception e) {
            // 处理可能的异常
        }

        BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gr = image.createGraphics();
        gr.setPaint(Color.WHITE);
        gr.fill(imageBounds); // 填充背景色

        renderer.paint(gr, imageBounds, mapBounds); // 渲染图像

        File file = new File(outputPath); // 创建文件
        ImageIO.write(image, "png", file); // 写入图像文件

        gr.dispose(); // 释放资源
        mapContent.dispose(); // 释放地图内容
    }


    // StyleFactory 用于创建地图样式元素,例如图层的边框、填充等。
    private static final StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory();
    // FilterFactory2 用于创建过滤条件,例如,在样式规则中选择符合特定条件的要素。
    private static final FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2();

    /**
     * 根据数值创建基于值的点样式。
     *
     * @return 样式对象,根据不同的值范围应用不同的颜色。
     */
    public static Style createValueBasedPointStyle() {
        // 创建一个黑色描边,宽度为1。
        Stroke stroke = styleFactory.createStroke(filterFactory.literal(Color.BLACK), filterFactory.literal(1));
        FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle();

        // 定义值的范围及其对应的颜色(十六进制表示)。
        Object[][] valueRanges = {
                {-5, Double.NEGATIVE_INFINITY, "#00acb8"},
                {0, -5, "#c1c0ac"},
                {10, 0, "#7a71fe"},
                {15, 10, "#1e26e3"},
                {20, 15, "#a6fcbb"},
                {25, 20, "#00ea15"},
                {30, 25, "#10932d"},
                {35, 30, "#fcf477"},
                {40, 35, "#c9c815"},
                {45, 40, "#8c8c12"},
                {50, 45, "#feadc0"},
                {55, 50, "#ff6370"},
                {60, 55, "#ee0244"},
                {65, 60, "#d48eff"},
                {Double.POSITIVE_INFINITY, 65, "#ab23ff"}
        };

        // 遍历每个值范围,为每个范围创建一个规则并添加到FeatureTypeStyle。
        for (Object[] range : valueRanges) {
            fts.rules().add(createRuleForRange(Double.parseDouble(range[1].toString()), Double.parseDouble(range[0].toString()), range[2].toString()));
        }

        // 创建样式并添加FeatureTypeStyle。
        Style style = styleFactory.createStyle();
        style.featureTypeStyles().add(fts);
        return style;
    }

    /**
     * 根据给定的值范围和颜色创建一个规则。
     *
     * @param min 范围的最小值。
     * @param max 范围的最大值。
     * @param hexColor 颜色的十六进制表示。
     * @return 样式规则,包含一个基于值范围的符号化表示。
     */
    public static Rule createRuleForRange(double min, Object max, String hexColor) {
        // 根据十六进制颜色创建填充,并设置不透明度为1.0。
        Fill fill = styleFactory.createFill(filterFactory.literal(hexToColor(hexColor)), filterFactory.literal(1.0));

        // 获取默认的圆形标记,并设置填充和描边。
        Mark mark = styleFactory.getCircleMark();
        mark.setFill(fill);
        mark.setStroke(null); // 不使用描边。

        // 创建图形对象,清除默认的图形符号,添加自定义的标记。
        Graphic graphic = styleFactory.createDefaultGraphic();
        graphic.graphicalSymbols().clear();
        graphic.graphicalSymbols().add(mark);
        graphic.setSize(filterFactory.literal(4)); // 设置图形大小。

        // 创建点符号器,应用上面的图形。
        PointSymbolizer symbolizer = styleFactory.createPointSymbolizer(graphic, null);

        // 创建规则,设置过滤条件为值在指定范围内。
        Rule rule = styleFactory.createRule();
        rule.symbolizers().add(symbolizer);
        rule.setFilter(
                filterFactory.between(
                        filterFactory.property("value"),
                        filterFactory.literal(min),
                        filterFactory.literal(max)
                )
        );

        return rule;
    }

    /**
     * 将十六进制颜色字符串转换为Color对象。
     *
     * @param hex 十六进制颜色字符串(例如,"#ff0000"表示红色)。
     * @return 转换后的Color对象。
     */
    public static Color hexToColor(String hex) {
        // 将十六进制字符串转换为整数,并创建颜色对象。
        // 这里没有添加前缀"FF",因为Color类的构造函数默认处理不透明颜色。
        return new Color(
                Integer.parseInt(hex.substring(1), 16)
        );
    }

}

测试代码

测试数据自行准备,如何解析雷达数据请看我上一篇博客。

package com.zykj.radar_server.data;

import com.zykj.radar_server.datahandle.GenerateMapImage;
import com.zykj.radar_server.datahandle.RadarDataParser;
import com.zykj.radar_server.datahandle.pojo.LonLatData;
import com.zykj.radar_server.entity.pojo.CoordinatePojo;
import com.zykj.radar_server.entity.pojo.RadarDataPojo;

import org.junit.jupiter.api.Test;
import org.locationtech.jts.geom.Coordinate;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class GenerateMapImageTest {

    @Test
    public void test() throws Exception {

        String filePath = "D:\\雷达测试数据\\数据\\20190305_110801_ZHBJ_Z_VOL_2.50.dat";
        RadarDataPojo radarDataPojo = RadarDataParser.handlePolarProductForPojo(filePath);
        ArrayList<LonLatData> lonLatDataList = radarDataPojo.getLonLatDataList();
        System.out.println(lonLatDataList.size());

        ArrayList<CoordinatePojo> coordinates = new ArrayList<>();

        for (int i = 0; i < lonLatDataList.size(); i++) {
            CoordinatePojo coordinatePojo = new CoordinatePojo();
            coordinatePojo.setCoordinate(new Coordinate(lonLatDataList.get(i).getLon(), lonLatDataList.get(i).getLat()));
            double val = lonLatDataList.get(i).getVal();
            coordinatePojo.setValue(val);
            coordinates.add(coordinatePojo);
        }

        // 指定输出图片路径
        String outputPath = "D:\\temp\\layers\\jiangsu_map_val4.png";
        GenerateMapImage.createMapImageVal(coordinates, outputPath);
        System.out.println("地图图片已生成: " + outputPath);
    }

}

渲染效果

雷达数据渲染效果如下所示,颜色越深回波强度越大:

image-20240316095823124

渲染点的大小可自行调节。

image-20240316094446348

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

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

相关文章

Linux编程4.8 网络编程-建立连接

1、服务器端 #include <sys/types.h> #include <sys/socket.h>int listen(int sockfd, int backlog);返回&#xff1a;成功返回0&#xff0c;出错返回-1。参数&#xff1a;sockfd:套接字的文件描述符backlog:定义了sockfd的挂起连接队列可能增长的最大长度。…

鸿蒙4.0ArkUI快速入门(一)应用模型

ArkUI篇 应用模型Stage模型FA模型模型对比 应用模型 应用模型是HarmonyOS为开发者提供的应用程序所需能力的抽象提炼&#xff0c;它提供了应用程序必备的组件和运行机制。 HarmonyOS先后提供了两种应用模型&#xff1a; FA&#xff08;Feature Ability&#xff09;模型&…

Vue多文件学习项目综合案例——小兔鲜,黑马vue教程

文章目录 一、项目截图二、主要知识点三、Main.js四、App.vue五、componentsXtxBanner.vueXtxFooter.vueXtxHeaderNav.vueXtxHotBrand.vueXtxNewGoods.vueXtxShortCut.vueXtxTopic.vue 六、stylesbase.csscommon.css 一、项目截图 二、主要知识点 把静态页面拆分成一个个vue组…

Axure软件安装汉化教程

Axure软件安装汉化教程 一、准备教程 下载Axure的软件&#xff0c;并解压打开 二、安装过程 双击Axure软件的运行程序&#xff0c;修改安装程序的路径&#xff0c;默认下一步即可。 三、软件汉化 打开Axure的软件安装路径&#xff0c;将汉化包复制粘贴进入到Axure RP 9安装…

Web入门

一Spring简单介绍&#xff1a; Spring Boot 是基于Spring的但是&#xff0c;Spring更为简单高效。 1.2Spring Boot快速入门&#xff1a; 二HTTP协议&#xff1a; 2.1HTTP协议概述 2.2请求协议 <!DOCTYPE html> <html lang"en"> <head><meta ch…

Linux部署DockerUI结合内网穿透实现远程管理本地Docker容器

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

文献速递:深度学习乳腺癌诊断---使用深度学习改善乳腺癌诊断的MRI技术

Title 题目 Improving breast cancer diagnostics with deep learning for MRI 使用深度学习改善乳腺癌诊断的MRI技术 01 文献速递介绍 乳腺磁共振成像&#xff08;MRI&#xff09;是一种高度敏感的检测乳腺癌的方式&#xff0c;报道的敏感性超过80%。传统上&#xff0c;其…

第六届国际大数据工程大会(BDE 2024)即将召开!

2024年第六届国际大数据工程大会(BDE 2024)将于2024年7月24-26日在中国西宁举行。本次会议由青海民族大学和中国矿业大学联合主办。BDE 2024旨在为大数据工程国际等领域的全球学术界、产业界和研究开发组织的研究人员提供一个交流平台&#xff0c;欢迎大数据领域的专家学者踊跃…

设计模式在业务中的实践

一、前言 随着美团外卖业务的不断迭代与发展&#xff0c;外卖用户数量也在高速地增长。在这个过程中&#xff0c;外卖营销发挥了“中流砥柱”的作用&#xff0c;因为用户的快速增长离不开高效的营销策略。而由于市场环境和业务环境的多变&#xff0c;营销策略往往是复杂多变的…

小白向-使用git实现不同服务器改动的同步

背景 深度学习项目&#xff0c;已有可运行的backbone&#xff0c;已将此项目在github建库。 需要使用不同分支进行不同改动的测试&#xff1b;有两台服务器可供程序运行&#xff1b; 项目需求 以github云端仓库为媒介&#xff0c;实现不同服务器改动无痛关联。维护项目代码…

Docker的简介及安装

Docker 是什么 Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机”。诞生于2013年&#xff0c;最 初的发起者是dotCloud公司&#xff0c;后来改名为Docker Inc&#xff0c;专注于Docker 相关技术和产品的开发。Docker 项目目前已经加入了Linux基金会…

【目标检测】YOLOv2 网络结构(darknet-19 作为 backbone)

上一篇文章主要是写了一些 YOLOv1 的原版网络结构&#xff0c;这篇文章一样&#xff0c;目标是还原论文中原版的 YOLOv2 的网络结构&#xff0c;而不是后续各种魔改的版本。 YOLOv2 和 YOLOv1 不一样&#xff0c;开始使用 Darknet-19 来作为 backbone 了。论文中给出了 Darkne…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:FolderStack)

FolderStack继承于Stack(层叠布局)控件&#xff0c;新增了折叠屏悬停能力&#xff0c;通过识别upperItems自动避让折叠屏折痕区后移到上半屏 说明&#xff1a; 该组件从API Version 11开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件…

数据在内存的存储

整数在内存中的存储 我们来回顾一下&#xff0c;整数在计算机是以补码的形式进行存储的&#xff0c;整数分为正整数和负整数&#xff0c;正整数的原码、反码和补码是一样的&#xff0c;负整数的原码、反码和补码略有不同&#xff08;反码是原码除符号位&#xff0c;其他位按位取…

【九】【算法分析与设计】双指针(3)

15. 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元…

SpringBoot(数据库操作 + druid监控功能)

文章目录 1.JDBC HikariDataSource&#xff08;SpringBoot2默认数据源&#xff09;1.数据库表设计2.引入依赖 pom.xml3.配置数据源参数 application.yml4.编写一个bean&#xff0c;映射表5.编写测试类来完成测试1.引入依赖 pom.xml2.使用JdbcTemplate进行测试3.成功&#xff0…

STM32信息安全 1.2 课程架构介绍:芯片生命周期管理与安全调试

STM32信息安全 1.2 课程架构介绍&#xff1a;STM32H5 芯片生命周期管理与安全调试 下面开始学习课程的第二节&#xff0c;简单介绍下STM32H5芯片的生命周期和安全调试&#xff0c;具体课程大家可以观看STM32官方录制的课程&#xff0c;链接&#xff1a;1.2. 课程架构介绍&…

01背包问题详解

01背包问题是动态规划问题的子背包问题&#xff0c;算是蓝桥杯以及CSP较为常考的一种题型。 这种问题是有一个板子的&#xff0c;非常简单 #include <bits/stdc.h> using namespace std;int k[200],v[200],dp[130][130]; int main() {int t,m;cin>>t>>m;fo…

【鸿蒙HarmonyOS开发笔记】常用组件介绍篇 —— Toggle切换按钮组件

概述 Toggle为切换按钮组件&#xff0c;一般用于两种状态之间的切换&#xff0c;例如下图中的蓝牙开关。 参数 Toggle组件的参数定义如下 Toggle(options: { type: ToggleType, isOn?: boolean })● type type属性用于设置Toggle组件的类型&#xff0c;可通过ToggleType枚举…

【MIT 6.S081】2020, 实验记录(9),Lab: file system

目录 Task 1&#xff1a;Large filesTask 2&#xff1a;Symbolic links2.1 增加一个系统调用 symlink2.2 新增文件类型2.3 新增 NOFOLLOW 标志位2.4 实现 sys_symlink 系统调用2.5 修改 sys_open 函数2.6 测试 Task 1&#xff1a;Large files 现在的 xv6 系统中&#xff0c;一…