使用java对栅格数据的处理,对栅格文件进行导入导出

news2024/9/23 1:36:22

需求背景:

对栅格文件进行导入导出(使用代码的方式,非命令方式);

当然也可以使用代码和GDAL的方式进行,但是GDAL配置部署不便捷,故选用GeoTools方式来实现。

ps:若是使用命令方式,首先打开PostgreSQL的安装目录【\PostgreSQL\14\bin】,然后使用如下命令即可实现把栅格文件导入到数据库中:

# 指定切片大小
raster2pgsql -s 4326 -I -C -M D:\model\tif\TDM1_DEM__30_N34E108_DEM.tif -F -t 256x256 sdx.tdm1_dem | psql -h 192.168.31.200 -p 5432 -U postgres -d testShp

# 4326 是ESP
# 256*256 是切片大小
# sdx.tdm1_dem 是哪个模式下的哪个表,也可以是public.tdm1_dem
# -h 192.168.31.200 是数据库地址
# -p 5432 端口
# -U postgres 用户名
# -d testShp 数据库名


# 自动切片大小
raster2pgsql -s 4326 -d -k -N -e -I -C -M "D:\model\tif\TDM1_DEM__30_N34E108_DEM.tif" -F -t auto public.raster_data | psql -h 192.168.31.200 -p 5432 -d testdb -U postgres

 若是使用代码导入的思路:

  • 配置好前置条件
  • 读取栅格数据
  • 连接到数据库
  • 创建表
  • 将数据插入到数据库中

实现:

1、配置好前置条件

  • 确保你的PostgreSQL数据库已安装并启用了PostGIS扩展
-- 安装PostGIS扩展
CREATE EXTENSION postgis;

-- 安装PostGIS的栅格支持
CREATE EXTENSION postgis_raster;
  • 确认PostGIS版本

确保你使用的是支持栅格数据的PostGIS版本。你可以使用以下命令来检查PostGIS版本:

SELECT POSTGIS_VERSION();
-- 查看函数
SELECT proname, proargtypes, prosrc
FROM pg_proc
JOIN pg_namespace ON pg_namespace.oid = pg_proc.pronamespace
WHERE proname = 'st_fromgdalraster';

SELECT proname, proargtypes
FROM pg_proc
JOIN pg_namespace ON pg_namespace.oid = pg_proc.pronamespace
WHERE proname LIKE 'st_f%' AND pg_namespace.nspname = 'public';

-- 查看扩展
SELECT postgis_full_version();

确保返回的版本信息显示PostGIS包含栅格支持

2、读取栅格数据、保存数据到数据库

添加依赖

        <gt.version>20.0</gt.version>

        <!-- 添加GeoTools依赖 -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-opengis</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-api</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-data</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-jdbc</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-metadata</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-render</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-coverage</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <!-- 如果使用的 GeoTools 功能需要额外的依赖,如坐标转换,可能还需要添加这个 -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.15</version>
        </dependency>


<!-- 1 栅格相关依赖 -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-image</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-process</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-process-raster</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geotiff</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.geotools/gt-swing -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <!--<dependency>
            <groupId>org.jdal</groupId>
            <artifactId>jdal-core</artifactId>
            <version>2.0.0</version>
        </dependency>
-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-imaging</artifactId>
            <version>1.0-alpha3</version>
        </dependency>

        <!--        <dependency>
                    <groupId>org.geotools</groupId>
                    <artifactId>gt-netcdf</artifactId>
                    <version>20.0</version>
                </dependency>-->

        <!-- https://mvnrepository.com/artifact/edu.ucar/netcdf -->
        <dependency>
            <groupId>edu.ucar</groupId>
            <artifactId>netcdf</artifactId>
            <version>4.3.22</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geometry</artifactId>
            <version>20.0</version>
        </dependency>

        <!-- TwelveMonkeys ImageIO TIFF -->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-tiff</artifactId>
            <version>3.8.0</version>
        </dependency>

        <!-- Maven example for JAI TIFF plugin -->
        <dependency>
            <groupId>javax.media</groupId>
            <artifactId>jai-core</artifactId>
            <version>1.1.3</version>
        </dependency>

        <!--gdal-->
        <dependency>
            <groupId>org.gdal</groupId>
            <artifactId>gdal</artifactId>
            <version>3.9.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/net.postgis/postgis-jdbc -->
        <dependency>
            <groupId>net.postgis</groupId>
            <artifactId>postgis-jdbc</artifactId>
            <version>2024.1.0</version>
        </dependency>



        <!-- 11 栅格相关依赖 -->

