使用SpringBoot将中国地震台网数据保存PostGIS数据库实践

目录

前言

一、数据转换

1、Json转JavaBean

2、JavaBean与数据库字段映射

二、空间数据表设计

1、表结构设计

三、PostGIS数据保存

1、Mapper接口定义

2、Service逻辑层实现

3、数据入库

4、运行实例及结果

总结


前言

        在上一篇博客中基于Java的XxlCrawler网络信息爬取实战-以中国地震台网为例,我们使用Java语言采用XxlCrawer组件进行中国地震台网数据的爬取,相信大家对如何抓取这种接口数据一定有了基本的认识,也掌握了如何基于XxlCrawer来实现自己的信息爬取实战。但是在前面的博客当中,我们仅仅是将信息爬取下来。为了在我们自己的应用系统中来应用这些基础数据,需要我们将爬取的数据进行存储起来。由于地震数据包含了空间位置信息,为方便进行空间分析的实现。这里我们将爬取的中国地震信息存储到PostGIS空间数据库中,为下一步的数据分析和可视化呈现奠定良好的基础。

        本文即紧紧围绕着将信息保存到空间数据库的目标,重点讲解如何实现将中国地震台网爬取的地震信息保存到PostGIS空间数据库中。首先讲解在爬取过程中数据格式和响应数据类型的转换,将网站回传的json数据转成符合Java命名规范的数据。然后介绍台网地震信息表的设计,如何构建空间数据表。再次介绍如何将爬取的数据调用Mybatis-Plus组件实现批量入库。如果您当前也有对地震等地质灾害数据进行分析的需求,不妨看看本博文。

一、数据转换

        在前面的博客中有提到,在中国地震台网中展示接口数据,将请求数据在浏览器中进行查看。可以看到以下的格式:

        通过这个接口可以看到,官方返回的数据中,其所有的字段名都是大写的,如下所示:

AUTO_FLAG: "M"
CATA_ID: "CD20240413222636.00"
CATA_TYPE: ""
EPI_DEPTH: 9
EPI_LAT: "24.05"
EPI_LON: "121.60"
EQ_CATA_TYPE: ""
EQ_TYPE: "M"
IS_DEL: ""
LOCATION_C: "台湾花莲县"
LOCATION_S: ""
LOC_STN: "0"
M: "4.2"
M_MB: "0"
M_MB2: "0"
M_ML: "0"
M_MS: "0"
M_MS7: "0"
NEW_DID: "CD20240413222636"
O_TIME: "2024-04-13 22:26:35"
O_TIME_FRA: "0"
SAVE_TIME: "2024-04-13 22:35:56"
SUM_STN: "0"
SYNC_TIME: "2024-04-13 22:35:56"
id: "46396"

        为了让更好的使用Java语言进行开发,使这些变量名变得更加合适,同时满足Java的编程规范。因此办结来重点讲解怎么将 json返回的数据转成java的合理变量名。

1、Json转JavaBean

        如上所言,在使用XxlCrawler进行信息爬取之后,返回的数据名称不太符合Java的命名规则。那针对这种需求,有没有什么办法来进行调整呢。答案是肯定的,不管是用Gson或者fastJson,这些设计良好的json处理框架其实都包含了Json对象与JavaBean对象的互相转换。当给定格式不符合Java命名规范的属性名,可以通过注解映射的方式修改成符合Java编码规范的变量。由于本实例中采用的是Gson组件,因此给出的示例代码也是基于Gson来实现的,其它的实现组件请自行搜索相关知识,根据官方文档的知识来进行设置。

        在Gson中,主要是采用@SerializedName("AUTO_FLAG")这个注解,注解后面的字段是通过接口返回的数据字段。把这个注解配置到属性中,表示当前属性对应哪个接口的字段。关键代码如下:

