前言
geoserver默认是支持postgis,postgis是postgresql数据库插件,在postgresql安装上插件即可;
sqlserver默认是不支持的,需要去geoserver官网找到对应版本下载插件,放到安装目录下,具体操作可参考另一篇文章
1,先确定需求
- 写一个通用方法,能同时支持发布sqlserver和postgresql中的空间表;
- 可同时发布同一个数据库下的多张表;
- 可指定发布到哪个geoserver;
- 同一个库多表发布反馈每一张表发布结果。
2,pom引入必要的依赖
<dependency>
<groupId>it.geosolutions</groupId>
<artifactId>geoserver-manager</artifactId>
<version>1.7.0</version>
</dependency>
3,建立三个对象
- 前端请求对象
public class PublicTablePO {
@ApiModelProperty(value = "数据库id")
@NotEmpty(message = "数据库id不能为空")
private String dbId;
@ApiModelProperty(value = "表名")
@NotEmpty(message = "数据源不能为空")
private List<String> table;
@ApiModelProperty(value = "地图配置id")
@NotEmpty(message = "地图配置不能为空")
private String config;
}
- 数据库对象
public class ExternalDataBaseDO {
private String id;
private String userName;
private String passWord;
private String host;
private String port;
private String databaseType;
。。。
}
- geoserver配置对象
public class MapDispositionDO {
private String id;
private String host;
private String name;
private String passwd;
。。。
}
4,实现主类
/**
* 发布指定的空间表
*
* @param tablePO
* @return
*/
@Override
public Result<List<String>> publishTable(PublicTablePO tablePO) {
ExternalDataBaseDO dataBaseDO = 根据id查询数据库对象
MapDispositionDO mapDispositionDO = 根据地图配置id查询geoserver配置
//创建数据存储
boolean createStoreState = false;
try {
createStoreState = GeoServerUtil.createDBStore(mapDispositionDO, dataBaseDO);
} catch (Exception e) {
log.error("创建数据库存储异常:{}", e.getMessage());
throw new MayException(CodeMsg.ERROR_MAP_STOREERROR);
}
if (!createStoreState) {
throw new MayException(CodeMsg.ERROR_MAP_STOREERROR);
}
//遍历发布每张表
List<String> resList = new ArrayList<>(tablePO.getTable().size());
for (String table : tablePO.getTable()) {
boolean res = GeoServerUtil.publishDBTableLayer(mapDispositionDO, table, dataBaseDO);
//更新缓存中的发布地址 //http://xxxxxxx:8991/geoserver/test/wms@test@XX
Update update = new Update();
if (res) {
resList.add(table + " 发布成功");
update.set("publish", mapDispositionDO.getHost() + "/test/wms@test@" + table);
} else {
resList.add(table + " 发布失败");
update.set("publish", null);
}
//TODO 更新每张表的发布地址
}
return Result.sucess(resList);
}
5,创建数据存储
根据数据类型分别创建DatastoreEncoder对象
/**
* 创建数据库数据存储
*
* @param dispositionDO
* @param dataBase
* @throws MalformedURLException
*/
public static boolean createDBStore(MapDispositionDO dispositionDO, ExternalDataBaseDO dataBase) throws Exception {
String ws = "test";
URL restURL = new URL(dispositionDO.getHost());
//获取管理对象
GeoServerRESTManager manager = new GeoServerRESTManager(restURL, dispositionDO.getName(), dispositionDO.getPasswd());
//获取发布对象
GeoServerRESTPublisher publisher = manager.getPublisher();
//获取所有的工作空间名称
List<String> workspaces = manager.getReader().getWorkspaceNames();
//判断工作空间是否存在
if (!workspaces.contains("test")) {
//创建一个新的工作空间
boolean createws = publisher.createWorkspace(ws);
log.info("创建工作空间 : {}", createws);
} else {
log.info("工作空间已经存在了: {}", ws);
}
boolean publishState;
if (dataBase.getDatabaseType().equalsIgnoreCase("mssql")) {
GSSqlServerDatastoreEncoder store = new GSSqlServerDatastoreEncoder(dataBase.getDataBaseName());
store.setDatabase(dataBase.getDataBaseName());
store.setHost(dataBase.getHost());
store.setPort(Integer.parseInt(dataBase.getPort()));
store.setUser(dataBase.getUserName());
store.setPassword(dataBase.getPassWord());
publishState = manager.getStoreManager().create(ws, store);
} else {
GSPostGISDatastoreEncoder store = new GSPostGISDatastoreEncoder(dataBase.getDataBaseName());
store.setDatabase(dataBase.getDataBaseName());
store.setHost(dataBase.getHost());
store.setPort(Integer.parseInt(dataBase.getPort()));
store.setUser(dataBase.getUserName());
store.setPassword(dataBase.getPassWord());
publishState = manager.getStoreManager().create(ws, store);
}
log.info("创建数据存储仓库 : {}:{}", dataBase.getDataBaseName(), publishState);
return publishState;
}
其中GSPostGISDatastoreEncoder是geoserver的jar包中已有的,GSSqlServerDatastoreEncoder没有可以直接仿制GSPostGISDatastoreEncoder手写一个,主要是类型不一样
this.setType("sqlserver");
this.setDatabaseType("sqlserver");
6,创建空间表图层
到这一步就不区分这个表是sqlserver还是postgresql,因为数据存储一步已经确定了数据库类型
/**
* 发布数据库中的表
* 工作空间相同test,数据存储使用数据库名,图层使用表名
*
* @throws IOException
*/
public static boolean publishDBTableLayer(MapDispositionDO dispositionDO, String tale_name, ExternalDataBaseDO dataBase) {
//TODO 可配置默认存储空间
String ws = "test";
String srs = "EPSG:4490";
try {
URL restURL = new URL(dispositionDO.getHost());
//获取管理对象
GeoServerRESTManager manager = new GeoServerRESTManager(restURL, dispositionDO.getName(), dispositionDO.getPasswd());
//判断图层是否已经存在,不存在则创建并发布
GeoServerRESTReader reader = new GeoServerRESTReader(restURL, dispositionDO.getName(), dispositionDO.getPasswd());
RESTLayer layer = reader.getLayer(ws, tale_name);
if (layer != null) {
log.info("mongodb图层已经发布过了 {}:{} ", dataBase.getDataBaseName(), tale_name);
//通过查询图层坐标信息检查是否发布正常
LayerInfoVO vo = getLayerFeatureInfo(dispositionDO, tale_name);
if (vo != null) {
return true;
}
return false;
}
GSFeatureTypeEncoder pds = new GSFeatureTypeEncoder();
pds.setTitle(tale_name);
pds.setName(tale_name);
pds.setSRS(srs);
GSLayerEncoder layerEncoder = new GSLayerEncoder();
layerEncoder.setEnabled(true);
boolean publish = manager.getPublisher().publishDBLayer(ws, dataBase.getDataBaseName(), pds, layerEncoder);
log.info("发布空间表图层 : {},{}", tale_name, publish);
return publish;
} catch (MalformedURLException e) {
log.error("发布空间表失败:", e);
return false;
}
}