实现类 


    public String importRasterData(GridDataDto gridDataDto) throws IOException {
        // 1. 连接数据库,创建模式、表相关内容 实现导入栅格数据的逻辑
        GridData gridData = gridDataDto.getParameter();
        String sourceFilePath = gridData.getSourceFilePath();
        String targetDatasource = gridData.getTargetDatasource();
        String targetDatasetName = gridData.getTargetDatasetName().toLowerCase();
        String importMode = gridData.getImportMode();
        // 解析 PostgreSQL 数据库 连接参数
        Map<String, Object> dataSourceMap = parseDatabaseParameters(targetDatasource);
        log.info("dataSourceMap = " + dataSourceMap);
        // 创建 PostgreSQL/PostGIS 表
        JDBCDataStoreFactory dsf = new PostgisNGDataStoreFactory();
        JDBCDataStore datastore = dsf.createDataStore(dataSourceMap);
        // 如果不存该模式,则创建模式schema 确保 schema 存在
        String schemaName = dataSourceMap.get("schema").toString();
        try (Connection connection = datastore.getDataSource().getConnection()) {
            Statement stmt = connection.createStatement();
            // 创建依赖扩展
            String[] extensions = {"postgis", "postgis_raster"};
            for (String extension : extensions) {
                String createExtensionSql = "CREATE EXTENSION IF NOT EXISTS " + extension;
                stmt.execute(createExtensionSql);
            }
            log.info("Extensions created successfully");

            // 检查 schema 是否存在
            String checkSchemaSql = "SELECT schema_name FROM information_schema.schemata WHERE schema_name = '" + schemaName + "'";
            ResultSet rs = stmt.executeQuery(checkSchemaSql);
            if (!rs.next()) {
                // 如果 schema 不存在,创建 schema
                String createSchemaSql = "CREATE SCHEMA " + schemaName;
                stmt.execute(createSchemaSql);
                log.info("schema created successfully");
            }
            // 确保表存在 根据importMode的值NONE、OVERWRITE、APPEND进行相关操作
            if ("NONE".equals(importMode) || "OVERWRITE".equals(importMode)) {
                // 删除表
                String dropTableSql = "DROP TABLE IF EXISTS " + schemaName + "." + targetDatasetName;
                stmt.execute(dropTableSql);
                // 如果表不存在,创建表
                // String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName + " (rid INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, rast raster, srid text, filename text)";
                // 如果表不存在,创建表
                String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName +
                        " (rid SERIAL PRIMARY KEY, rast raster, srid text, filename text)";
                stmt.execute(createTableSql);
                log.info("Table created successfully");
            } else if ("APPEND".equals(importMode)) {
                // 检查表是否存在,不存在则创建
                String checkTableSql = "SELECT to_regclass('" + schemaName + "." + targetDatasetName + "')";
                rs = stmt.executeQuery(checkTableSql);
                if (!rs.next() || rs.getString(1) == null) {
                    // 如果表不存在,创建表
                    // String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName +" (rid INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, rast raster, srid text)";
                    String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName + " (rid SERIAL PRIMARY KEY, rast raster, srid text)";
                    stmt.execute(createTableSql);
                    log.info("Table created successfully");
                }
            }
        } catch (SQLException e) {
            log.error("Failed to ensure schema exists", e);
            throw new IOException("Failed to ensure schema exists", e);
        }

        // 保存到记录表中
        ServerImportInfo serverImportInfo = new ServerImportInfo();
        BeanUtils.copyProperties(gridData, serverImportInfo);
        Date now = new Date();
        serverImportInfo.setCreateTime(now);
        serverImportInfo.setStartTime(now);
        serverImportInfo.setUpdateTime(now);
        serverImportInfo.setState("RUNNING");
        serverImportInfo.setDataType("栅格-导入");
        serverImportInfoService.save(serverImportInfo);
        // 数据库相关连接和判断完成,下面实现
        // 2. 读取栅格数据
        try {
            File file = new File(gridData.getSourceFilePath());
            GeoTiffReader reader = new GeoTiffReader(file);
            GridCoverage2D coverage = reader.read(null);
            System.out.println("coverage = " + coverage);
            log.info("栅格数据读取完成");
            if (coverage != null) {
                // 获取和打印坐标参考系统信息
                CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem();
                System.out.println("CRS: " + crs);
                // 获取栅格图像
                RenderedImage image = coverage.getRenderedImage();
                System.out.println("image = " + image);
                // 获取栅格的范围(Envelope)
                Envelope2D envelope = coverage.getEnvelope2D();
                System.out.println("Raster bounds: " + envelope.toString());
                System.out.println("Raster read successfully!");
            } else {
                System.err.println("Failed to read raster data.");
            }
            // 3. 导入栅格数据
            Integer saveRaster = storeRasterIntoDatabase(datastore, sourceFilePath, schemaName, targetDatasetName);
            System.out.println("saveRaster = " + saveRaster);
            log.info("栅格数据导入完成");
            // 4. 更新导入状态 判断是否大于0
            if (saveRaster > 0) {
                serverImportInfo.setState("FINISHED");
            } else {
                serverImportInfo.setState("FAILED");
            }
            // 5. 保存导入信息
            saveGridInfo(serverImportInfo);
            log.info("导入信息保存完成");

        } catch (Exception e) {
            log.error("导入栅格数据失败", e);
        } finally {
            // 关闭数据源
            datastore.dispose();
            log.info("数据源已关闭");
        }
        return String.valueOf(serverImportInfo.getId());
    }