package com.yelang.project.extend.earthquake.domain.crawler;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class CeicEarthquake implements Serializable{
	private static final long serialVersionUID = -1212153879708670015L;
	private Long pkId;//主键
	@SerializedName("AUTO_FLAG")
	private String autoFlag;
	@SerializedName("CATA_ID")
	private String cataId;
	@SerializedName("CATA_TYPE")
	private String cataType;
	@SerializedName("EPI_DEPTH")
	private BigDecimal epiDepth = new BigDecimal("0.0");
	@SerializedName("EPI_LAT")
	private String epiLat;//纬度
	@SerializedName("EPI_LON")
	private String epiLon;
	@SerializedName("EQ_CATA_TYPE")
	private String eqCataType;
	@SerializedName("EQ_TYPE")
	private String eqType;
	@SerializedName("IS_DEL")
	private String isDel;
	@SerializedName("LOCATION_C")
	private String locationC;
	@SerializedName("LOCATION_S")
	private String locationS;
	@SerializedName("LOC_STN")
	private String locStn;
	@SerializedName("M")
	private String m;
	@SerializedName("M_MB")
	private String mmb;
	@SerializedName("M_MB2")
	private String mmb2;
	@SerializedName("M_ML")
	private String mml;
	@SerializedName("M_MS")
	private String mms;
	@SerializedName("M_MS7")
	private String mms7;
	@SerializedName("NEW_DID")
	private String newDid;
	@SerializedName("O_TIME")
	private Date oTime;
	@SerializedName("O_TIME_FRA")
	private String oTimeFra;
	@SerializedName("SAVE_TIME")
	private Date saveTime;
	@SerializedName("SUM_STN")
	private String sumStn;
	@SerializedName("SYNC_TIME")
	private Date syncTime;
	@SerializedName("id")
	private String epiId;
}

        通过以上的代码就可以实现将接口返回的参数映射成符合我们需求的JavaBean。

2、JavaBean与数据库字段映射

        众所周知,数据的命名一般是用小写,而且单词之间一般使用下划线连接起来。而Java中对属性的命名与数据库的字段还是有一定的差异。好在我们采用的是Mybatis_Plus这个框架,可以实现数据库字段和JavaBean的对应。为了后续介绍方便,这里将直接给出空间字段的设置。以实体类代码的形式给出。在Mybatis_Plus中,主要采用@TableField(value="cata_type")来进行数据库字段的设置。完整的代码如下所示:

package com.yelang.project.extend.earthquake.domain.crawler;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.google.gson.annotations.SerializedName;
import com.yelang.framework.handler.PgGeometryTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@TableName(value ="biz_ceic_earthquake",autoResultMap = true)
public class CeicEarthquake implements Serializable{
	private static final long serialVersionUID = -1212153879708670015L;
	@TableId(value="pk_id")
	private Long pkId;//主键
	@SerializedName("AUTO_FLAG")
	@TableField(value="auto_flag")
	private String autoFlag;
	@SerializedName("CATA_ID")
	@TableField(value="cata_id")
	private String cataId;
	@SerializedName("CATA_TYPE")
	@TableField(value="cata_type")
	private String cataType;
	@SerializedName("EPI_DEPTH")
	@TableField(value="epi_depth")
	private BigDecimal epiDepth = new BigDecimal("0.0");
	@SerializedName("EPI_LAT")
	@TableField(value="epi_lat")
	private String epiLat;//纬度
	@SerializedName("EPI_LON")
	@TableField(value="epi_lon")
	private String epiLon;
	@SerializedName("EQ_CATA_TYPE")
	@TableField(value="eq_cata_type")
	private String eqCataType;
	@SerializedName("EQ_TYPE")
	@TableField(value="eq_type")
	private String eqType;
	@SerializedName("IS_DEL")
	@TableField(value="is_del")
	private String isDel;
	@SerializedName("LOCATION_C")
	@TableField(value="location_c")
	private String locationC;
	@SerializedName("LOCATION_S")
	@TableField(value="location_s")
	private String locationS;
	@SerializedName("LOC_STN")
	@TableField(value="loc_stn")
	private String locStn;
	@SerializedName("M")
	@TableField(value="m")
	private String m;
	@SerializedName("M_MB")
	@TableField(value="mmb")
	private String mmb;
	@SerializedName("M_MB2")
	@TableField(value="mmb2")
	private String mmb2;
	@SerializedName("M_ML")
	@TableField(value="mml")
	private String mml;
	@SerializedName("M_MS")
	@TableField(value="mms")
	private String mms;
	@SerializedName("M_MS7")
	@TableField(value="mms7")
	private String mms7;
	@SerializedName("NEW_DID")
	@TableField(value="new_did")
	private String newDid;
	@SerializedName("O_TIME")
	@TableField(value="o_time")
	private Date oTime;
	@SerializedName("O_TIME_FRA")
	@TableField(value="o_time_fra")
	private String oTimeFra;
	@SerializedName("SAVE_TIME")
	@TableField(value="save_time")
	private Date saveTime;
	@SerializedName("SUM_STN")
	@TableField(value="sum_stn")
	private String sumStn;
	@SerializedName("SYNC_TIME")
	@TableField(value="sync_time")
	private Date syncTime;
	@SerializedName("id")
	@TableField(value="epi_id")
	private String epiId;
	@TableField(typeHandler = PgGeometryTypeHandler.class)
	private String geom;
	@TableField(exist=false)
	private String geomJson;
}

