使用Java和PostGis的全国A级风景区数据入库实战

目录

前言

一、数据介绍

1、空间数据 

 2、属性表说明

3、QGIS数据预览 

 二、PostGIS空间数据库设计

1、空间表结构

 三、Java空间入库

1、实体定义

2、数据操作Mapper

3、业务层实现

4、入库

5、数据入库验证

总结


前言

        星垂平野阔,月涌大江流”“晴川历历汉阳树,芳草萋萋鹦鹉洲”……祖国的每一寸土地,都饱含着诗情画意。旅行一定是很多朋友的爱好,有人说:“人生至少要有两次冲动:一场奋不顾身的爱情和一段走就走的旅行。”不知道在看博文的朋友,是否也是一位旅行爱好者呢。

        随着后疫情时代的到来,许多人又开始踏上旅行。旅游可以放松自己身心,缓解工作和生活方面的压力.旅行的过程中是不需要有任何的心理负担的,可以使人达到一种完全放松的状况.感受最原始的快乐。旅行的时候不仅可以观赏风景,还可以尝美食,住宾馆,听故事,感受全国各地的饮食文化.增长自己的见识,可以看到更多的人.了解更多的民俗文化,看到更多的景色使自己的内心感到充实。旅游可以开阔眼界,观察到丰富的人文景观,了解各地的文化风俗,饮食习惯和宗教信仰,广交朋友。旅游还可以锤炼人的意志,增加人的智慧,尤其是去一些有挑战性的景区游玩,征服一座山,跨过一条河学会一项新技能,都可以使自己变的更加勇敢。

        中华大地,旅游景点众多,那我们国家到底有多少旅游景区呢?在前面的很多博文中,我们讲过如何将空间数据进行入库。那么文本将采用Java语言,重点讲述如何将全国A级风景区数据导入到PostGis数据库中,为后续我们进行旅游资源和旅游路线的推荐和展示打下坚实的基础。如果您也是WebGis的爱好者,可以从本文了解空间数据的入库开发方式,知道空间数据库的设计和操作。

一、数据介绍

        数据说明,本文下载的数据是朋友分享的2023年全国A级风景区数据。数据大小为36MB左右,数据格式shapfile,下面是数据展示。

1、空间数据 

        这里我们采用Qgis对空间数据进行导入前查看。其基础信息如下表所示:

序号参数说明
1文件格式

ESRI Shapefile

2文件编码

GBK

3元素类型

Point

4坐标参考系

EPSG:4326 - WGS 84 

5数据单位
6数据总数

14,847

 2、属性表说明

        在shp文件中,除了有空间数据的定义,还有属性数据的定义,A级景区shp数据一共有15个字段,详情请看下面的表定义。

序号字段名数据类型长度
1

景区名称

String 254
2

等级

String254
3

所属省份

String254
4

地址

String254
5

评定时间

String254
6

发布时间

String254
7

发布链接

String254
8

lng_GCJ02(高德经度)

Double18
9

lat_GCJ02(高德纬度)

Double18
10

lng_BD09(百度经度)

Double18
11

lat_BD09(百度纬度)

Double18
12

lng_WGS84

Double18
13

lat_WGS84

Double18
14

所属城市

String254
15

所属区县

String254

3、QGIS数据预览 

        我们使用qgis对数据进行简单标绘,使用景区名字进行标注,使用景区等级做分类。可以看到如下的分类结果展示。       

 二、PostGIS空间数据库设计

        空间数据库我们采用PostGIS进行存储,这里来简单设计一下如何存储景区数据。完整的景区数据条数在1万5千条左右。因此我们只需要设计一张景区表即可。与其空间属性保持一一对应的关系,我们来看一下数据表的表结构信息。

1、空间表结构

        下面给出风景区空间数据库表的表结构:

/*==============================================================*/
/* Table: biz_scenic_spot                                       */
/*==============================================================*/
create table biz_scenic_spot (
   id                   INT8                 not null,
   name                 VARCHAR(255)         null,
   level                VARCHAR(4)           null,
   province             VARCHAR(255)         null,
   city                 VARCHAR(255)         null,
   area                 VARCHAR(255)         null,
   address              VARCHAR(255)         null,
   evaluation_time      VARCHAR(255)         null,
   publish_time         VARCHAR(255)         null,
   publish_link         VARCHAR(255)         null,
   lng_GCJ02            VARCHAR(30)          null,
   lat_GCJ02            VARCHAR(30)          null,
   lng_BD09             VARCHAR(30)          null,
   lat_BD09             VARCHAR(30)          null,
   lng_WGS84            VARCHAR(30)          null,
   lat_WGS84            VARCHAR(30)          null,
   geom                 geometry                null,
   constraint PK_BIZ_SCENIC_SPOT primary key (id)
);

comment on table biz_scenic_spot is
'全国风景区信息表';

comment on column biz_scenic_spot.id is
'主键';

comment on column biz_scenic_spot.name is
'景区名称';

comment on column biz_scenic_spot.level is
'景区级别';

comment on column biz_scenic_spot.province is
'所属省份';

comment on column biz_scenic_spot.city is
'所属城市';

comment on column biz_scenic_spot.area is
'所属区县';

comment on column biz_scenic_spot.address is
'地址';

comment on column biz_scenic_spot.evaluation_time is
'评定时间';

comment on column biz_scenic_spot.publish_time is
'发布时间';

comment on column biz_scenic_spot.publish_link is
'发布链接';

comment on column biz_scenic_spot.lng_GCJ02 is
'lng_GCJ02';

comment on column biz_scenic_spot.lat_GCJ02 is
'lat_GCJ02';

comment on column biz_scenic_spot.lng_BD09 is
'lng_BD09';

comment on column biz_scenic_spot.lat_BD09 is
'lat_BD09';

comment on column biz_scenic_spot.lng_WGS84 is
'lng_WGS84';

comment on column biz_scenic_spot.lat_WGS84 is
'lat_WGS84';

为了在后面的应用中应用空间索引,我们在geom字段上创建空间索引,创建语句如下:

-- ----------------------------
CREATE INDEX "idx_biz_scenic_spot_geom" ON "public"."biz_scenic_spot" USING gist (
  "geom" "public"."gist_geometry_ops_2d"
);

 三、Java空间入库

        这里主要讲解如何使用Java语言将shp数据进行导入到PostGis数据库中,主要采用的组件还是Gdal,如果大家对gdal不太熟悉,可以翻看博主以前的博客,有关于gdal的部署和具体使用方法。下面从代码实现来详细讲解具体的入库过程。后台开发框架采用Springboot,ORM框架采用Mybatis-plus,都是熟悉的组件。如果看博客的朋友对上述框架不是很熟悉,可以先学习一下相关的知识,对于理解和代码掌握有很大的帮助。

1、实体定义

        示例工程采用MVC三层开发模式,这里只讲解M层,V和C在后续博文中讲解。

package com.yelang.project.extend.scenicspot.domain;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yelang.framework.handler.PgGeometryTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
 *  全国风景区信息表