public Integer storeRasterIntoDatabase(JDBCDataStore dataSource, String filePath, String schemaName, String targetDatasetName) throws IOException, SQLException, FactoryException {
        File file = new File(filePath);
        GeoTiffReader reader = new GeoTiffReader(file);
        GridCoverage2D coverage = reader.read(null);
        if (coverage == null) {
            throw new IOException("Failed to read raster data.");
        }
        RenderedImage image = coverage.getRenderedImage();
        Envelope2D envelope = coverage.getEnvelope2D();
        CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem();
        int width = image.getWidth();
        int height = image.getHeight();
        double xPixelSize = envelope.getWidth() / width;
        double yPixelSize = envelope.getHeight() / height;
        double upperLeftX = envelope.getMinimum(0);
        double upperLeftY = envelope.getMaximum(1);
        // 获取srid
        int srid = CRS.lookupEpsgCode(crs, true);
        log.info("srid = " + srid);

        log.info("Raster size: " + width + " x " + height);
        log.info("Pixel size: " + xPixelSize + " x " + yPixelSize);
        log.info("Upper-left corner: " + upperLeftX + ", " + upperLeftY);
        String tableName = schemaName + "." + targetDatasetName;
        // Convert GridCoverage2D to image
        File tempFile = File.createTempFile("raster", ".tif");
        GeoTiffWriter writer = null;
        try {
            writer = new GeoTiffWriter(tempFile);
            writer.write(coverage, null);
        } finally {
            if (writer != null) {
                // Dispose of the writer to release resources
                writer.dispose();
            }
        }
        byte[] rasterData = convertCoverageToByteArray(coverage);
        //System.out.println("rasterData1 = " + Arrays.toString(rasterData));
        // 将栅格数据转换为字节数组
        Integer saveraster = 0;
        // Insert into PostGIS
        try (Connection connection = dataSource.getDataSource().getConnection()) {
            // raster ST_FromGDALRaster(bytea gdaldata, integer srid=NULL);
            //String sql = "INSERT INTO " + tableName + " (rast) VALUES (st_fromgdalraster(?::bytea,?))";
            String sql = "INSERT INTO " + tableName + " (rast) VALUES (st_fromgdalraster(?,?))";
            try (PreparedStatement stmt = connection.prepareStatement(sql)) {
                // 将字节数组作为二进制数据插入
                stmt.setBinaryStream(1, new ByteArrayInputStream(rasterData));
                // 设置栅格数据的SRID(可选)
                stmt.setInt(2, srid);
                log.info("stmt = " + stmt);
                stmt.executeUpdate();
                ++saveraster;
            }
            log.info("Inserted {} raster(s) into {}", saveraster, tableName);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            reader.dispose();
            dataSource.dispose();
        }

        return saveraster;
    }
    private byte[] convertCoverageToByteArray(GridCoverage2D coverage) throws IOException {
        // Create a temporary file to store the GeoTIFF
        File tempFile = File.createTempFile("coverage", ".tif");
        tempFile.deleteOnExit();

        GeoTiffWriter writer = null;
        try {
            writer = new GeoTiffWriter(tempFile);
            writer.write(coverage, null);
        } finally {
            if (writer != null) {
                // Dispose of the writer to release resources
                writer.dispose();
            }
        }
        // Read GeoTIFF file into byte array
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            Files.copy(tempFile.toPath(), baos);
            return baos.toByteArray();
        }
    }