二、空间数据表设计

        在很多的技术博客当中,都提到过如何进行空间数据库的设计,与常规的关系型数据库表不一样的是,空间数据库多了空间信息的存储的查询。以地震信息为例,就包含了其经纬度坐标信息。因此这里使用PostGIS作为空间数据库存储空间信息。

        在讲解改表是,我们首先根据接口的字段来定义其关键属性字段,然后自己设计Geometry字段,通过爬取的经纬度信息来生成Geometry信息,然后保存到相应的字段当中。

1、表结构设计

        主要表结构设计如下,包含了通过接口返回的基本信息:

 

         生成出来的SQL语句如下,如果需要的话,可以直接使用,这里直接提供,供大家参考。

CREATE TABLE "public"."biz_ceic_earthquake" (
  "pk_id" int8 NOT NULL,
  "auto_flag" varchar(30) COLLATE "pg_catalog"."default",
  "cata_id" varchar(30) COLLATE "pg_catalog"."default",
  "cata_type" varchar(30) COLLATE "pg_catalog"."default",
  "epi_depth" numeric(11,8),
  "epi_lat" varchar(15) COLLATE "pg_catalog"."default",
  "epi_lon" varchar(15) COLLATE "pg_catalog"."default",
  "eq_cata_type" varchar(30) COLLATE "pg_catalog"."default",
  "eq_type" varchar(30) COLLATE "pg_catalog"."default",
  "is_del" varchar(6) COLLATE "pg_catalog"."default",
  "location_c" varchar(255) COLLATE "pg_catalog"."default",
  "location_s" varchar(100) COLLATE "pg_catalog"."default",
  "loc_stn" varchar(20) COLLATE "pg_catalog"."default",
  "m" varchar(10) COLLATE "pg_catalog"."default",
  "mmb" varchar(10) COLLATE "pg_catalog"."default",
  "mmb2" varchar(10) COLLATE "pg_catalog"."default",
  "mml" varchar(10) COLLATE "pg_catalog"."default",
  "mms" varchar(10) COLLATE "pg_catalog"."default",
  "mms7" varchar(10) COLLATE "pg_catalog"."default",
  "new_did" varchar(16) COLLATE "pg_catalog"."default",
  "o_time" timestamp(6),
  "o_time_fra" varchar(10) COLLATE "pg_catalog"."default",
  "save_time" timestamp(6),
  "sum_stn" varchar(10) COLLATE "pg_catalog"."default",
  "sync_time" timestamp(6),
  "epi_id" varchar(10) COLLATE "pg_catalog"."default",
  "geom" "public"."geometry",
  CONSTRAINT "pk_biz_ceic_earthquake" PRIMARY KEY ("pk_id")
);
CREATE INDEX "idx_biz_ceic_earthquake_eqidept" ON "public"."biz_ceic_earthquake" USING btree (
  "epi_depth" "pg_catalog"."numeric_ops" ASC NULLS LAST
);
CREATE INDEX "idx_biz_ceic_earthquake_geom" ON "public"."biz_ceic_earthquake" USING gist (
  "geom" "public"."gist_geometry_ops_2d"
);
CREATE INDEX "idx_biz_ceic_earthquake_m" ON "public"."biz_ceic_earthquake" USING btree (
  "m" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);