* @author wzh
*
*/
@TableName(value = "biz_scenic_spot", autoResultMap = true)
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class ScenicSpot implements Serializable{
	private static final long serialVersionUID = 1830004907219610805L;

	@TableId
	private Long id;
	
	private String name;//景区名称
	
	private String level;//景区级别
	
	private String province;//所属省份
	
	private String city;//所属城市
	
	private String area;//所属区县
	
	private String address;//地址
	
	@TableField(value="evaluation_time")
	private String evaluationTime;//评定时间
	
	@TableField(value="publish_time")
	private String publishTime;//发布时间
	
	@TableField(value="publish_link")
	private String publishLink;//发布时间
	
	@TableField(value="lng_GCJ02")
	private String lngGCJ02;
	
	@TableField(value="lat_GCJ02")
	private String latGCJ02;
	
	@TableField(value="lng_BD09")
	private String lngBD09;
	
	@TableField(value="lat_BD09")
	private String latBD09;
	
	@TableField(value="lng_WGS84")
	private String lngWGS84;
	
	@TableField(value="lat_WGS84")
	private String latWGS84;
	
	@TableField(typeHandler = PgGeometryTypeHandler.class)
	private String geom;
	
	@TableField(exist=false)
	private String geomJson;

	public ScenicSpot(String name, String level, String province, String city, String area, String address,
			String evaluationTime, String publishTime, String publishLink,String lngGCJ02, String latGCJ02, String lngBD09, String latBD09,
			String lngWGS84, String latWGS84, String geom) {
		super();
		this.name = name;
		this.level = level;
		this.province = province;
		this.city = city;
		this.area = area;
		this.address = address;
		this.evaluationTime = evaluationTime;
		this.publishTime = publishTime;
		this.publishLink = publishLink;
		this.lngGCJ02 = lngGCJ02;
		this.latGCJ02 = latGCJ02;
		this.lngBD09 = lngBD09;
		this.latBD09 = latBD09;
		this.lngWGS84 = lngWGS84;
		this.latWGS84 = latWGS84;
		this.geom = geom;
	}
}

        这里有几个地方要注意的就是,在类最开始定义的地方,@TableName(value = "biz_scenic_spot", autoResultMap = true),这里一定要这么写,否则后续将无法操作geometry数据。其次是@TableField(typeHandler = PgGeometryTypeHandler.class),通过绑定typehandler来设置具体的处理函数。

2、数据操作Mapper

        熟悉Mybatis-Plus(mp)的朋友一定了解ORM操作的三个重要对象之一就是Mapper,相当与对jdbc的封装。下面是mapper的实现:

package com.yelang.project.extend.scenicspot.mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yelang.project.extend.scenicspot.domain.ScenicSpot;

public interface ScenicSpotMapper extends BaseMapper<ScenicSpot>{
	static final String FIND_GEOJSON_SQL="<script>"
			+ "select st_asgeojson(geom) as geomJson from biz_scenic_spot "
			+ "where id = #{id} "
			+ "<if test='null != name'>and name like concat('%', #{name}, '%')</if>"
			+ "</script>";
	@Select(FIND_GEOJSON_SQL)
	ScenicSpot findGeoJsonById(@Param("id")Long id,@Param("name")String name);
}

3、业务层实现

        为了方便做景区数据的批量入库,我们在Mp之上实现serviceimpl,好直接调用其的批量处理方法,示例代码如下:

package com.yelang.project.extend.scenicspot.service.impl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yelang.project.extend.scenicspot.domain.ScenicSpot;
import com.yelang.project.extend.scenicspot.mapper.ScenicSpotMapper;
import com.yelang.project.extend.scenicspot.service.IScenicSpotService;
@Service
public class ScenicSpotServiceImpl extends ServiceImpl<ScenicSpotMapper, ScenicSpot> implements IScenicSpotService{

	@Override
	public ScenicSpot findGeoJsonById(Long id) {
		return this.baseMapper.findGeoJsonById(id, null);
	}
}

4、入库

        这里采用junit测试组件来进行数据入库,首先将调用gdal进行shp数据解析,然后调用service方法进行空间数据入库。这里需要注意的是,要在junit测试方法中注入bean对象,因此,需要在测试bean中使用下面的注解。

@SpringBootTest
@RunWith(SpringRunner.class)
package com.yelang.project;
import java.util.ArrayList;
import java.util.List;
import org.gdal.gdal.gdal;
import org.gdal.ogr.DataSource;
import org.gdal.ogr.Feature;
import org.gdal.ogr.Geometry;
import org.gdal.ogr.Layer;
import org.gdal.ogr.ogr;
import org.gdal.osr.SpatialReference;
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.yelang.project.extend.scenicspot.domain.ScenicSpot;
import com.yelang.project.extend.scenicspot.service.IScenicSpotService;
@SpringBootTest
@RunWith(SpringRunner.class)
public class ImportScenicSpot {
	@Autowired
	private IScenicSpotService scenicSpotService;