这个是整体导入的示例,拓展一下也可以切片导入

既然可以导入栅格,那么反过来也是可以导出栅格数据变成栅格文件的,示例代码如下:

public String exportRasterData(GridDataDto gridDataDto) throws IOException {
        GridData gridData = gridDataDto.getParameter();
        // 导出目标文件的路径信息
        String targetFilePath = gridData.getTargetFilePath();
        // 导出的源数据集
        String sourceDataset = gridData.getSourceDataset();
        // 解析 PostgreSQL 数据库 连接参数
        Map<String, Object> dataSourceMap = parseDatabaseParameters(sourceDataset);
        log.info("Data source map: {}", dataSourceMap);
        // 创建 PostgreSQL/PostGIS 表
        JDBCDataStoreFactory dsf = new PostgisNGDataStoreFactory();
        JDBCDataStore datastore = dsf.createDataStore(dataSourceMap);
        // 如果不存该模式,则给出提示
        String schemaName = dataSourceMap.get("schema").toString();
        String tableName = dataSourceMap.get("dataset").toString();
        try (Connection connection = datastore.getDataSource().getConnection()) {
            Statement stmt = connection.createStatement();
            String checkSchemaSql = "SELECT schema_name FROM information_schema.schemata WHERE schema_name = '" + schemaName + "'";
            ResultSet rs = stmt.executeQuery(checkSchemaSql);
            if (!rs.next()) {
                log.error("schema notexist, create schema: {}", schemaName);
            }
            // 检查表是否存在,不存在则给出提示
            String checkTableSql = "SELECT to_regclass('" + schemaName + "." + tableName + "')";
            rs = stmt.executeQuery(checkTableSql);
            if (!rs.next() || rs.getString(1) == null) {
                log.error("Table notexist, create table: {}", tableName);
            }
            // 把数据库中的栅格数据导出成一个文件
            exportRasterFromDatabaseToImageFile(connection, schemaName, tableName, targetFilePath);

            // 保存到记录表中
            ServerImportInfo serverImportInfo = new ServerImportInfo();
            BeanUtils.copyProperties(gridData, serverImportInfo);
            Date now = new Date();
            serverImportInfo.setCreateTime(now);
            serverImportInfo.setStartTime(now);
            serverImportInfo.setUpdateTime(now);
            serverImportInfo.setState("RUNNING");
            serverImportInfo.setDataType("栅格-导出");
            serverImportInfo.setState("FINISHED");
            serverImportInfoService.save(serverImportInfo);
            log.info("导出信息保存完成");

            return String.valueOf(serverImportInfo.getId());

        } catch (SQLException e) {
            log.error("Failed to ensure schema exists", e);
            throw new IOException("Failed to ensure schema exists", e);
        } finally {
            datastore.dispose();
        }

    }
public void exportRasterFromDatabaseToImageFile(Connection connection, String schemaName, String targetDatasetName, String imagePath) {
        try {
            // Retrieve raster data from the database
            byte[] rasterData = getRasterDataFromDB(connection, schemaName, targetDatasetName);
            // log.info("rasterData = " + Arrays.toString(rasterData));
            log.info("Converting raster data to images...");
            convertRasterDataToImages(rasterData, imagePath);
            log.info("Conversion complete.");
        } catch (SQLException | IOException e) {
            e.printStackTrace();
        }
    }

  private byte[] getRasterDataFromDB(Connection connection, String schemaName, String targetDatasetName) throws SQLException, IOException {
        String tableName = schemaName + "." + targetDatasetName;
        String sql = "SELECT ST_AsGDALRaster(rast, 'GTiff') FROM " + tableName + " LIMIT 1";
        log.info("Executing SQL: " + sql);
        try (PreparedStatement stmt = connection.prepareStatement(sql);
             ResultSet rs = stmt.executeQuery()) {
            if (rs.next()) {
                log.info("Retrieved raster data from database.");
                try (InputStream is = rs.getBinaryStream(1); ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = is.read(buffer)) != -1) {
                        baos.write(buffer, 0, bytesRead);
                    }
                    return baos.toByteArray();
                }
            } else {
                throw new SQLException("No raster data found.");
            }
        }
    }
 private void convertRasterDataToImages(byte[] rasterData, String outTiffPath) throws IOException {
        File tempFile = File.createTempFile("raster", ".tif");
        tempFile.deleteOnExit();
        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
            fos.write(rasterData);
        }
        AbstractGridFormat format = GridFormatFinder.findFormat(tempFile);
        GridCoverage2DReader reader = format.getReader(tempFile, null);
        GridCoverage2D coverage = reader.read(null);
        log.info("Coverage name: {}", coverage.getName());
        writeTiff(coverage, outTiffPath);
    }
 public static void writeTiff(Coverage coverage, String outTiffPath) throws IOException {
        File file = new File(outTiffPath);
        GeoTiffWriter geoTiffWriter = new GeoTiffWriter(file);
        final GeoTiffFormat format = new GeoTiffFormat();
        final GeoTiffWriteParams wp = new GeoTiffWriteParams();
        // 设置写出参数
        wp.setCompressionMode(GeoTiffWriteParams.MODE_DEFAULT);
        wp.setTilingMode(GeoToolsWriteParams.MODE_DEFAULT);
        ParameterValueGroup paramWrite = format.getWriteParameters();
        paramWrite.parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()).setValue(wp);
        geoTiffWriter.write((GridCoverage) coverage, paramWrite.values().toArray(new GeneralParameterValue[4]));
        geoTiffWriter.dispose();
    }

