当前位置: 首页 > news >正文

对于geoserver发布数据后的开发应用

对于geoserver发布数据后的开发应用


文章目录

  • 对于geoserver发布数据后的开发应用
    • @[TOC](文章目录)
  • 前言
  • 一、geosever管理地理数据的后端实用方法
    • 后端进行登录geoserver并且发布一个矢量数据
      • 前置的domain数据准备
      • 后端内容
  • 总结

前言

首先,本篇文章仅进行技术分享,某些数据并不会公开。
目前其实还不太会用arcgis发布某些图层数据,但是知道怎么用。


一、geosever管理地理数据的后端实用方法

由于目前工作的局限性,之前的代码都是用geoserver来进行保存的,所以需要构建一个强大的后端处理技术来保证与前端交互的时候,某些服务能服务于非Gis人员。
我的geosever是由docker进行安装的 ,具体可以看下面的文章,用windows直接按照也是可以的,只是我好不容易装好docker不方便我用的话就很累。
docker搭建geoserver
启动下面的镜像
在这里插入图片描述
访问本地的8090端口,正常登录即可
在这里插入图片描述
查看一下数据预览
在这里插入图片描述
在这里插入图片描述
接下来要写一下仿照geoserver进行登录的操作,待会我去把这个遥感数据删除,用后端进行管理geoserver的发布。

后端进行登录geoserver并且发布一个矢量数据

因为我要写一个模块,专门用于发布矢量数据并且使用cesium去将这个数据的wms服务给请求下来加载到图层上去。
大致思路是mysql用于持久化系统数据,pgsql对于每一个shp数据进行创建表,用于存贮上传shp数据里的dbf表数据,至于为什么要存这玩意,其实是因为要导出为Excel表方便统计,并且做成功能。
首先是思考的是手动操作的流程,登录geosever,然后得到目标文件的文件路径,发布数据选择样式,发布成功后,获取它的wms服务链接,存到mysql数据库里,得到它的dbf数据,存到pgsql里,下面是这些步骤的代码。

前置的domain数据准备

先写一个实体类先

import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import java.util.Date;/*** @Author chuxuan* @Date 2025/5/23* @Description TODO:这是用于shp数据管理的实体类 */
@Data
public class ShpDetail {private static final long serialVersionUID = 1L;/*** 主键id*/private Long id;/*** shp名称*/@Excel(name = "shp名称")private String name;/*** shp文件名称*/@Excel(name = "shp文件名称")private String fileName;/*** geoserver的工作区*/@Excel(name = "geoserver的工作区")private String geoserverWorkArea;/*** 数据库表名*/@Excel(name = "数据库表名")private String tableName;/*** 数据库字段名,逗号分割*/@Excel(name = "数据库字段名,逗号分割")private String tableField;/*** 数据时间*/@JsonFormat(pattern = "yyyy-MM-dd")@Excel(name = "数据时间", width = 30, dateFormat = "yyyy-MM-dd")private Date dataTime;/*** 缩略图*/@Excel(name = "缩略图")private String thumbUrl;/*** shp坐标编码*/@Excel(name = "shp坐标编码")private String srs;/*** wms的url*/@Excel(name = "wms的url")private String wmsUrl;/*** 图层名称*/@Excel(name = "图层名称")private String layerName;/*** 图层样式名称*/@Excel(name = "图层样式名称")private String sldName;/*** 边界*/@Excel(name = "边界")private String box;/*** 图例id*/@Excel(name = "图例id")private Long legendId;/*** 删除标志(0代表存在 2代表删除)*/private String delFlag;/*** 中心点纬度*/@Excel(name = "中心点纬度")private String viewCenterLat;/*** 中心点经度*/@Excel(name = "中心点经度")private String viewCenterLong;/*** 级别,默认11*/@Excel(name = "级别,默认11")private Integer viewZoom;/*** 备注*/@Excel(name = "备注")private String remark;/*** 创建者*/private String createBy;/*** 创建时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;/*** 更新者*/private String updateBy;/*** 更新时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date updateTime;/*** 是否包含必要字段*/private Boolean needfulStatus;/*** 特别排除的字段,有些字段无法保存的需要排除掉*/private String excludeFields;/*** 图例名曾*/@TableField(exist = false)private String legendName;
}