	@Test
	public void importData() {
		// 指定文件的名字和路径
		String strVectorFile = "C:/BaiduDownload/20230726 A级景点、宗教分布、与非遗空间分布\\2023年全国A级景区数据/2023年全国A级景区数据.shp";
		// 注册所有的驱动
		ogr.RegisterAll();
		gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
		gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
		String strDriverName = "ESRI Shapefile";
		org.gdal.ogr.Driver oDriver = ogr.GetDriverByName(strDriverName);
		if (oDriver == null) {
			System.out.println(strDriverName + " 驱动不可用!\n");
			return;
		}
		DataSource dataSource = oDriver.Open(strVectorFile);
		Layer layer = dataSource.GetLayer(0);
		SpatialReference spatialReference = layer.GetSpatialRef();
		String srid = spatialReference.GetAttrValue("AUTHORITY", 1);
		long featureCount = layer.GetFeatureCount();
		List<ScenicSpot> list = new ArrayList<ScenicSpot>(3000);
		for (int i = 0; i < featureCount; i++) {
			Feature feature = layer.GetFeature(i);
			String name = feature.GetFieldAsString("景区名称");
			String level = feature.GetFieldAsString("等级");
			String province = feature.GetFieldAsString("所属省份");
			String city = feature.GetFieldAsString("所属城市");
			String area = feature.GetFieldAsString("所属区县");
			String address = feature.GetFieldAsString("地址");
			String evaluationTime = feature.GetFieldAsString("评定时间");
			String publishTime = feature.GetFieldAsString("发布时间");
			String publishLink = feature.GetFieldAsString("发布链接");
			String lngGCJ02 = feature.GetFieldAsString("lng_GCJ02");
			String latGCJ02 = feature.GetFieldAsString("lat_GCJ02");
			String lngBD09 = feature.GetFieldAsString("lng_BD09");
			String latBD09 = feature.GetFieldAsString("lat_BD09");
			String lngWGS84 = feature.GetFieldAsString("lng_WGS84");
			String latWGS84 = feature.GetFieldAsString("lat_WGS84");
			Geometry geom = feature.GetGeometryRef();
			//step 1、生成原始wkt
			String wkt = geom.ExportToWkt();
			wkt = "SRID=" + srid +";" + wkt;//拼接srid,实现动态写入
			list.add(new ScenicSpot(name, level, province, city, area, address, evaluationTime, publishTime, publishLink, lngGCJ02, latGCJ02, lngBD09, latBD09, lngWGS84, latWGS84, wkt));
			if(list.size() == 2000) {
				System.out.println("00000000000000");
				scenicSpotService.saveBatch(list,2000);
				list.clear();
			}
		}
		if(list.size() >0) {
			scenicSpotService.saveBatch(list,1000);
		}
		System.out.println("完成!!!");
		dataSource.delete();
		gdal.GDALDestroyDriverManager();
	}
}

5、数据入库验证

        下面我们来运行一下测试代码,试着将数据导入到数据库中,鼠标右键运行。

        运行后在控制台可以看到以下输出: 

