1. 引言
geoserver 是一个基于 java 的开源地理信息服务器,用于发布、共享和编辑地图数据。在实际项目中,我们往往需要将 geoserver 的能力嵌入到自己的 springboot 应用中,实现地图服务的自动化发布与管理。本文将介绍如何在 springboot 项目中集成 geoserver 源码,并实现地图服务的发布。
2. 集成方式概述
springboot 集成 geoserver 主要有两种方式:
- rest api 方式:通过调用 geoserver 提供的 restful 接口进行数据发布和管理,适合与独立部署的 geoserver 服务交互。
- 源码嵌入方式:将 geoserver 的核心模块作为依赖引入 springboot 项目,在应用内部直接调用 geoserver 的 api 完成发布,适合深度定制和一体化部署。
本文重点介绍第二种方式,即源码集成。
3. 环境准备
在开始之前,需要准备以下环境:
- jdk 1.8 或以上版本
- maven 3.6 或以上版本
- springboot 2.x 或 3.x 项目
- geoserver 源码(建议使用 2.19.x 或 2.20.x 稳定版本)
4. 引入 geoserver 依赖
在 springboot 项目的 pom.xml 中引入 geoserver 相关依赖。geoserver 的模块较多,这里只引入发布所需的核心模块:
<dependency>
<groupid>org.geoserver</groupid>
<artifactid>gs-main</artifactid>
<version>2.20.0</version>
</dependency>
<dependency>
<groupid>org.geoserver</groupid>
<artifactid>gs-wms</artifactid>
<version>2.20.0</version>
</dependency>
<dependency>
<groupid>org.geoserver</groupid>
<artifactid>gs-wfs</artifactid>
<version>2.20.0</version>
</dependency>
<dependency>
<groupid>org.geoserver</groupid>
<artifactid>gs-rest</artifactid>
<version>2.20.0</version>
</dependency>注意:geoserver 的依赖较多,如果遇到依赖冲突,可以通过排除传递依赖或调整版本解决。
5. 初始化 geoserver 上下文
geoserver 的运行依赖 spring 上下文。在 springboot 中,我们需要手动初始化 geoserver 的上下文。可以创建一个配置类来完成初始化:
import org.geoserver.config.geoserver;
import org.geoserver.config.geoserverinfo;
import org.geoserver.config.impl.geoserverimpl;
import org.geoserver.platform.geoserverresourceloader;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import java.io.file;
@configuration
public class geoserverconfig {
@bean
public geoserver geoserver() throws exception {
// 指定数据目录
file datadir = new file("./geoserver_data");
if (!datadir.exists()) {
datadir.mkdirs();
}
geoserverresourceloader resourceloader = new geoserverresourceloader(datadir);
geoserver geoserver = new geoserverimpl();
geoserver.setresourceloader(resourceloader);
geoserverinfo info = geoserver.getfactory().createglobal();
info.setid("global");
geoserver.setglobal(info);
return geoserver;
}
}6. 实现数据发布
初始化完成后,就可以通过 geoserver 的 api 实现数据发布。下面以发布一个 shapefile 为例:
import org.geoserver.catalog.catalog;
import org.geoserver.catalog.datastoreinfo;
import org.geoserver.catalog.layerinfo;
import org.geoserver.catalog.resourceinfo;
import org.geoserver.catalog.workspaceinfo;
import org.geoserver.catalog.impl.catalogimpl;
import org.geoserver.config.geoserver;
import org.springframework.stereotype.service;
import java.io.file;
@service
public class layerpublishservice {
private final geoserver geoserver;
public layerpublishservice(geoserver geoserver) {
this.geoserver = geoserver;
}
public void publishshapefile(string workspacename, string storename, string layername, file shapefile) throws exception {
catalog catalog = geoserver.getcatalog();
// 创建工作区
workspaceinfo workspace = catalog.getworkspacebyname(workspacename);
if (workspace == null) {
workspace = catalog.getfactory().createworkspace();
workspace.setname(workspacename);
catalog.add(workspace);
}
// 创建数据存储
datastoreinfo store = catalog.getdatastorebyname(workspacename, storename);
if (store == null) {
store = catalog.getfactory().createdatastore();
store.setname(storename);
store.setworkspace(workspace);
store.getconnectionparameters().put("url", "file:" + shapefile.getabsolutepath());
store.getconnectionparameters().put("namespace", workspacename);
catalog.add(store);
}
// 创建图层
resourceinfo resource = catalog.getresourcebyname(workspacename, layername, resourceinfo.class);
if (resource == null) {
resource = catalog.getfactory().createfeaturetype();
resource.setname(layername);
resource.setstore(store);
resource.setnamespace(workspace);
catalog.add(resource);
}
layerinfo layer = catalog.getlayerbyname(layername);
if (layer == null) {
layer = catalog.getfactory().createlayer();
layer.setresource(resource);
layer.setname(layername);
catalog.add(layer);
}
}
}7. 发布 postgis 数据源
除了 shapefile,实际项目中更常用的是发布 postgis 数据库中的数据。发布 postgis 数据源的代码如下:
import org.geoserver.catalog.datastoreinfo;
import org.geoserver.catalog.workspaceinfo;
import org.geoserver.config.geoserver;
import org.springframework.stereotype.service;
import java.util.hashmap;
import java.util.map;
@service
public class postgispublishservice {
private final geoserver geoserver;
public postgispublishservice(geoserver geoserver) {
this.geoserver = geoserver;
}
public void publishpostgis(string workspacename, string storename, string host, int port,
string database, string user, string password) throws exception {
var catalog = geoserver.getcatalog();
// 创建工作区
workspaceinfo workspace = catalog.getworkspacebyname(workspacename);
if (workspace == null) {
workspace = catalog.getfactory().createworkspace();
workspace.setname(workspacename);
catalog.add(workspace);
}
// 创建 postgis 数据存储
datastoreinfo store = catalog.getdatastorebyname(workspacename, storename);
if (store == null) {
store = catalog.getfactory().createdatastore();
store.setname(storename);
store.setworkspace(workspace);
map<string, string> params = new hashmap<>();
params.put("dbtype", "postgis");
params.put("host", host);
params.put("port", string.valueof(port));
params.put("database", database);
params.put("user", user);
params.put("passwd", password);
store.getconnectionparameters().putall(params);
catalog.add(store);
}
}
}8. 通过 rest api 发布(备选方案)
如果不想深度耦合 geoserver 源码,也可以使用 rest api 方式。这种方式需要先启动一个独立的 geoserver 服务,然后通过 http 请求进行发布:
import org.springframework.http.*;
import org.springframework.stereotype.service;
import org.springframework.web.client.resttemplate;
@service
public class geoserverrestservice {
private final resttemplate resttemplate = new resttemplate();
private static final string base_url = "http://localhost:8080/geoserver/rest";
public void createworkspace(string workspacename, string username, string password) {
string url = base_url + "/workspaces";
string body = "<workspace><name>" + workspacename + "</name></workspace>";
httpheaders headers = new httpheaders();
headers.setcontenttype(mediatype.application_xml);
headers.setbasicauth(username, password);
httpentity<string> entity = new httpentity<>(body, headers);
resttemplate.exchange(url, httpmethod.post, entity, string.class);
}
public void publishlayer(string workspacename, string storename, string layername,
string username, string password) {
string url = base_url + "/workspaces/" + workspacename + "/datastores/" + storename + "/featuretypes";
string body = "<featuretype><name>" + layername + "</name></featuretype>";
httpheaders headers = new httpheaders();
headers.setcontenttype(mediatype.application_xml);
headers.setbasicauth(username, password);
httpentity<string> entity = new httpentity<>(body, headers);
resttemplate.exchange(url, httpmethod.post, entity, string.class);
}
}9. 常见问题与注意事项
- 依赖冲突:geoserver 依赖的库版本可能与 springboot 冲突,建议使用 maven 的
dependencymanagement统一管理版本。 - 数据目录权限:geoserver 需要读写数据目录,部署时需确保应用有相应权限。
- 内存配置:geoserver 对内存要求较高,建议在启动参数中适当调大 jvm 堆内存。
- 中文乱码:发布中文数据时,注意设置正确的字符编码。
10. 总结
本文介绍了在 springboot 项目中集成 geoserver 源码并实现地图服务发布的完整流程,包括依赖引入、上下文初始化、shapefile 发布、postgis 数据源发布以及 rest api 备选方案。源码嵌入方式适合深度定制场景,而 rest api 方式更适合解耦部署。开发者可以根据实际业务需求选择合适的集成方式。
以上就是springboot项目集成geoserver源码实现地图服务发布的详细内容,更多关于springboot geoserver地图服务发布的资料请关注代码网其它相关文章!
发表评论