1. springboot项目初始化
1.1 方式一:springboot官方的模板生成器
1.2 方式二:idea开发工具生成(推荐)
1.2.1 新建项目
1.2.2 选择spring initializr, 修改参数
1.2.3 添加依赖
1.2.4 项目初始化成功
1.2.5 idea连接本地数据库
- 打开database工具
- 添加postgresql
- 测试连接,添加
2. 引入mybatis-plus
根据官网文档(baomidou.com/)引入
2.1 创建用户表
create table "user"
(
id bigint not null
primary key,
user_name varchar(50),
age integer,
email varchar(100),
user_account varchar(256),
avatar_url varchar(1024),
gender integer,
user_password varchar(512),
user_status integer default 0,
phone varchar(128),
create_time timestamp,
update_time timestamp,
is_delete integer default 0
);
comment on table "user" is '用户表';
comment on column "user".user_name is '用户昵称';
comment on column "user".age is '年龄';
comment on column "user".email is '邮箱';
comment on column "user".user_account is '账号';
comment on column "user".avatar_url is '头像';
comment on column "user".gender is '性别';
comment on column "user".user_password is '密码';
comment on column "user".user_status is '状态 0-正常';
comment on column "user".phone is '电话';
comment on column "user".create_time is '创建时间';
comment on column "user".update_time is '更新时间';
comment on column "user".is_delete is '是否删除';
alter table "user"
owner to postgres;
2.2 往测试表user插入数据
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
2.3 引入依赖
2.3.1 pom.xml文件添加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
2.3.2 重新加载maven
2.4 修改配置文件
2.4.1 将application文件的后缀名为.yml 支持嵌套写法
2.4.2 修改内容
# DataSource Config
spring:
application:
name: webgis-demo
datasource:
driver-class-name: org.postgresql.Driver
# schema: classpath:db/schema-h2.sql
# data: classpath:db/data-h2.sql
url: jdbc:postgresql://localhost:5432/postgis_21_sample
username: postgres
password: Giseryin
server:
port: 8301
servlet:
#服务应用名
context-path: /webgis-demo
session:
timeout: PT540M
2.5 创建实体类
2.5.1 创建module
包存放java对象
2.5.2 创建 user 实体类,使用lombok简化代码
/**
* 用户表
* @TableName user
*/
@TableName(value ="public.user")
@Data
public class User implements Serializable {
/**
*
*/
@TableId
private Long id;
/**
* 用户昵称
*/
private String userName;
/**
* 年龄
*/
private Integer age;
/**
* 邮箱
*/
private String email;
/**
* 账号
*/
private String userAccount;
/**
* 头像
*/
private String avatarUrl;
/**
* 性别
*/
private Integer gender;
/**
* 密码
*/
private String userPassword;
/**
* 状态 0-正常
*/
private Integer userStatus;
/**
* 电话
*/
private String phone;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
private Integer isDelete;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
User other = (User) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getUserName() == null ? other.getUserName() == null : this.getUserName().equals(other.getUserName()))
&& (this.getAge() == null ? other.getAge() == null : this.getAge().equals(other.getAge()))
&& (this.getEmail() == null ? other.getEmail() == null : this.getEmail().equals(other.getEmail()))
&& (this.getUserAccount() == null ? other.getUserAccount() == null : this.getUserAccount().equals(other.getUserAccount()))
&& (this.getAvatarUrl() == null ? other.getAvatarUrl() == null : this.getAvatarUrl().equals(other.getAvatarUrl()))
&& (this.getGender() == null ? other.getGender() == null : this.getGender().equals(other.getGender()))
&& (this.getUserPassword() == null ? other.getUserPassword() == null : this.getUserPassword().equals(other.getUserPassword()))
&& (this.getUserStatus() == null ? other.getUserStatus() == null : this.getUserStatus().equals(other.getUserStatus()))
&& (this.getPhone() == null ? other.getPhone() == null : this.getPhone().equals(other.getPhone()))
&& (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
&& (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getUserName() == null) ? 0 : getUserName().hashCode());
result = prime * result + ((getAge() == null) ? 0 : getAge().hashCode());
result = prime * result + ((getEmail() == null) ? 0 : getEmail().hashCode());
result = prime * result + ((getUserAccount() == null) ? 0 : getUserAccount().hashCode());
result = prime * result + ((getAvatarUrl() == null) ? 0 : getAvatarUrl().hashCode());
result = prime * result + ((getGender() == null) ? 0 : getGender().hashCode());
result = prime * result + ((getUserPassword() == null) ? 0 : getUserPassword().hashCode());
result = prime * result + ((getUserStatus() == null) ? 0 : getUserStatus().hashCode());
result = prime * result + ((getPhone() == null) ? 0 : getPhone().hashCode());
result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", userName=").append(userName);
sb.append(", age=").append(age);
sb.append(", email=").append(email);
sb.append(", userAccount=").append(userAccount);
sb.append(", avatarUrl=").append(avatarUrl);
sb.append(", gender=").append(gender);
sb.append(", userPassword=").append(userPassword);
sb.append(", userStatus=").append(userStatus);
sb.append(", phone=").append(phone);
sb.append(", createTime=").append(createTime);
sb.append(", updateTime=").append(updateTime);
sb.append(", isDelete=").append(isDelete);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}
2.6 添加mapper
2.6.1 添加mapper包
2.6.2 启动类添加注解,扫描mapper包
2.6.3 添加mapper类 UserMapper
/**
* @author Giseryin
* @description 针对表【user(用户表)】的数据库操作Mapper
* @createDate 2022-11-10 10:31:23
* @Entity generator.domain.User
*/
public interface UserMapper extends BaseMapper<User> {
}
2.7 测试
2.7.1 添加依赖引入 单元测试工具Junit
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
2.7.2 编写测试类,查看测试结果
@SpringBootTest
@RunWith(SpringRunner.class)
public class SampleTest {
@Resource
private UserMapper userMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userMapper.selectList(null);
// Assert.assertEquals(5, userList.size());
userList.forEach(System.out::println);
}
}
打印成功
3.gdb数据入库
3.1 pom.xml 引入Geotools、GDAL依赖
添加仓库地址
<!-- 添加仓库地址 -->
<repositories>
<repository>
<id>osgeo</id>
<name>OSGeo Release Repository</name>
<url>https://repo.osgeo.org/repository/release/</url>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
</repositories>
<!--设置Geotools 版本号 -->
<properties>
<geotools.version>21.0</geotools.version>
</properties>
<!--geoTools-->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-jdbc</artifactId>
<version>${geotools.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-collections</artifactId>
<groupId>commons-collections</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-cql</artifactId>
<version>${geotools.version}</version>
</dependency>
<!--操作shape文件-->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>${geotools.version}</version>
</dependency>
<!--坐标系-->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools.jdbc</groupId>
<artifactId>gt-jdbc-postgis</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-jts-wrapper</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-opengis</artifactId>
<version>${geotools.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.osgeo/proj4j 用于投影坐标转化 -->
<dependency>
<groupId>org.osgeo</groupId>
<artifactId>proj4j</artifactId>
<version>0.1.0</version>
</dependency>
<!-- 引入gdal -->
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
<version>3.5.0</version>
</dependency>
3.2 GDAL环境安装
- 把release-xxxx/bin/目录及其子目录下的dll文件全部复制到你要使用的JDK版本%JAVA_HOME%/jre/bin/目录下
- 添加环境变量
注: 看变量值那个路径中有没有 proj.db 这个文件,如果没有说明GDAL不完整,需要重新下载或编绎
- 设置好环境变量后重启电脑
3.3 创建数据库连接实体类
import lombok.Data;
import java.io.Serializable;
@Data
public class DBconn implements Serializable {
/**
* 数据库类型
*/
private String dbtype;
/**
* ip
*/
private String host;
/**
* 端口
*/
private String port;
/**
* 模式
*/
private String schema;
/**
* 数据库名
*/
private String database;
/**
* 用户名
*/
private String user;
/**
* 密码
*/
private String passwd;
}
3.4 创建gis数据导入工具类 编写导入逻辑代码
- gdal注册及数据库配置
static {
gdal.AllRegister();
// 为了支持中文路径,请添加下面这句代码
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
}
//默认的geom字段
private static String GEOM_NAME = "geom";
//用于geotools创建数据库连接对象
private static Map DBMAP = new HashMap<String, Object>();
private static void setDBMAP(DBconn dBconn){
DBMAP.put("dbtype", dBconn.getDbtype());
DBMAP.put("host", dBconn.getHost());
DBMAP.put("port", dBconn.getPort());
DBMAP.put("schema", dBconn.getSchema());
DBMAP.put("database", dBconn.getDatabase());
DBMAP.put("user", dBconn.getUser());
DBMAP.put("passwd", dBconn.getPasswd());
}
- 获取gdal 的 gdb数据源对象,读取gdb数据
/**
* 根据文件路径获取gdb数据源对象
*
* @param filePath
* @return
*/
public static DataSource GetDataSourceByGdbFilePath(String filePath) {
Driver driver = ogr.GetDriverByName("OpenFileGDB");
DataSource dataSource = driver.Open(filePath, 0);
return dataSource;
}
注:gdal支持读取的数据源类型,参考 gdal 官网,如下:
- 创建字段
//创建字段
public static SimpleFeatureType creatSimpleFeatureType(Feature feature, String wkt, String tableName) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName(tableName);
try {
builder.setCRS(CRS.parseWKT(wkt));
} catch (FactoryException e) {
e.printStackTrace();
}
//添加矢量数据类型
GeometryJSON geometryJSON = new GeometryJSON();
try {
Geometry read = geometryJSON.read(feature.GetGeometryRef().ExportToJson());
Class geomClass = Class.forName("org.locationtech.jts.geom." + read.getGeometryType());
builder.add(GEOM_NAME, geomClass);
} catch (Exception e) {
e.printStackTrace();
}
//添加属性
for (int p = 0; p < feature.GetFieldCount(); p++) {
FieldDefn fieldDefn = feature.GetFieldDefnRef(p);
String name = fieldDefn.GetName().toLowerCase();
int fieldType = fieldDefn.GetFieldType();
String typeName = fieldDefn.GetFieldTypeName(fieldDefn.GetFieldType());
Class<?> clazz;
//根据GDAL的 FieldDefn 的类型,创建对应的 java数据类型
switch (typeName) {
case "String":
clazz = String.class;
break;
case "Real":
clazz = Double.class;
break;
default:
clazz = String.class;
break;
}
builder.add(name, clazz);
}
//build the type
final SimpleFeatureType LOCATION = builder.buildFeatureType();
return LOCATION;
}
- 创建表
//创建表
public static DataStore createTable(SimpleFeatureType simpleFeatureType) {
DataStore dataStore = null;
try {
dataStore = DataStoreFinder.getDataStore(DBMAP);
System.out.println(simpleFeatureType.getTypeName() + "test");
String[] typeNames = dataStore.getTypeNames();
List<String> collect = Arrays.stream(typeNames).filter(item -> item.equals(simpleFeatureType.getTypeName())).collect(Collectors.toList());
if (collect.isEmpty()) {
dataStore.createSchema(simpleFeatureType);//创建表
}
} catch (IOException e) {
e.printStackTrace();
}
return dataStore;
}
- 添加要素
/**
* 将GDBFeature 添加到 geotools 集合中
*
* @param features
* @param feature
* @param featureBuilder
*/
private static void addFeature(List<SimpleFeature> features, Feature feature, SimpleFeatureBuilder featureBuilder) {
//添加矢量数据
GeometryJSON geometryJSON = new GeometryJSON();
try {
featureBuilder.add(geometryJSON.read(feature.GetGeometryRef().ExportToJson()));
} catch (IOException e) {
throw new RuntimeException(e);
}
for (int p = 0; p < feature.GetFieldCount(); p++) {
String data = feature.GetFieldAsString(feature.GetFieldDefnRef(p).GetName());
featureBuilder.add(data);
}
SimpleFeature f = featureBuilder.buildFeature(null);
features.add(f);
}
- 导入
/**
* 将GDB数据导入到数据库中
* @param gdbFilePath gdb路径
* @param dBconn 数据库连接参数
*/
public static void importGdbToDatabase(String gdbFilePath, DBconn dBconn) {
setDBMAP(dBconn);
//获取gdb数据源
DataSource dataSource = GetDataSourceByGdbFilePath(gdbFilePath);
for (int i = 0; i < dataSource.GetLayerCount(); i++) {
Layer layer = dataSource.GetLayer(i);
String wkt = layer.GetSpatialRef().ExportToWkt();//坐标系信息
String tableName = layer.GetName();//获取表名称
SimpleFeatureType simpleFeatureType = null;
List<SimpleFeature> features = new ArrayList<>();
DataStore dataStore = null;
do {//获取图层下的要素
Feature feature = layer.GetNextFeature();
if (null == feature) {
break;
}
//创建表数据类型
if (simpleFeatureType == null) {
simpleFeatureType = creatSimpleFeatureType(feature, wkt, tableName);
dataStore = createTable(simpleFeatureType);
}
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(simpleFeatureType);
//将Feature对象添加到集合中去
addFeature(features, feature, featureBuilder);
} while (true);
Transaction t = new DefaultTransaction("add");
//将组装的数据插入数据库中
try {
SimpleFeatureCollection simpleFeatureCollection = DataUtilities.collection(new ListFeatureCollection(simpleFeatureType, features));
SimpleFeatureSource featureSource = dataStore.getFeatureSource(tableName);
if (featureSource instanceof SimpleFeatureStore) {
System.out.println("SimpleFeatureStore");
SimpleFeatureStore featureStore = (SimpleFeatureStore) dataStore.getFeatureSource(tableName);
featureStore.setTransaction(t);
featureStore.addFeatures(simpleFeatureCollection);
t.commit();
} else {
System.out.println("not SimpleFeatureStore");
}
} catch (IOException e) {
e.printStackTrace();
try {
t.rollback();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} finally {
try {
if (t != null) {
t.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
dataStore.dispose();
}
}
}
- 完整代码
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import org.geotools.data.*;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class GisUtils {
static {
gdal.AllRegister();
// 为了支持中文路径,请添加下面这句代码
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
}
//默认的geom字段
private static String GEOM_NAME = "geom";
//数据库连接参数
private static Map DBMAP = new HashMap<String, Object>() ;
private static void setDBMAP(DBconn dBconn) {
DBMAP.put("dbtype", dBconn.getDbtype());
DBMAP.put("host", dBconn.getHost());
DBMAP.put("port", dBconn.getPort());
DBMAP.put("schema", dBconn.getSchema());
DBMAP.put("database", dBconn.getDatabase());
DBMAP.put("user", dBconn.getUser());
DBMAP.put("passwd", dBconn.getPasswd());
}
/**
* 根据文件路径获取gdb数据源对象
* @param filePath
* @return
*/
public static DataSource GetDataSourceByGdbFilePath(String filePath) {
Driver driver = ogr.GetDriverByName("OpenFileGDB");
DataSource dataSource = driver.Open(filePath, 0);
return dataSource;
}
/**
* 根据文件路径获取 Shapefile数据源对象
* @param filePath
* @return
*/
public static DataSource GetDataSourceByShpFilePath(String filePath) {
Driver driver = ogr.GetDriverByName("ESRI Shapefile");
DataSource dataSource = driver.Open(filePath, 0);
return dataSource;
}
/**
* 将GDB数据导入到数据库中,只会导入GDB中的矢量数据,保留现存的空间坐标系信息
* @param gdbFilePath gdb路径
* @param dBconn 数据库连接参数
*/
public static void importGdbToDatabase(String gdbFilePath, DBconn dBconn) {
setDBMAP(dBconn);
DataSource dataSource = GetDataSourceByGdbFilePath(gdbFilePath);
for (int i = 0; i < dataSource.GetLayerCount(); i++) {
Layer layer = dataSource.GetLayer(i);
String wkt = layer.GetSpatialRef().ExportToWkt();//坐标系信息
String tableName = layer.GetName();//获取表名称
SimpleFeatureType simpleFeatureType = null;
List<SimpleFeature> features = new ArrayList<>();
DataStore dataStore = null;
do {//获取图层下的要素
Feature feature = layer.GetNextFeature();
if (null == feature) {
break;
}
//创建表数据类型
if (simpleFeatureType == null) {
simpleFeatureType = creatSimpleFeatureType(feature, wkt, tableName);
dataStore = createTable(simpleFeatureType);
}
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(simpleFeatureType);
//将Feature对象添加到集合中去
addFeature(features, feature, featureBuilder);
} while (true);
Transaction t = new DefaultTransaction("add");
//将组装的数据插入数据库中
try {
SimpleFeatureCollection simpleFeatureCollection = DataUtilities.collection(new ListFeatureCollection(simpleFeatureType, features));
SimpleFeatureSource featureSource = dataStore.getFeatureSource(tableName);
if (featureSource instanceof SimpleFeatureStore) {
System.out.println("SimpleFeatureStore");
SimpleFeatureStore featureStore = (SimpleFeatureStore) dataStore.getFeatureSource(tableName);
featureStore.setTransaction(t);
featureStore.addFeatures(simpleFeatureCollection);
t.commit();
} else {
System.out.println("not SimpleFeatureStore");
}
} catch (IOException e) {
e.printStackTrace();
try {
t.rollback();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} finally {
try {
if (t != null) {
t.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
dataStore.dispose();
}
}
}
public static void importShpToDatabase(String shpFilePath, DBconn dBconn) {
setDBMAP(dBconn);
DataSource dataSource = GetDataSourceByShpFilePath(shpFilePath);
for (int i = 0; i < dataSource.GetLayerCount(); i++) {
Layer layer = dataSource.GetLayer(i);
String wkt = layer.GetSpatialRef().ExportToWkt();//坐标系信息
String tableName = layer.GetName();//获取表名称
SimpleFeatureType simpleFeatureType = null;
List<SimpleFeature> features = new ArrayList<>();
DataStore dataStore = null;
do {//获取图层下的要素
Feature feature = layer.GetNextFeature();
if (null == feature) {
break;
}
//创建表数据类型
if (simpleFeatureType == null) {
simpleFeatureType = creatSimpleFeatureType(feature, wkt, tableName);
dataStore = createTable(simpleFeatureType);
}
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(simpleFeatureType);
//将Feature对象添加到集合中去
addFeature(features, feature, featureBuilder);
} while (true);
Transaction t = new DefaultTransaction("add");
;
//将组装的数据插入数据库中
try {
SimpleFeatureCollection simpleFeatureCollection = DataUtilities.collection(new ListFeatureCollection(simpleFeatureType, features));
SimpleFeatureSource featureSource = dataStore.getFeatureSource(tableName);
if (featureSource instanceof SimpleFeatureStore) {
System.out.println("SimpleFeatureStore");
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
featureStore.setTransaction(t);
featureStore.addFeatures(simpleFeatureCollection);
t.commit();
} else {
System.out.println("not SimpleFeatureStore");
}
} catch (IOException e) {
e.printStackTrace();
try {
t.rollback();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} finally {
try {
if (t != null) t.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
dataStore.dispose();
}
}
}
/**
* 将GDBFeature 添加到 geotools 集合中
*
* @param features
* @param feature
* @param featureBuilder
*/
private static void addFeature(List<SimpleFeature> features, Feature feature, SimpleFeatureBuilder featureBuilder) {
//添加矢量数据
GeometryJSON geometryJSON = new GeometryJSON();
try {
featureBuilder.add(geometryJSON.read(feature.GetGeometryRef().ExportToJson()));
} catch (IOException e) {
throw new RuntimeException(e);
}
for (int p = 0; p < feature.GetFieldCount(); p++) {
String data = feature.GetFieldAsString(feature.GetFieldDefnRef(p).GetName());
featureBuilder.add(data);
}
SimpleFeature f = featureBuilder.buildFeature(null);
features.add(f);
}
//创建字段
public static SimpleFeatureType creatSimpleFeatureType(Feature feature, String wkt, String tableName) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName(tableName);
try {
builder.setCRS(CRS.parseWKT(wkt));
} catch (FactoryException e) {
e.printStackTrace();
}
//添加矢量数据类型
GeometryJSON geometryJSON = new GeometryJSON();
try {
Geometry read = geometryJSON.read(feature.GetGeometryRef().ExportToJson());
Class geomClass = Class.forName("org.locationtech.jts.geom." + read.getGeometryType());
builder.add(GEOM_NAME, geomClass);
} catch (Exception e) {
e.printStackTrace();
}
//添加属性
for (int p = 0; p < feature.GetFieldCount(); p++) {
FieldDefn fieldDefn = feature.GetFieldDefnRef(p);
String name = fieldDefn.GetName().toLowerCase();
int fieldType = fieldDefn.GetFieldType();
String typeName = fieldDefn.GetFieldTypeName(fieldDefn.GetFieldType());
Class<?> clazz;
switch (typeName) {
case "String":
clazz = String.class;
break;
case "Real":
clazz = Double.class;
break;
default:
clazz = String.class;
break;
}
builder.add(name, clazz);
}
//build the type
final SimpleFeatureType LOCATION = builder.buildFeatureType();
return LOCATION;
}
//创建表
public static DataStore createTable(SimpleFeatureType simpleFeatureType) {
DataStore dataStore = null;
try {
dataStore = DataStoreFinder.getDataStore(DBMAP);
System.out.println(simpleFeatureType.getTypeName() + "test");
String[] typeNames = dataStore.getTypeNames();
List<String> collect = Arrays.stream(typeNames).filter(item -> item.equals(simpleFeatureType.getTypeName())).collect(Collectors.toList());
if (collect.isEmpty()) {
dataStore.createSchema(simpleFeatureType);//创建表
}
} catch (IOException e) {
e.printStackTrace();
}
return dataStore;
}
}
3.5 测试gdb数据入库
import org.junit.Test;
@Test
public void gdalTest() throws IOException {
DBconn dBconn=new DBconn();
dBconn.setDbtype("postgis");
dBconn.setHost("localhost");
dBconn.setPort("5432");
dBconn.setSchema("sde");
dBconn.setDatabase("postgis_21_sample");
dBconn.setUser("postgres");
dBconn.setPasswd("Giseryin");
GisUtils.importGdbToDatabase("E:\hygt\5-data\1-图形\test.gdb",dBconn);
}
4.发布样式
4.1 使用QGIS生成样式并导出
- 添加图层
- 打开图层属性
- 选择按名称对要素分类
4.添加文字标注
- 导出样式
4.2 geoserver发布样式
- 添加样式
- 导入样式
- 验证保存
5. 发布geoserver服务
5.1 引入所需依赖,调用geoserver接口
<!-- 添加仓库地址 -->
<repositories>
<repository>
<id>GeoSolutions</id>
<url>https://maven.geo-solutions.it/</url>
</repository>
</repositories>
<!--添加依赖 -->
<dependency>
<groupId>it.geosolutions</groupId>
<artifactId>geoserver-manager</artifactId>
<version>1.7.0</version>
</dependency>
5.2 创建Geoserver 连接实体类
@Data
public class GeoserverConn implements Serializable {
private static final long serialVersionUID = 7143188313880619178L;
private String url;
private String username;
private String password;
}
5.3 发布postgis数据源的图层
/**
* 发布 postgis 表到 geoserver
* @param conn geoserver连接参数
* @param dBconn 数据库连接参数
* @param tableName 表名
* @param workspace 工作空间
* @param store 存储名
* @param srs 坐标系,eg: “EPSG:4490”
* @throws MalformedURLException
*/
public static void publishPostgisData(GeoserverConn conn, DBconn dBconn,String tableName,String workspace,String store,String srs) throws MalformedURLException {
//判断工作空间是否存在,不存在则创建
URL u=new URL(conn.getUrl());
GeoServerRESTManager manager=new GeoServerRESTManager(u,conn.getUsername(),conn.getPassword());
GeoServerRESTPublisher publisher=manager.getPublisher();
List<String> workspaces=manager.getReader().getWorkspaceNames();
if(!workspaces.contains(workspace)){
boolean createws = publisher.createWorkspace(workspace);
System.out.println("create ws:"+createws);
} else {
System.out.println("workspace 已经存在了,ws:"+workspace);
}
//判断数据存储(datastore)是否已经存在,不存在则创建
RESTDataStore restStore=manager.getReader().getDatastore(workspace,store);
if(restStore == null){
GSPostGISDatastoreEncoder encoder = new GSPostGISDatastoreEncoder(store);
encoder.setHost(dBconn.getHost());
encoder.setPort(Integer.parseInt(dBconn.getPort()));
encoder.setUser(dBconn.getUser());
encoder.setPassword(dBconn.getPasswd());
encoder.setDatabase(dBconn.getDatabase());
encoder.setSchema(dBconn.getSchema());
encoder.setConnectionTimeout(500);
encoder.setMaxConnections(20);
encoder.setMinConnections(1);
encoder.setExposePrimaryKeys(true);
boolean createStore=manager.getStoreManager().create(workspace,encoder);
System.out.println("create store:"+createStore);
}else {
System.out.println("数据存储已经存在了,store:"+store);
}
//判断图层是否已经存在,不存在则创建发布
RESTLayer layer=manager.getReader().getLayer(workspace,tableName);
if(layer==null){
GSFeatureTypeEncoder pds = new GSFeatureTypeEncoder();
pds.setTitle(tableName);
pds.setName(tableName);
pds.setSRS(srs);
GSLayerEncoder layerEncoder = new GSLayerEncoder();
//查询是否有图层同名的样式,有则设为图层的默认样式
boolean existsStyle = manager.getStyleManager().existsStyle(tableName);
if (existsStyle) {
layerEncoder.setDefaultStyle(tableName);
layerEncoder.addStyle(tableName);
}
boolean publish=manager.getPublisher().publishDBLayer(workspace,store,pds,layerEncoder);
System.out.println("publish:"+publish);
}else {
System.out.println("表已经发布过了,table:"+tableName);
}
}
5.4 发布图层组
/**
* 发布 图层组 到 geoserver
* @param conn
* @param layerNames
* @param groupName
* @throws MalformedURLException
*/
public static void publishLayerGroups(GeoserverConn conn,List<String>layerNames,String groupName) throws MalformedURLException {
URL u = new URL(conn.getUrl());
GeoServerRESTManager manager = new GeoServerRESTManager(u, conn.getUsername(), conn.getPassword());
GeoServerRESTPublisher publisher=manager.getPublisher();
RESTLayerGroup layerGroup = manager.getReader().getLayerGroup(groupName);
if(layerGroup ==null){
GSLayerGroupEncoder gsLayerGroupEncoder=new GSLayerGroupEncoder();
//添加图层
for (int i = layerNames.size() - 1; i >= 0; i--) {
gsLayerGroupEncoder.addLayer(layerNames.get(i));
}
//发布服务
boolean create = publisher.createLayerGroup(groupName, gsLayerGroupEncoder);
}else{
System.out.println("图层组已存在:"+groupName);
}
}
6. gdb入库及图层组发布
6.1 GIS服务接口
public interface GisService {
ResponseResult publishLayergroup() throws IOException;
}
6.2 接口实现类
@Service
public class GisServiceImpl implements GisService {
@Override
public ResponseResult publishLayergroup() throws IOException {
//数据库连接参数
DBconn dBconn=new DBconn();
dBconn.setDbtype("postgis");
dBconn.setHost("localhost");
dBconn.setPort("5432");
dBconn.setSchema("sde");
dBconn.setDatabase("postgis_21_sample");
dBconn.setUser("postgres");
dBconn.setPasswd("Giseryin");
//geoserver连接参数
GeoserverConn gsConn=new GeoserverConn();
gsConn.setUrl("http://localhost:8787/geoserver");
gsConn.setUsername("admin");
gsConn.setPassword("geoserver");
//gdb路径
GisUtils.importGdbToDatabase("E:\hygt\5-data\1-图形\test.gdb",dBconn);
DataSource dataSource = GisUtils.GetDataSourceByGdbFilePath("E:\hygt\5-data\1-图形\test.gdb");
//导入数据库的表名列表
List<String> tableNames=new ArrayList<>();
//geoserver图层名
List<String>layerNames=new ArrayList<>();
//geoserver 要发布的工作空间名
String workspace="publish-test";
//geoserver 要发布的存储名称
String store="pgstore1";
//geoserver 要发布的图层组名称
String groupName= "group1";
for (int i = 0; i < dataSource.GetLayerCount(); i++) {
Layer layer = dataSource.GetLayer(i);
//获得图层的空间参考
SpatialReference spatialReference = layer.GetSpatialRef();
//获得图层的epsg 数字编码
String epsgCode = spatialReference.GetAttrValue("AUTHORITY", 1);
String tableName = layer.GetName();//获取gbb图层名称
tableNames.add(tableName);
String gsLayerNamme=workspace+":"+tableName;
layerNames.add(gsLayerNamme);
String epsg="EPSG:"+epsgCode;
//发布图层
GeoServerUtils.publishPostgisData(gsConn,dBconn,tableName,workspace,store,epsg);
}
//发布图层组
GeoServerUtils.publishLayerGroups(gsConn,layerNames,groupName);
return ResponseResult.success();
}
}
7. mybatis-plus处理Geometry字段类型
- pom.xml 引入postgis-jdbc依赖
<!--编(解)码postgresql写入(或读取)的Geometry-->
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2.5.0</version>
</dependency>
- 定义 mybatis的TypeHandler,实现jts的Geometry Java类型 转成能够被postgis-jdbc的Geometry JDBC类型
public abstract class AbstractGeometryTypeHandler<T extends Geometry> extends BaseTypeHandler<T> {
/**
* WKTReader非线程安全
*/
private static final ThreadLocal<WKTReader> READER_POOL = ThreadLocal.withInitial(WKTReader::new);
/**
* WKTWriter非线程安全
*/
private static final ThreadLocal<WKTWriter> WRITER_POOL = ThreadLocal.withInitial(WKTWriter::new);
/**
* 与数据库中几何列的空间坐标系保持一致,要不然写入会报错
*/
private static final int SRID_IN_DB = 4546;
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
PGgeometry pGgeometry = new PGgeometry(WRITER_POOL.get().write(parameter));
org.postgis.Geometry geometry = pGgeometry.getGeometry();
geometry.setSrid(SRID_IN_DB);
ps.setObject(i, pGgeometry);
}
@SneakyThrows
@Override
public T getNullableResult(ResultSet rs, String columnName) {
String string = rs.getString(columnName);
return getResult(string);
}
@SneakyThrows
@Override
public T getNullableResult(ResultSet rs, int columnIndex) {
String string = rs.getString(columnIndex);
return getResult(string);
}
@SneakyThrows
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) {
String string = cs.getString(columnIndex);
return getResult(string);
}
private T getResult(String string) throws SQLException {
if(string == null){
return null;
}
PGgeometry pGgeometry = new PGgeometry(string);
String s = pGgeometry.toString();
String target = String.format("SRID=%s;", SRID_IN_DB);
String wkt = s.replace(target, "");
try {
return (T) READER_POOL.get().read(wkt);
} catch (Exception e) {
throw new RuntimeException("解析wkt失败:" + wkt, e);
}
}
}
public class GeometryTypeHandler extends AbstractGeometryTypeHandler<Geometry>{
}
- 实体类的几何类型,添加
TableField
注解,定义Java类型和JDBC类型的转换器
@TableField(value = "geom",typeHandler = GeometryTypeHandler.class)
private Geometry geom;
- mybatis-plus 的xml配置文件定义字段的类型转换器
- service实现层读取接收到的geojson转为 jts 的geometry类型直接保存
@Override
public ResponseResult test(Map<String, Object> geojson) throws IOException {
System.out.println(geojson);
Cunju cunju=new Cunju();
GeometryJSON gJson=new GeometryJSON();
String jsonString = JSONObject.toJSONString(geojson);
StringReader reader=new StringReader(jsonString);
Geometry geometry = gJson.read(reader);
cunju.setFid(new BigInteger("1001"));
cunju.setGeom(geometry);
cunju.setObjectid(1200D);
cunju.setShapeLeng(1200D);
cunju.setName("test3");
cunju.setShapeLe1(1200D);
cunju.setShapeArea(1200D);
cunjuMapper.insert(cunju);
return ResponseResult.success(geojson);
}