COMMENT ON COLUMN "public"."biz_ceic_earthquake"."pk_id" IS '主键id';

        为了在查询的时候提高查询性能,我们建立三个索引,两个普通索引和一个空间索引,构建在geom这个字段上的。后期如果要做空间分析可以使用空间索引进行查询效率提升。

三、PostGIS数据保存

        设计好了地震信息空间数据表,信息接口也进行了定义。万事俱备只欠东风,只需要采用Mybatis_Plus组件将爬取的信息通过接口保存到PostGIS空间数据库中即可。在第一节中其实已经将实现接口参数转换成数据库字段,关于实体类的定义在此不赘述,这里只将数据入库的流程和方法进行简单介绍。ORM框架采用Mybatis_Plus框架。

1、Mapper接口定义

        mapper接口相当于是数据库操作的总入口,由于这里仅演示如何插入数据,暂时没有其它的业务需求,因此接口中除集成的方法,暂不新增新的方法。

package com.yelang.project.extend.earthquake.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
public interface CeicEarthquakeMapper extends BaseMapper<CeicEarthquake>{
}

2、Service逻辑层实现

        业务逻辑层也比较简单,为了演示效果,同样不增加额外的方法,仅实现MP自带的批量插入功能来实现数据插入。

package com.yelang.project.extend.earthquake.service.impl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
import com.yelang.project.extend.earthquake.mapper.CeicEarthquakeMapper;
import com.yelang.project.extend.earthquake.service.ICeicEarthquakeService;
@Service
public class CeicEarthquakeServiceImpl extends ServiceImpl<CeicEarthquakeMapper, CeicEarthquake> implements ICeicEarthquakeService{
}

3、数据入库

        数据入库主要是调用ICeicEarthquakeService的批量插入方法。这里采用Junit测试套件进行爬取测试。实际情况可以内置到SpringBoot的一个方法或者定时任务当中。在这里需要注意的一个地方就是,我们在数据库中定义了一个Geometry字段来存储空间点信息。因此在信息爬取过程中需要动态生成,主要是手动构造Wkt格式的数据,通过PgGeometryTypeHandler来实现空间类型转换,看过博客的朋友应该对这种操作方法很熟悉。爬取及入库的代码如下:

package com.yelang.project;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.xuxueli.crawler.XxlCrawler;
import com.xuxueli.crawler.parser.strategy.NonPageParser;
import com.yelang.common.utils.StringUtils;
import com.yelang.project.extend.earthquake.domain.crawler.CeicDateAdapter;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquakeCrawler;
import com.yelang.project.extend.earthquake.service.ICeicEarthquakeService;
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestXxlCrawerCeic {
	@Autowired
	private ICeicEarthquakeService service;
	@Test
	public void testGetCeic() {
		String commonUrl = "https://www.ceic.ac.cn/ajax/search?start=&&end=&&jingdu1=&&jingdu2=&&weidu1=&&weidu2=&&height1=&&height2=&&zhenji1=&&zhenji2=&_="
				+ System.currentTimeMillis();
		String[] urlList = new String[20];
		urlList[0] = commonUrl + "&&page=" + 1;
		// 构造爬虫
		XxlCrawler crawler = new XxlCrawler.Builder().setUrls(urlList).setThreadCount(3).setPauseMillis(3000)
				.setUserAgent(
						"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36")
				.setIfPost(false).setFailRetryCount(3)// 重试三次
				.setPageParser(new NonPageParser() {
					public void parse(String url, String pageSource) {
						if (!StringUtils.isBlank(pageSource)) {
							pageSource = pageSource.substring(1, pageSource.length() - 1);
							Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new CeicDateAdapter()).create();
							CeicEarthquakeCrawler crawler = gson.fromJson(pageSource, CeicEarthquakeCrawler.class);
							System.out.println("总页数:"+crawler.getNum());
							for (CeicEarthquake data : crawler.getShuju()) {
								String geom = "SRID=" + 4326 +";POINT (" + data.getEpiLon()+ " "+data.getEpiLat()+")";//拼接srid,实现动态写入
								System.out.println(data);
								System.out.println(geom);
								data.setGeom(geom);
							}
							service.saveBatch(crawler.getShuju(), 300);
						}
					}
				}).build();
		crawler.start(true);// 启动
	}
}

        上面代码的关键就是WKT的构造,默认采用4326坐标系:

