2024年使用Java和PostGis的全国A级风景区数据入库实战_postgis java(2),字节跳动今日学习内容

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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{
static final String FIND_GEOJSON_SQL=“”;
@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、数据入库验证


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


![](https://img-blog.csdnimg.cn/direct/e6bb64dc63d54cf0907f32e81682e354.png)


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


![](https://img-blog.csdnimg.cn/direct/d96abb6ad5084790a12d13f33956f5bd.png)



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)

本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。

最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。

最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。

学习路线图

其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。

相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。

网络安全工具箱

当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。

项目实战

最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

面试题

归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值