shp数据添加的AddDTO,作用是在我们上传的时候将发布图层的style等参数都放进去,以及一个简单是shp数据。
由此可以设计DTO

import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import java.util.Date;
import java.util.List;
import lombok.Data;
/*** @Author chuxuan* @Date 2025/5/23* @Description TODO:这是用于shp数据上传的DTO类 */
@Data
public class ShpDetailAddDTO {private static final long serialVersionUID = 1L;/** 主键id */@Excel(name = "主键id")private Long id;/** shp文件名称 */@Excel(name = "shp文件名称")private String fileName;/** shp中文简称 */@Excel(name = "shp中文简称")private String name;/** 数据时间 */@JsonFormat(pattern = "yyyy-MM-dd")@Excel(name = "数据时间", width = 30, dateFormat = "yyyy-MM-dd")private Date dataTime;/** 数据库表名 */@Excel(name = "数据库表名")private String tableName;/** 图层样式名称 */@Excel(name = "图层样式名称")private String sldName;/** 图例id */@Excel(name = "图例id")private Long legendId;/** geoserver的工作区 */@Excel(name = "geoserver的工作区")private String geoserverWorkArea;/** 图层名称 */@Excel(name = "图层名称")private String layerName;/** 级别,默认11 */@Excel(name = "级别,默认11")private Integer viewZoom;/** 备注 */@Excel(name = "备注")private String remark;/** 中心点纬度 */@Excel(name = "中心点纬度")private String viewCenterLat;/** 中心点经度 */@Excel(name = "中心点经度")private String viewCenterLong;/** 缩略图 */@Excel(name = "缩略图")private String thumbUrl;/** shp坐标编码 */@Excel(name = "shp坐标编码")private String srs = "4326";/** 数据归属区域(可多选) */@Excel(name = "数据归属区域(可多选)")private List<Long> areaList;/** 数据归属分类(可多选) */@Excel(name = "数据归属分类(可多选)")private List<Long> classifyList;@Excel(name = "是否包含必要字段")private Boolean needfulStatus;@Excel(name = "特别排除的字段")private String excludeFields;
}

然后是一个获取geoserver的配置类,需要从数据库中获取,这个类我已经写好了,只需要去写一下方法即可
先指导AI干活,帮我把某个配置类的注解和注释都写正规一点
写好对应的获取geosever的配置
geoserver获取配置
然后因为配置化的原因,写了很久的代码,系统太复杂了,光理解代码都要了很长时间

后端内容

  1. geoserver的登录
  2. 数据的上传以及解包
  3. geoserver的上传参数配置以及相关的数据库配置字段,pgsql的shp数据建表
  4. geoserver上的以及数据库上的相关增删改查
  5. 总结来说,3个服务并且使用多个DTO才能组成后端服务

geosever登录
首先是Geosever的Utils工具,写在common里utils里去