String geom = "SRID=" + 4326 +";POINT (" + data.getEpiLon()+ " "+data.getEpiLat()+")";//拼接srid,实现动态写入

4、运行实例及结果

        使用Junit的测试套件运行上述方法,在控制台可以看到如下的打印结果:

        很明显在控制台中看到批量插入语句和信息爬取信息,示例信息如下:

CeicEarthquake(pkId=null, autoFlag=M, cataId=CD20240407190310.00, cataType=, epiDepth=18, epiLat=41.89, epiLon=82.17, eqCataType=, eqType=M, isDel=, locationC=新疆阿克苏地区拜城县, locationS=, locStn=0, m=4.2, mmb=0, mmb2=0, mml=0, mms=0, mms7=0, newDid=CD20240407190310, oTime=Sun Apr 07 19:03:09 CST 2024, oTimeFra=0, saveTime=Sun Apr 07 19:08:03 CST 2024, sumStn=0, syncTime=Sun Apr 07 19:08:03 CST 2024, epiId=46366, geom=null, geomJson=null)
SRID=4326;POINT (82.17 41.89)
CeicEarthquake(pkId=null, autoFlag=M, cataId=CD20240407182216.00, cataType=, epiDepth=15, epiLat=41.91, epiLon=82.00, eqCataType=, eqType=M, isDel=, locationC=新疆阿克苏地区拜城县, locationS=, locStn=0, m=3.0, mmb=0, mmb2=0, mml=0, mms=0, mms7=0, newDid=CD20240407182216, oTime=Sun Apr 07 18:22:16 CST 2024, oTimeFra=0, saveTime=Sun Apr 07 18:27:58 CST 2024, sumStn=0, syncTime=Sun Apr 07 18:27:58 CST 2024, epiId=46365, geom=null, geomJson=null)
SRID=4326;POINT (82.00 41.91)
19:43:44.403 [pool-2-thread-2] DEBUG c.y.p.e.e.m.C.insert - [debug,137] - ==>  Preparing: INSERT INTO biz_ceic_earthquake ( pk_id, auto_flag, cata_id, cata_type, epi_depth, epi_lat, epi_lon, eq_cata_type, eq_type, is_del, location_c, location_s, loc_stn, m, mmb, mmb2, mml, mms, mms7, new_did, o_time, o_time_fra, save_time, sum_stn, sync_time, epi_id, geom ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
19:43:44.548 [pool-2-thread-2] DEBUG c.y.p.e.e.m.C.insert - [debug,137] - ==> Parameters: 1780562787278299138(Long), M(String), CD20240411005512.00(String), (String), 12(BigDecimal), 24.14(String), 121.87(String), (String), M(String), (String), 台湾花莲县海域(String), (String), 0(String), 4.4(String), 0(String), 0(String), 0(String), 0(String), 0(String), CD20240411005512(String), 2024-04-11 00:55:12.0(Timestamp), 0(String), 2024-04-11 01:05:21.0(Timestamp), 0(String), 2024-04-11 01:05:21.0(Timestamp), 46385(String), SRID=4326;POINT(121.87 24.14)(PGgeometry)

         最后来看一下在PostGIS当中是否将数据成功入库,在客户端中执行以下查询语句:

select * from biz_ceic_earthquake;

        通过上述界面看到,通过XxlCrawler爬取的信息就成功的保存到了PostGIS空间数据库中。

总结

        以上就是本文的主要内容,本文即紧紧围绕着将信息保存到空间数据库的目标,重点讲解如何实现将中国地震台网爬取的地震信息保存到PostGIS空间数据库中。首先讲解在爬取过程中数据格式和响应数据类型的转换,将网站回传的json数据转成符合Java命名规范的数据。然后介绍台网地震信息表的设计,如何构建空间数据表。再次介绍如何将爬取的数据调用Mybatis-Plus组件实现批量入库。行文仓促,定有不足,欢迎朋友们在评论浏览批评指正,不胜感激。

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

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

相关文章

ActiveMQ 07 集群配置

Active MQ 07 集群配置 官方文档 http://activemq.apache.org/clustering 主备集群 http://activemq.apache.org/masterslave.html Master Slave TypeRequirementsProsConsShared File System Master SlaveA shared file system such as a SANRun as many slaves as requ…

leetcode:739.每日温度/496.下一个更大元素

单调栈的应用&#xff1a; 求解当前元素右边比该元素大的第一个元素&#xff08;左右、大小都可以&#xff09;。 单调栈的构成&#xff1a; 单调栈里存储数组的下标&#xff1b; 单调栈里的元素递增&#xff0c;求解当前元素右边比该元素大的第一个元素&#xff1b;元素递…

Python继承

语法格式&#xff1a; class 子类类名(父类1[&#xff0c;父类2&#xff0c;...])&#xff1a;类体如果在类定义中没有指定父类&#xff0c;则默认父类是 object类 。也就是说&#xff0c;object 是所有类的父类&#xff0c;里面定义了一些所有类共有的默认实现&#xff0c;比…

Python接口自动化 —— Web接口!

1.2.1 web接口的概念 这里用一个浏览器调试工具捕捉课程管理页面请求作为例子&#xff1a; 当请求页面时&#xff0c;服务器会返回资源&#xff0c;将协议看做是路的话&#xff0c;http可以看做高速公路&#xff0c;soap看做铁路传输的数据有html&#xff0c;css&#xff0…

【文献分享】PCCP:机器学习 + 分子动力学 + 第一性原理 + 热学性质 + 微观结构

分享一篇关于机器学习 分子动力学 第一性原理 热学性质&#xff08;密度、粘度、扩散系数&#xff09; 微观结构的文章。 感谢论文的原作者&#xff01; 关键词&#xff1a; 1. Machine learning, 2. Deep potential, 3. Molecular dynamics 4. Molten salt, 5. Thermo…

OCP-数据库中的小米SU7

oracle ocp ​数据库中的SU7 ​好看又好用 需要找工作和落户的快来

剑指offer剪绳子;leetcode:LCR 131. 砍竹子 I

现需要将一根长为正整数 bamboo_len 的竹子砍为若干段&#xff0c;每段长度均为正整数。请返回每段竹子长度的最大乘积是多少。 示例 1&#xff1a; 输入: bamboo_len 12 输出: 81提示&#xff1a; 2 < bamboo_len < 58 注意&#xff1a;本题与主站 343 题相同&#…

基于峰谷分时电价引导下的电动汽车充电负荷优化

在研究电动汽车用户充电需求的前提下&#xff0c;利用蒙特卡洛方法对&#xff12;种不同充电方式进行模拟并对其进行分 析&#xff1b;分析用户响应度对电动汽车有序充电的影响&#xff0c;建立峰谷分时电价对电动汽车负荷影响的模型&#xff0c;在模拟出电动汽 车无序充电负荷…

Windows 部署ChatGLM3大语言模型

一、环境要求 硬件 内存&#xff1a;> 16GB 显存: > 13GB&#xff08;4080 16GB&#xff09; 硬盘&#xff1a;60G 软件 python 版本推荐3.10 - 3.11 transformers 库版本推荐为 4.36.2 torch 推荐使用 2.0 及以上的版本&#xff0c;以获得最佳的推理性能 二、部…

重生奇迹mu恶魔来袭副本

在游戏重生奇迹mu中&#xff0c;恶魔来袭副本是玩家能够组队通过的副本。但是因为手游组队的不方便性&#xff0c;部分玩家对其还是非常苦手。而今天&#xff0c;我们就给大家讲解一下这个游戏的双人通关攻略。 1、挂机找怪手动输出 (1)对于普通剧情副本而言&#xff0c;挂机…

利用CNN-Bigru-Attention模型输电线路故障诊断(Python代码,TensorFlow框架,)

效果视频&#xff1a;利用CNN-Bigru-Attention模型输电线路故障诊断(Python代码&#xff0c;TensorFlow框架&#xff0c;压缩包带有数据集和代码&#xff0c;解压缩可直接运行)_哔哩哔哩_bilibili 售后包免费远程协助运行&#xff08;用向日葵或者todesk软件协助&#xff09; …

校园智能水电预付费管理系统

校园智能水电预付费管理系统是一种专为学校水电资源管理而设计的智能化系统&#xff0c;旨在提供全面的水电资源管理解决方案&#xff0c;满足校园管理者对水电资源管理的需求。该系统整合了先进的智能技术和云计算&#xff0c;为校园管理者提供了实时监控、自动计费、节能管理…

如何将图片你分辨率调整到350dpi?分辨率快速设置工具

图片的分辨率通常用在打印照片和一些考试平台对上传证件照的要求上&#xff0c;我们平时拍摄的图片dpi大多都是96的&#xff0c;所以不符合使用需求&#xff0c;那么怎么把这些比较低分辨率的图片修改到350dpi呢&#xff1f;试试本文分享的这几个方法吧&#xff0c;简单又方便。…

使用阿里云试用Elasticsearch学习:创建仪表板pivot、搜索discover和仪表板dashboard

文档&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/transform-examples.html#example-clientips 在kibana左栏打开Transforms&#xff0c;并创建Transforms&#xff08;转换&#xff09; Management > Stack Management > Data > T…

component-传入值圆形百分比展示,.background-image: conic-gradient()

1.效果 2.代码 <template><div class"circle" :style"{ background-image: conic-gradient(#3498db 0 ${fillPercentage}%, transparent ${fillPercentage}% 100%) }"></div> <!-- 使用动态绑定样式来设置填充效果 --> </temp…

放大招,推广手机流量卡,佣金丰厚等你来拿

流量卡推广是一个非常冷门但又在身边非常常见的行业&#xff0c;知道的人目前靠着这个信息&#xff0c;发了很多小财&#xff0c;可以说早知道这一行的人会非常容易变成暴发户。 你可能也会好奇&#xff0c;为什么那么多广告都是在推流量卡&#xff0c;他们推卡到底有多高的利…

SpringBoot配置文件加载顺序

一、内部配置加载顺序 SpringBoot程序启动时&#xff0c;会从以下位置加载配置文件&#xff1a; file:./config/ &#xff1a;当前项目的config目录下&#xff1b;file:./ &#xff1a;当前项目的根目录下&#xff1b;classpath:/c…

L1-086 斯德哥尔摩火车上的题

上图是新浪微博上的一则趣闻&#xff0c;是瑞典斯德哥尔摩火车上的一道题&#xff0c;看上去是段伪代码&#xff1a; s a 1112031584 for (i 1; i < length(a); i) {if (a[i] % 2 a[i-1] % 2) {s max(a[i], a[i-1])} } goto_url(www.multisoft.se/ s)其中字符串的 …

STM32 CAN控制的相关结构体(标准库)

STM32 CAN控制的相关结构体&#xff08;标准库&#xff09; 初始化结构体&#xff1a; CAN_InitTypeDef CAN_Prescaler 本成员设置CAN外设的时钟分频&#xff0c;它可控制时间片Tq的时间长度&#xff0c;这里设置的值最终会减1后再写入BRP寄存器位&#xff0c;即前面介绍的Tq计…

数组中两个字符串的最短距离---一题多解(贪心/二分)

点击跳转到题目 方法&#xff1a;贪心 / 二分 目录 贪心&#xff1a; 二分&#xff1a; 贪心&#xff1a; 要找出字符串数组中指定两个字符串的最小距离&#xff0c;即找出指定字符串对应下标之差的最小值 思考&#xff1a;如果是直接暴力求解&#xff0c;需要两层for循环…