20:29:30.821 [main] DEBUG c.y.p.e.s.m.S.insert - [debug,137] - ==> Parameters: 1762817301184356354(Long), 八面山景区(String), 3A(String), 湖南(String), 湘西土家族苗族自治州(String), 龙山县(String), 湖南湘西自治州八面山景区(String), -(String), 发布时间:2022-08-03;统计截至时间:2021年底(String), (String), 109.25780600000(String), 28.83474400000(String), 109.26441070000(String), 28.84042333000(String), 109.25318500000(String), 28.83790594000(String), SRID=4326;POINT(109.253185 28.83790594)(PGgeometry)
20:29:30.822 [main] DEBUG c.y.p.e.s.m.S.insert - [debug,137] - ==> Parameters: 1762817301184356355(Long), 湘西自治州花垣县古苗河百瀑大峡谷景区(String), 3A(String), 湖南(String), 湘西土家族苗族自治州(String), 花垣县(String), 湖南湘西自治州湘西自治州花垣县古苗河百瀑大峡谷景区(String), -(String), 发布时间:2022-08-03;统计截至时间:2021年底(String), (String), 109.48161300000(String), 28.58698200000(String), 109.48818110000(String), 28.59279936000(String), 109.47683150000(String), 28.59022625000(String), SRID=4326;POINT(109.4768315 28.59022625)(PGgeometry)
20:29:30.822 [main] DEBUG c.y.p.e.s.m.S.insert - [debug,137] - ==> Parameters: 1762817301188550658(Long), 浏阳古风洞(String), 2A(String), 湖南(String), 长沙市(String), 浏阳市(String), 湖南长沙市浏阳古风洞(String), -(String), 发布时间:2022-08-03;统计截至时间:2021年底(String), (String), 113.79441900000(String), 28.21724500000(String), 113.80095370000(String), 28.22317049000(String), 113.78889760000(String), 28.22061438000(String), SRID=4326;POINT(113.7888976 28.22061438)(PGgeometry)
20:29:30.822 [main] DEBUG c.y.p.e.s.m.S.insert - [debug,137] - ==> Parameters: 1762817301188550659(Long), 耒阳市农耕文化博物馆旅游景区(String), 2A(String), 湖南(String), 衡阳市(String), 耒阳市(String), 湖南衡阳市耒阳市农耕文化博物馆旅游景区(String), -(String), 发布时间:2022-08-03;统计截至时间:2021年底(String), (String), 112.86089200000(String), 26.42240400000(String), 112.86748910000(String), 26.42806999000(String), 112.85559400000(String), 26.42594269000(String), SRID=4326;POINT(112.855594 26.42594269)(PGgeometry)
20:29:30.822 [main] DEBUG c.y.p.e.s.m.S.insert - [debug,137] - ==> Parameters: 1762817301188550660(Long), 耒阳市党史陈列馆(String), 2A(String), 湖南(String), 衡阳市(String), 耒阳市(String), 湖南衡阳市耒阳市党史陈列馆(String), -(String), 发布时间:2022-08-03;统计截至时间:2021年底(String), (String), 112.85569800000(String), 26.40719700000(String), 112.86228240000(String), 26.41286866000(String), 112.85039320000(String), 26.41072176000(String), SRID=4326;POINT(112.8503932 26.41072176)(PGgeometry)
完成!!!

         最后到数据库中验证数据是否已经成功导入,在客户端中运行以下语句。可以看到数据全部导入,数据总条数是14847条。

总结

        以上就是本文的主要内容,那么文本将采用Java语言,重点讲述如何将全国A级风景区数据导入到PostGis数据库中,为后续我们进行旅游资源和旅游路线的推荐和展示打下坚实的基础。如果您也是WebGis的爱好者,可以从本文了解空间数据的入库开发方式,知道空间数据库的设计和操作。

  • 79
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 118
    评论