至此!即可实现栅格数据通过代码进行导入导出了!

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

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

相关文章

大模型api谁家更便宜

1 openai 可点此链接查询价格&#xff1a;https://openai.com/api/pricing/ 2 百度 可点此链接查询价格&#xff1a;https://console.bce.baidu.com/qianfan/chargemanage/list 需要注意&#xff0c;百度千帆平台上还提供其他家的模型调用服务&#xff0c; 如llama, yi-34b等…

IDE快速复制文件名

在很多情况下我们需要复制IDE中文件的名称&#xff0c;习惯性的F2却不能重命名 如图操作又比较繁琐 解决方法⭐⭐⭐ 其实直接CtrlC可以复制文件名&#x1f921;&#x1f921;&#x1f921;

7-Zip压缩包如何添加密码,加密后如何取消

压缩包文件大家经常使用&#xff0c;最熟悉的肯定是RAR、ZIP格式压缩文件&#xff0c;但是7z压缩文件格式也很好用&#xff0c;它是三种压缩文件格式中压缩率最大的。想要将文件压缩到最小&#xff0c;使用7z格式可以达到最大化。那么在使用7z压缩格式的时候&#xff0c;我们可…

银河麒麟V10系统软件商店手动更新方法

银河麒麟桌面操作系统V10重新安装之后&#xff0c;有些软件商店未能及时的自动更新&#xff0c;从而软件商店里无法获取最新的软件应用&#xff0c;这个时候就需要我们手动的进行升级更新一下软件商店了&#xff0c;更新之后软件商店里的内容就会增加不少&#xff0c;那么&…

阿尔泰科技案例解析-炼钢厂设备监测解决方案!

案例背景 在一家大型钢铁冶炼厂中&#xff0c;熔炉是生产过程的核心设备&#xff0c;广泛应用于金属冶炼、铸造和加工步骤&#xff0c;如钢铁的冶炼和精炼。为了确保熔炉在最佳状态下运行&#xff0c;并防止潜在的故障或事故&#xff0c;该厂需要对熔炉及厂房内相关设备的多个…

开发模型例题

答案&#xff1a;A 解析&#xff1a;瀑布模型是跟对需求明确的项目 增量模型是将需求分为多个阶段&#xff0c;适合一开始需求不明确的 演化模型适合用户需求不清&#xff0c;需求经常变化的情况 螺旋模型适合庞大&#xff0c;复杂且具有高风险的系统

F12抓包07:Network界面功能详细介绍

课程大纲 ​ 本课介绍F12“网络”&#xff08;Network&#xff09;tab菜单界面的功能区域和使用。 8.1 录制与清空 8.2 过滤与搜索 1、url过滤 2、全局搜索 8.3 保留日志 勾选“保留日志”&#xff1a;刷新界面后请求记录不清空&#xff1b;否则&#xff0c;清空历史请求记录…

西门子博途PLC跑马灯的简单编程方式

新手必学的PLC程序&#xff0c;老电工转型电气工程师必看&#xff01;#自动化##PLC##电工##电气##学习##编程##跑马灯##西门子##外企# 工控人加入PLC工业自动化精英社群 工控人加入PLC工业自动化精英社群

AutoIT:强大的RPA自动化脚本神器,安装到使用的保姆级教程!