import it.geosolutions.geoserver.rest.GeoServerRESTManager;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.GeoServerRESTReader;
import it.geosolutions.geoserver.rest.decoder.RESTLayer;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.datastore.GSShapefileDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Base64;
public class GeoServerUtils {/*** shp数据发布* 图层 发布** @param url* @param userName* @param passWord* @param FilePath    文件路径* @param workSpace   工作区名称* @param dataSetName 数据存储名称* @param layerName   图层名称*/public static void publishShape(String url, String userName, String passWord, String FilePath, String workSpace, String dataSetName, String layerName, String type) throws IOException {File file = new File(FilePath);// 连接geoServerGeoServerRESTManager geoServerRESTManager = null;try {geoServerRESTManager = new GeoServerRESTManager(new URL(url), userName, passWord);} catch (Exception e) {System.out.println("远程连接GeoServer失败...");e.printStackTrace();}// shp读写和发布assert geoServerRESTManager != null;GeoServerRESTReader restReader = geoServerRESTManager.getReader();GeoServerRESTPublisher restPublisher = geoServerRESTManager.getPublisher();// 存在相应的工作区if (!restReader.existsWorkspace(workSpace)) {restPublisher.createWorkspace(workSpace);} else {System.out.println("workSpace已经存在了,workSpace :" + workSpace);}if (!restReader.existsDatastore(workSpace, dataSetName)) {//创建shape文件存储try {//shp文件所在的位置String urlDataStorePath = file.getPath();// 数据存储需要的文件String shpFilePath = String.format("file://%s", urlDataStorePath);URL urlShapeFile = new URL(shpFilePath);// 创建数据集GSShapefileDatastoreEncoder datastoreEncoder = new GSShapefileDatastoreEncoder(dataSetName, urlShapeFile);datastoreEncoder.setCharset(Charset.forName("UTF-8"));geoServerRESTManager.getStoreManager().create(workSpace, datastoreEncoder);} catch (MalformedURLException e) {e.printStackTrace();}}// 图层layerif (!restReader.existsLayer(workSpace, layerName)) {try {GSFeatureTypeEncoder gsFeatureTypeEncoder = new GSFeatureTypeEncoder();gsFeatureTypeEncoder.setTitle(layerName);gsFeatureTypeEncoder.setName(layerName);gsFeatureTypeEncoder.setSRS(GeoServerRESTPublisher.DEFAULT_CRS);GSLayerEncoder gsLayerEncoder = new GSLayerEncoder();
//                 gsLayerEncoder.addStyle("grass");boolean layer = restPublisher.publishDBLayer(workSpace, dataSetName, gsFeatureTypeEncoder, gsLayerEncoder);System.out.println("publish layer : " + layer);} catch (Exception e) {e.printStackTrace();}}//绑定样式sldif (!StringUtils.isEmpty(type)){styleBinding(url,workSpace,layerName,type,userName,passWord);}
//        styleBinding(url,workSpace,layerName,type+"_style",userName,passWord);}public static String GeoServerReader(String url, String userName, String passWord, String workspaceName, String workspaceLayerName) throws IOException {GeoServerRESTReader restReader = new GeoServerRESTReader(url, userName, passWord);OkHttpClient client = new OkHttpClient();String bbox = null;try {// 构建请求Request request = new Request.Builder().url(url + "/wms?request=GetCapabilities&service=WMS&version=1.3.0").build();// 发送请求并获取响应Response response = client.newCall(request).execute();String responseBody = response.body().string();// 解析 GetCapabilities 响应DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(new InputSource(new StringReader(responseBody)));// 查找指定图层的边界框信息NodeList layerNodes = doc.getElementsByTagName("Layer");for (int i = 0; i < layerNodes.getLength(); i++) {Element layerElement = (Element) layerNodes.item(i);//旧逻辑String layerWorkspace = layerElement.getAttribute("queryable");String layerTitle = layerElement.getElementsByTagName("Name").item(0).getTextContent();//新逻辑
//                String layerWorkspace = workspaceName;
//                String layerTitle = workspaceLayerName;
//                if (layerWorkspace.equals(workspaceName) || layerTitle.equals(workspaceLayerName)) {bbox = layerElement.getElementsByTagName("EX_GeographicBoundingBox").item(0).getTextContent();break;
//                }}// 关闭响应response.close();} catch (IOException | ParserConfigurationException | SAXException e) {e.printStackTrace();}String formatting = GeoServerUtils.formatting(bbox);return formatting;}/*** 数据格式处理方法** @param data* @return*/public static String formatting(String data) {data = data.replaceAll("\\s+(?=\\d)", ",");data = String.join(",", data.replace("\n", ","));// 去除逗号后的空格data = data.replaceAll(",\\s+", ",");data = data.replaceFirst(",", "");data = data.replaceAll(",$", "");String[] parts = data.split(",");String output = null;if (parts.length >= 4) {// 交换第一个逗号后面的数和第二个逗号后面的数String temp = parts[1];parts[1] = parts[2];parts[2] = temp;// 重新组合成一个新的字符串output = String.join(",", parts);}return output;}/*** 图层样式绑定** @param geoServerUrl* @param workspace* @param layerName* @param styleName* @param username* @param password* @throws IOException*/public static void styleBinding(String geoServerUrl, String workspace, String layerName, String styleName, String username, String password) throws IOException {// 构建REST API请求URLString urlStr = geoServerUrl + "rest/layers/" + workspace + ":" + layerName;URL url = new URL(urlStr);HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 设置HTTP方法为PUTconn.setRequestMethod("PUT");conn.setDoOutput(true);// 设置基本认证String auth = username + ":" + password;String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());conn.setRequestProperty("Authorization", "Basic " + encodedAuth);// 设置Content-Type为application/xmlconn.setRequestProperty("Content-Type", "application/xml");// 构建XML数据String xmlData = "<layer>" +"<defaultStyle>" +"<name>" + styleName + "</name>" +"</defaultStyle>" +"</layer>";// 发送请求数据OutputStream os = conn.getOutputStream();os.write(xmlData.getBytes());os.flush();// 获取响应码int responseCode = conn.getResponseCode();if (responseCode == 200) {System.out.println("样式绑定成功!");} else {System.out.println("样式绑定失败,响应码:" + responseCode);}}public static void deleteLayer(String geoServerUrl, String username, String password, String workspace, String layerName) throws MalformedURLException {// 创建 GeoServer REST 管理器URL url = new URL(geoServerUrl);GeoServerRESTManager manager = new GeoServerRESTManager(url, username, password);GeoServerRESTPublisher publisher = manager.getPublisher();// 删除图层boolean deleted = publisher.unpublishFeatureType(workspace, layerName, layerName);//删除数据集boolean deletedData = publisher.removeDatastore(workspace,layerName,true);if (deleted && deletedData) {System.out.println("Layer '" + layerName + "' deleted successfully.");} else {System.out.println("Failed to delete layer '" + layerName + "'.");}}}

然后通过引用这些数据就能实现连接geoserver并进行管理增删改查

String url = hsSysConfigService.getGeoserverUrl();//获取url配置
String username = hsSysConfigService.getGeoserverUsername();//获取geoserver的用户名
String password = hsSysConfigService.getGeoserverPassword();//获取geoserver的密码
String uploadDir = hsSysConfigService.getUploadUrl()+"/"+dto.getFileName()+"/"; // 文件保存的路径
String filePath = file.getPath();
File file = new File(uploadDir +dto.getFileName()+".shp");
// 如果存在".",则截取文件名的子串
String filenameWithoutExtension = dto.getFileName();
try {//这个是一个上传到geoserver的例子//1.模拟首先是登录//2.然后文件路径必须是shp矢量数据的路径,//然后dto的getGeoserverWorkArea是工作空间,//filenameWithoutExtension是文件前缀//最后hsLegend.getSldStyle()是geoserver里的样式GeoServerUtils.publishShape(url, username, password, filePath, dto.getGeoserverWorkArea(), filenameWithoutExtension, filenameWithoutExtension,hsLegend.getSldStyle());} catch (IOException e) {e.printStackTrace();}

上传就不多写了,其实如果说,上传的数据是需要合并的数据的话,那就上传一个压缩包,最大大小自己注意即可
读取矢量数据的工具库
首先是建立一些有用的,要做到的有合并矢量数据以及读取矢量数据

import java.util.*;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
/*** 矢量数据合并** @param list       矢量文件集合* @param outputFile 文件输出路径*/public static void mergeShapeFiles(List<String> list, String outputFile) throws IOException {List<SimpleFeatureCollection> featureCollections = new ArrayList<>();// 读取所有输入的Shapefile文件for (String filePath : list) {File file = new File(filePath);ShapefileDataStore dataStore = new ShapefileDataStore(file.toURI().toURL());SimpleFeatureSource featureSource = dataStore.getFeatureSource();featureCollections.add(featureSource.getFeatures());dataStore.dispose();}// 获取Shapefile的Feature类型SimpleFeatureType schema = featureCollections.get(0).getSchema();// 使用DefaultFeatureCollection来存储合并后的数据DefaultFeatureCollection mergedCollection = new DefaultFeatureCollection(null, schema);SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(schema);// 合并所有FeatureCollection中的数据for (SimpleFeatureCollection featureCollection : featureCollections) {try (SimpleFeatureIterator iterator = featureCollection.features()) {while (iterator.hasNext()) {SimpleFeature feature = iterator.next();featureBuilder.addAll(feature.getAttributes());mergedCollection.add(featureBuilder.buildFeature(null));}}}File dir = new File(outputFile);if (!dir.exists()) {dir.mkdirs();}outputFile = outputFile + "/result.shp";// 准备ShapefileDataStoreFactory所需的参数File newFile = new File(outputFile);Map<String, Serializable> params = new HashMap<>();params.put("url", newFile.toURI().toURL());params.put("create spatial index", Boolean.TRUE); // 可选:创建空间索引// 创建新的Shapefile数据存储ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);newDataStore.createSchema(schema);Transaction transaction = new DefaultTransaction("create");SimpleFeatureSource featureSource = newDataStore.getFeatureSource(newDataStore.getTypeNames()[0]);if (featureSource instanceof SimpleFeatureStore) {SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;featureStore.setTransaction(transaction);featureStore.addFeatures(mergedCollection);transaction.commit();transaction.close();} else {System.out.println("无法写入: " + outputFile);}newDataStore.dispose();}
}

读取矢量信息中的属性

    public static List<Map<String, Object>> shpDataInfo(File file) throws IOException {List<Map<String, Object>> featuresList = new ArrayList<>();// 创建FileDataStore并获取FeatureSourceShapefileDataStore store = (ShapefileDataStore) FileDataStoreFinder.getDataStore(file);store.setCharset(Charset.forName("UTF-8")); // 设置字符编码SimpleFeatureSource featureSource = store.getFeatureSource();store.dispose();// 获取Shapefile的FeatureTypeSimpleFeatureType schema = featureSource.getSchema();// 遍历每个要素并读取其属性try (FeatureIterator<SimpleFeature> features = featureSource.getFeatures().features()) {while (features.hasNext()) {HashMap map = new HashMap();SimpleFeature feature = features.next();for (AttributeDescriptor attr : schema.getAttributeDescriptors()) {String attrName = attr.getName().toString();Object attrValue = feature.getAttribute(attrName);map.put(attrName, attrValue);}featuresList.add(map);}return featuresList;}}

对应需要使用的maven库

<!--GeoServer--><dependency><groupId>it.geosolutions</groupId><artifactId>geoserver-manager</artifactId><version>1.7.0</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-main</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-referencing</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.2.25</version></dependency>

至此很多路线就打通了
还没写Pgsql管理里面的shp数据,以后再写了


总结

后面会出一下cesium加载模型并变色的教程的。

相关文章:

  • sglang是如何运行?
  • 巴西电商爆发期,第三方海外仓如何应用WMS系统抢占市场先机?
  • 详解MySQL索引
  • 使用 uv 工具从 pyproject.toml 和 uv.lock 快速安装 Python 依赖
  • HJ106 字符逆序【牛客网】
  • Leetcode 3313. 查找树中最后标记的节点
  • Pytorch中文文本分类
  • 2025 年油烟净化技术前瞻
  • 车载诊断架构 --- 车载诊断有那些内容(下)
  • mac将自己网络暴露到公网
  • TCP与UDP区别及应用场景详解
  • Gemini 2.5 Pro 一次测试
  • TCP 三次握手,第二次握手报文丢失会发生什么?
  • FFmpeg 安装包全攻略:gpl、lgpl、shared、master 区别详解
  • macOs系统M1芯片执行source ~/.zshrc报错503
  • SurfaceFlinger及Android应用RenderThread角度观察Jank丢帧卡顿
  • 调度关键路径里调整优先级导致hardlockup
  • 5.23本日总结
  • AI编辑器规则
  • 非关系型数据库NoSQL
  • 福建省人民政府网站/网络广告营销的典型案例
  • 网站建设报告实训步骤/seo专业技术培训
  • wordpress调用搜索功能/seo课程在哪培训好
  • h5网站开发多少钱/南昌seo搜索优化
  • 电影网站推广/电商sem是什么意思
  • 网站建设最新活动/网页制作免费模板