### 回答1: 要使用pgadmin4和postgis进行数据表的可视化,您需要先完成以下步骤: 1. 安装PostgreSQL和PostGIS 在您的计算机上安装PostgreSQL和PostGIS。这些软件是免费的,并且有很多安装指南可供参考。在安装PostgreSQL时,请确保安装PostGIS插件。 2. 启动pgadmin4 启动pgadmin4,然后登录到您的PostgreSQL服务器。在服务器组中右键单击并选择“新建服务器”。 3. 创建连接 填写服务器属性对话框,以创建到PostgreSQL服务器的连接。请务必输入正确的服务器名称和登录凭据。 4. 创建数据库 右键单击服务器并选择“新建数据库”。在“新建数据库”对话框中,输入数据库名称并选择“PostGIS”作为模板。 5. 创建表 在新创建的数据库上右键单击,选择“新建查询工具”。在查询工具中,输入SQL命令以创建表。例如,以下命令将在数据库中创建一个名为“cities”的表: ``` CREATE TABLE cities ( id SERIAL PRIMARY KEY, name VARCHAR(50), location GEOMETRY(Point, 4326) ); ``` 6. 导入数据 您可以使用pgadmin4的导入工具将数据导入到表中。右键单击表并选择“导入/导出”,然后选择要导入的文件。 7. 可视化数据 在pgadmin4中,右键单击表并选择“查看/编辑数据”。这将打开一个表格,其中包含表中的数据。您可以使用此表格可视化您的数据。 8. 使用PostGIS扩展 PostGIS提供了很多地理空间函数,可以方便地分析和可视化地理数据。例如,以下命令将在PostGIS中计算“cities”表中所有城市之间的距离: ``` SELECT a.name, b.name, ST_Distance(a.location, b.location) AS distance FROM cities AS a, cities AS b WHERE a.id < b.id; ``` 这是一些基本步骤,您可以使用pgadmin4和PostGIS进行数据表的可视化和分析。根据您的需求,可能需要更多的操作和配置。 ### 回答2: 使用pgAdmin 4和PostGIS可以轻松地进行数据表的可视化和操作。 首先,确保已经安装了PostgreSQL数据库以及pgAdmin 4。在pgAdmin 4中,创建一个新的数据库连接,将连接到已经安装好PostgreSQL的服务器。通过输入正确的主机、端口、用户名和密码来建立连接。 接下来,创建一个新的数据库,右键点击服务器,选择"创建"->"数据库",并设置数据库的名称和所有者。点击保存后,新的数据库就会被创建。 然后,在创建的数据库中启用PostGIS扩展。右键点击数据库,选择"查询工具"来打开查询窗口,然后运行以下命令来启用PostGIS扩展: CREATE EXTENSION postgis; 完成后,会在数据库中创建spatial_ref_sys系统表和一些其他的函数和视图。 现在,可以开始创建数据表了。右键点击数据库,选择"创建"->"表",然后在弹出窗口中输入表的名称、列的名称和数据类型。在定义列时,可以选择适当的地理或几何数据类型,如POINT,LINESTRING等。点击保存后,数据表就会被创建。 要在pgAdmin 4中进行数据表的可视化,可以右键点击表,选择"查看/编辑数据",然后在弹出窗口中查看和编辑数据。在数据表的视图中,可以选择不同的选项来执行查询、插入、更新和删除操作。 除了在pgAdmin 4中可视化地查看和操作数据表外,还可以使用PostGIS的功能来进行地理数据的查询和分析。例如,可以使用ST_Distance函数计算两个点之间的距离,使用ST_Within函数判断一个点是否在一个多边形内等等。 总之,使用pgAdmin 4和PostGIS可以方便地进行数据表的可视化和操作,并结合PostGIS的功能进行地理数据的查询和分析。 ### 回答3: PgAdmin是一个开源的基于Web的数据库管理工具,可以用于管理和操作PostgreSQL数据库PostGIS是一个开源的地理信息系统(GIS)扩展,用于在PostgreSQL数据库中存储和处理地理空间数据。 要使用PgAdmin和PostGIS进行数据表的可视化,首先需要在PostgreSQL数据库中安装和配置PostGIS扩展。然后,可以使用PgAdmin连接到PostgreSQL数据库,创建新的数据库使用现有的数据库。 在PgAdmin中,可以使用SQL工具或查询工具来执行SQL语句,包括创建表、插入数据、查询和更新数据操作。例如,可以通过执行CREATE TABLE语句创建新的数据表,并使用INSERT语句将数据插入到表中。 要进行数据表的可视化,可以使用PgAdmin提供的可视化功能。在PgAdmin的对象树视图中,可以展开数据库和表,查看和编辑表结构、查看数据以及执行各种操作。 此外,PgAdmin还支持地理空间数据的可视化和分析。可以使用PgAdmin的地理信息系统工具来展示地理空间数据,如地图、图表和统计数据等。可以使用地理信息系统工具查询和分析地理空间数据,如计算距离、面积和缓冲区等操作。 通过使用PgAdmin和PostGIS,你可以方便地进行数据表的可视化和地理空间数据的处理。无论是在专业的GIS应用程序中还是在日常的数据管理工作中,这些工具都提供了强大的功能和简单易用的界面,帮助你更好地管理和分析数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 118
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜郎king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值