作为一个经常需要在Windows上处理各种繁琐任务的“码农”&#xff0c;我对各种自动化工具有着深厚的兴趣。尤其是AutoIT这种工具&#xff0c;让人简直爱不释手。 我有时候需要写一大堆技术文档&#xff0c;里面各种表格、数据&#xff0c;手动操作简直让人头大。那时候&#x…

5款AI头像生成神器,独特头像不是梦!

在各种应用程序和社交媒体平台上&#xff0c;头像几乎无处不在。它不仅仅是个人的标识&#xff0c;更是展现个性和特征的一种方式。随着人工智能技术的不断进步&#xff0c;各种头像生成器应运而生&#xff0c;让我们能够创造出更加独特和个性化的头像。使用这些AI头像生成器非…

How can I register a custom environment in OpenAI‘s gym?

题意&#xff1a;如何在OpenAI的Gym中注册一个自定义环境&#xff1f; 问题背景&#xff1a; I have created a custom environment, as per the OpenAI Gym framework; containing step, reset, action, and reward functions. I aim to run OpenAI baselines on this custom…

tabBar设置底部导航栏

如果应用是一个多 tab 应用&#xff0c;可以通过 tabBar 配置项指定一级导航栏&#xff0c;以及 tab 切换时显示的对应页&#xff0c;简单来说就是像美团外卖下面的导航栏一样可以任意切换 1.首先创建三个页面&#xff0c;在页面里面可以写一些东西或者放一张图片方便区分。 2.…

JavaScript高级进阶(二)

JS弹窗 弹窗与语法 警告窗 window.alert()//用于确保用户可以得到某些信息 确认窗 window.confirm()//用于验证是否接受用户操作 提示窗 window.prompt()//用于提示用户在进入页面前输入某个值 <script> //警告窗 alert(欢迎光临); //提示框 var str prompt(是不是…

秒懂:进程切换——O(1)调度算法

情景理解&#xff1a; 上面这张图展示的就是Linux内核中的调度队列示意图&#xff0c;那么具体是如何进行队列调度的呢&#xff1f; 首先&#xff0c;图中有两个queue[140]&#xff0c;这个就是所谓的队列结构&#xff0c;&#xff08;蓝色和红色扩出来的&#xff09;其中有一…

(Arxiv-2022)eDiff-I:具有一组专家降噪器的文本到图像扩散模型

eDiff-I&#xff1a;具有一组专家降噪器的文本到图像扩散模型 Paper Title&#xff1a;eDiff-I: Text-to-Image Diffusion Models with an Ensemble of Expert Denoisers Paper是NVIDIA 公司发表在arxiv 2022的工作 Paper地址 项目页面地址 图 1. 我们提出的方法 eDiff-I 的示例…

电子连接器接触电阻仿真教程

电子连接器接触电阻是指连接器连接通路中公母端子接点处电阻与公母端子导体的电阻总和。接触电阻是电子连接器的重要电气特性参数,对同款连接器,接触电阻则是衡量其品质优劣的重要指标。接触电阻过大时会导致传输信号在连接器上的能量损耗过大,电压降过大,发热过大等不利于…

【计网】计算机网络基础

当自律变成一种本能的习惯&#xff0c; 你就会享受到它的快乐。 --- 村上春树 --- 初识计算机网络 1 初识协议1.1 协议分层1.2 OSI七层模型1.3 TCP / IP协议 2 初识局域网2.1 什么是局域网2.2 MAC地址2.3 局域网通信 3 简单认识IP地址 1 初识协议 1.1 协议分层 首先&#…

Xilinx SDK入门示例

本文以测试PS端的UART和DDR3&#xff0c;介绍Xilinx SDK的简单用法。 1 创建VIVADO工程 Step1&#xff1a;新建工程 Step2&#xff1a; Step3&#xff1a;选择器件 Step4&#xff1a;在接下来的页面中&#xff0c;点击Finish完成工程的创建 Step5&#xff1a;点击IP INTERGA…

JavaScript 编程精粹:JavaScript 事件处理

JavaScript 编程精粹&#xff1a;JavaScript 事件处理 一 . BOM1.1 Window1.1.1 alert()1.1.2 confirm()1.1.3 setInterval()1.1.4 setTimeout()1.1.5 小案例 - 通过定时器来控制灯的亮暗 1.2 History1.3 Location 二 . DOM2.1 获取 Element 对象2.2 常见 Element 对象的使用 三…

【Qt】实现一个小闹钟

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton>//按钮类 #include <QLineEdit>//行编辑器 #include <QLabel>//标签类 #include <QTextEdit>//输入框 #include <QTimerEvent>//定时器事件类 #inc…