GeoServer是一个用 Java
编写并允许用户共享和编辑地理空间数据的开源服务器端软件。 GeoServer
使用开放标准发布来自任何主要空间数据源的数据,它专为互操作性而设计,允许用户要素数据进行更新、删除、插入操作,通过 GeoServer 可以比较容易的在用户之间迅速共享空间地理信息。 实施 Web
地图服务 (WMS
) 标准,GeoServer
可以创建各种输出格式的地图。GeoServer
已集成免费地图库——OpenLayers
,可快速生成简单地图。 另外,GeoServer
建立在 Geotools
之上,是一个开源 Java GIS
工具包。
GeoServer
是领先的大规模发布地理空间数据的开源服务器,是用于管理和传播地理空间数据的强大解决方案。 它支持多种输入格式,用于根据 OGC
和 ISO TC 211
发布的标准以及社区标准,通过众所周知的 API
生成令人惊叹的地图、执行分析或简单地在 Web
上提供Map
。 很多组织使用 GeoServer
提供 PB 级数据,从点数据(例如全球实时船舶位置)到海量多维地球观测数据。
GeoServer
是开放地理空间联盟 Open Geospatial Consortium (OGC)、Web 要素服务Web Feature Service (WFS) 和 Web 覆盖服务 Web Coverage Service (WCS)标准的参考实现,也是经过高性能认证的兼容 Web 地图服务Web Map Service (WMS)。 GeoServer 构成了地理空间网络的核心组件。
类型 | 值 |
---|---|
输入格式 | Shapefile、GeoPackage、Oracle Spatial、PostGIS、SQL Server、MongoDB、GeoTiff、JPEG200、NetCDF、ElasticSearch、SAP Hana |
协议和输出格式 | OGC Web Map Services (WMS)、OGC Web Feature Services (WFS)、OGC Web Coverage Services (WCS)、OGC Web Processing Services (WPS)、OGC Web Map Tile Services (WMTS)、Catalogue Service for the Web (CSW)、Tile Mapping Service (TMS)、OGC Web Map Services、OGC KML/KMZ、OGC GML、New OGC REST API 、GeoJSON、GeoRSS、DDS/BIL for 3D mapping |
使用的知名世界组织 | DLR (Ge)、EUMETSAT (EU)、DigitalGlobe (US)、Halliburton (US/UK)、New York City (US)、MassGIS (US)、Topcon (Jp/It)、FarmersEdge (Can/US)、San Jose Water (US)、PDF (US)、FNMOC (US)、NOOA (US)、City of Genoa (It)、World Bank、UN FAO、UN WFP、UNEGP GRID、BEV (At)、IGN (Fr)、BRGM (Fr)、EMSA (EU)、National Land Survey (NLS) of Finland (Fi)、Swedish Agency for Maritime and Water Management (SWAM)、UNESCO、Finnish Environment Institute (Fi)、New South Wales Geological Survey (Au)、GeoScience Australia (Au)、Total (fr)、Norbit (No)、NPRA (No)、DWD (Ge)、Rennes Metropole (Fr) |
若用户想要深入学习GeoServer,可前往官网查看GeoServer用户手册和GeoServer文档。
|
|
OGC
Web地图服务(WMS)规范定义了一个HTTP
接口,用于从服务器请求带有地理参考的地图图像。GeoServer
支持使用最广泛的WMS
版本WMS 1.1.1,以及WMS 1.3.0。WMS
提供了一个简单的HTTP
接口,用于从一个或多个分布式地理空间数据库请求地理注册地图图像。WMS
请求定义了要处理的地理层和感兴趣的区域。对请求的响应是一个或多个可以在浏览器应用程序中显示的地理注册地图图像(以JPEG
、PNG
等格式返回)。该接口还支持指定返回的图像是否应该是透明的,以便可以合并或不合并来自多个服务器的层。
OGC
Web要素服务WFS用于使用HTTP
在互联网上创建、修改和交换矢量格式的地理信息。WFS
用地理标记语言(Geography Markup Language,GML
)编码和传输信息,GML
是XML
的一个子集。GeoServer
支持的WFS
版本2.0.0、1.1.0和1.0.0。WFS
代表了地理信息在互联网上创建、修改和交换方式的变化。例如,WFS
不使用文件传输协议FTP
在文件级别共享地理信息,而是在要素和要素属性级别提供对地理信息的直接细粒度访问。
OGC
Web 覆盖服务 (WCS) 将地理空间信息的接收称为“覆盖”:表示空间变化现象的数字地理空间信息。可以将其视为光栅数据的WFS
。它获取地图的“源代码
”,但在本例中,它不是原始向量,而是原始图像。WCS
和WMS
有一个重要的区别。尽管它们十分相似都可以返回相似的格式,但WCS
能够返回更多信息,包括有价值的元数据和更多格式。
WCS
服务包含三种接口请求:GetCapabilities、DescribeCoverage和GetCoverage。
OGC
Web 处理服务WPS是一种用于发布地理空间过程、算法和计算的服务。WPS
服务是Geoserver
的扩展,为数据处理和地理空间分析提供执行操作。默认情况下,WPS
不是GeoServer
的一部分,但可以作为扩展提供。WPS
接口标准为地理空间处理服务(如多边形叠加)的输入和输出(请求和响应)的标准化提供了规则。该标准还定义了客户机如何请求流程的执行,以及如何处理流程的输出。它定义了一个接口,用于促进地理空间过程的发布以及客户对这些过程的发现和绑定。WPS
所需的数据可以通过网络传输,也可以在服务器上获得。
OGC
Web 地图切片服务WMTS标准定义了一些操作,这些操作允许用户访问瓦片地图,WMTS
可能是OGC
首个支持RESTful
访问的服务标准。
OGC
Web 目录服务CSW可以从GeoServer
目录中检索和显示相关数据服务和处理服务项目。
开放Web
服务(WCS
、WFS
、WMS
和WPS
)使用通用元数据定义来描述所提供的服务,并指出任何使用限制。
|
|
在安装GeoServer
前,务必记得安装好Java
才可(可Win+R打开cmd
命令行窗口输入java -version
进行测试,这里使用的是Java 8
,在GeoServer下载页面点击Archived
可下载历史各个版本的GeoServer
。
|
|
参考Windows installer,双击安装包选择适配项进行安装即可。
参考Windows binary,首先解压该文件得到下图所示的文件夹后,进入bin
文件夹后用鼠标双击startup.bat
,会弹出启动GeoServer
的命令行窗口,启动成功后的默认端口为8888,打开浏览器访问http://localhost:8888/geoserver可进入GeoServer
服务器的登录页面,默认的用户名为admin,密码为geoserver。
关闭GeoServer
服务器只需要关闭命令行窗口即可。
参考Web archive,首先解压该文件得到如下所示的文件夹,在文件夹中找到geoserver.war
文件并复制后粘贴到Tomcat
服务器的webapps
文件夹下(D:\program files\apache-tomcat-10.0.12\webapps),之后进入bin
文件夹下双击startup.bat
,弹出Tomcat
服务器启动的命令行窗口,待启动完成后打开浏览器访问http://localhost:8080/geoserver
浏览器进入Tomcat
http://localhost:8080/主页后选择登录,使用用户名tomcat
和密码s3cret
登录可查看并管理Web
应用程序,可以看到/geoserver
,说明GeoServer
服务器部署成功,点击该项可进入相关页面。
为了更好地使用GeoServer,可参考Using the web administration interface、Publishing a shapefile等官方帮助示例。
这里以WGC1984
坐标系的栅格Tif
数据为例进行实验。
进入GeoServer
主页后,发布之前需要打开工作区cite
的WCS
服务功能。
先点击左侧的数据存储,选择添加新的数据存储,
之后选择新建数据源下的栅格数据源中的GeoTIFF,
在添加栅格数据源界面,这里选择已有的工作区为cite
(当然可以自己新建一个工作区),然后输入数据源名称为sample
,然后点击浏览选择要上传的Tif
数据后点击保存,会进入新建图层界面,点击发布。
进入编辑图层界面,根据自己的需要对数据、发布、维度、Tile Caching、Security五个方面进行设置后,最终点击保存即可在图层中看到。
点击左侧的图层预览,右侧查找到cite:sample
(工作区名:数据名)后点击右侧的OpenLayers
即可对Tif
影像进行预览。
上传GeoTIFF
数据到GeoServer
服务器的函数,详见4.2.1。
PublishGeoTiffToGeoServer
import it.geosolutions.geoserver.rest.GeoServerRESTManager;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.encoder.datastore.GSGeoTIFFDatastoreEncoder;
/**
* @function 发布本地GeoTiff到GeoServer上形成WCS服务
* @author NoName
* @createdate 2022.2.14
* @param1 Tif_fileName: D:/迅雷下载/sample.tif
* @param2 saveIP GeoServer服务器的Ip地址
* @param3 savePort GeoServer服务器的端口号
* @param4 saveIP GeoServer服务器的用户名
* @param5 savePort GeoServer服务器的密码
* @param6 workspace 待发布WCS服务的工作空间名称
* @param7 storename 待发布WCS服务的数据存储名称
* @return WCS服务的identifier
*/
public static String PublishGeoTiffToGeoServer(String Tif_fileName,String saveIP,String savePort,String username,String password,String workspace,String storename)
{
/**
* 上传服务
*/
String serviceurl = "http://"+saveIP+":"+savePort+"/geoserver"; //GeoServer的连接配置
int flag=0;
try
{
URL u = new URL(serviceurl);
GeoServerRESTManager manager = new GeoServerRESTManager(u, username, password);
GeoServerRESTPublisher publisher = manager.getPublisher();
List workspaces = manager.getReader().getWorkspaceNames();
if (!workspaces.contains(workspace)) //判断工作区(workspace)是否存在,不存在则创建
{
boolean createws = publisher.createWorkspace(workspace);
System.out.println("create ws : " + createws);
} else {
System.out.println("workspace存在 :" + workspace);
}
//新建数据存储,如已经存在将覆盖
GSGeoTIFFDatastoreEncoder gsGeoTIFFDatastoreEncoder = new GSGeoTIFFDatastoreEncoder(storename);
gsGeoTIFFDatastoreEncoder.setWorkspaceName(workspace);
gsGeoTIFFDatastoreEncoder.setUrl(new URL("file:" + Tif_fileName));
boolean createStore = manager.getStoreManager().create(workspace, gsGeoTIFFDatastoreEncoder);
System.out.println("create store (TIFF文件创建状态) : " + createStore);
boolean publish = manager.getPublisher().publishGeoTIFF(workspace, storename, new File(Tif_fileName));
System.out.println("publish (TIFF文件发布状态) : " + publish);
if(publish==true)
{
flag=1;
}else
{
flag=0;
}
}catch(Exception e)
{
e.printStackTrace();
flag = 0;
}
if(flag == 1)
{
return workspace+":"+storename;
}
else
return "";
}
GetCapabilities
操作是向WCS
服务器请求该服务器提供哪些操作和服务(“功能”)的列表。
Using a GET request (standard HTTP):
http://localhost:8080/geoserver/wcs?service=wcs&version=1.0.0&request=getcapabilities
DescribeCoverage
请求的目的是获取有关客户想要查询的覆盖范围的附加信息。它返回有关crs、元数据、域、范围和可用格式的信息。客户机通常需要发出DescribeCoverage
请求,然后才能确保能够发出正确的GetCoverage
请求。
http://localhost:8080/geoserver/wcs?service=wcs&version=1.0.0&request=describecoverage&identifier=cite:sample
http://localhost:8080/geoserver/wcs?service=wcs&version=1.1.0&request=describecoverage&identifiers=cite:sample
GetCoverage
操作请求实际的空间数据。它可以检索覆盖范围的子集,结果可以是覆盖范围本身,也可以是对它的引用。GetCoverage
请求最强大的功能是能够对域(高度和时间)和范围进行裁剪。它还可以进行重采样,以不同的数据格式编码,并以不同的方式返回生成的文件。
http://localhost:8080/geoserver/wcs?request=GetCoverage&service=wcs&version=1.0.0&sourceCov
erage=cite:sample&crs=EPSG:4326&format=geotiff&BBox=114.13813710173059,30.423415944431966,114.52639379166072,30.726972419428588&width=1366&height=1068
点击GeoServer
主页下方的演示,选择右侧的WCS request builder
,进入WCS request builder
页面,Coverage name
一栏选择cite:sample
点击Get Coverage
可直接下载该Tif
影像。
点击Generate GetCoverage XML
后会弹出GetCoverage
所对应的HTTP Post
请求需要的XML
,因为本质上Get Coverage
就是利用XML
中的一些信息(版本号、服务类型、Bounding Box、宽度和高度、坐标系、数据格式)来发送请求获得GeoServer
服务器的响应而得到WCS
服务对应的Tif
影像。
利用上述XML
可得到下载sample
影像的WCSUrl
格式为 http://localhost:8080/geoserver/wcs?request=GetCoverage&service=wcs&version=1.0.0&sourceCov
erage=cite:sample&crs=EPSG:4326&format=geotiff&BBox=114.13813710173059,30.423415944431966,114.52639379166072,30.726972419428588&width=1366&height=1068,将其输入到浏览器的地址栏里后回车即可进行下载,GeoServer服务器后台进行响应。
最后利用ArcGIS
打开下载好的cite_sample.tif
进行查看,结果如下图所示。
依赖的第三方jar
包如下,在Eclipse
中将这些jar
包添加到Build Path
中即可运行。
commons-beanutils-1.9.4.jar
commons-codec-1.9.jar
commons-collections-3.2.2.jar
commons-collections4-4.2.jar
commons-compiler-3.0.8.jar
commons-dbcp-1.4.jar
commons-fileupload-1.3.3.jar
commons-httpclient-3.1.jar
commons-io-2.8.0.jar
commons-jxpath-1.3.jar
commons-lang-2.5.jar
commons-lang3-3.8.1.jar
commons-logging-1.1.1.jar
commons-pool-1.5.4.jar
commons-text-1.4.jar
dom4j.jar
geoserver-manager-1.7.0-pdok2.jar
jaxen-1.1.6.jar
jdom-1.1.3.jar
json.jar
log4j-1.2.17.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar
a、上传GeoTIFF
数据到GeoServer
服务器的函数PublishGeoTiffToGeoServer
/**
* @function 发布本地GeoTiff到GeoServer上形成WCS服务
* @author NoName
* @createdate 2022.2.14
* @param1 Tif_fileName: D:/迅雷下载/sample.tif
* @param2 saveIP GeoServer服务器的Ip地址
* @param3 savePort GeoServer服务器的端口号
* @param4 saveIP GeoServer服务器的用户名
* @param5 savePort GeoServer服务器的密码
* @param6 workspace 待发布WCS服务的工作空间名称
* @param7 storename 待发布WCS服务的数据存储名称
* @return WCS服务的identifier
*/
public static String PublishGeoTiffToGeoServer(String Tif_fileName,String saveIP,String savePort,String username,String password,String workspace,String storename)
{
/**
* 上传服务
*/
String serviceurl = "http://"+saveIP+":"+savePort+"/geoserver"; //GeoServer的连接配置
int flag=0;
try
{
URL u = new URL(serviceurl);
GeoServerRESTManager manager = new GeoServerRESTManager(u, username, password);
GeoServerRESTPublisher publisher = manager.getPublisher();
List workspaces = manager.getReader().getWorkspaceNames();
if (!workspaces.contains(workspace)) //判断工作区(workspace)是否存在,不存在则创建
{
boolean createws = publisher.createWorkspace(workspace);
System.out.println("create ws : " + createws);
} else {
System.out.println("workspace存在 :" + workspace);
}
//新建数据存储,如已经存在将覆盖
GSGeoTIFFDatastoreEncoder gsGeoTIFFDatastoreEncoder = new GSGeoTIFFDatastoreEncoder(storename);
gsGeoTIFFDatastoreEncoder.setWorkspaceName(workspace);
gsGeoTIFFDatastoreEncoder.setUrl(new URL("file:" + Tif_fileName));
boolean createStore = manager.getStoreManager().create(workspace, gsGeoTIFFDatastoreEncoder);
System.out.println("create store (TIFF文件创建状态) : " + createStore);
boolean publish = manager.getPublisher().publishGeoTIFF(workspace, storename, new File(Tif_fileName));
System.out.println("publish (TIFF文件发布状态) : " + publish);
if(publish==true)
{
flag=1;
}else
{
flag=0;
}
}catch(Exception e)
{
e.printStackTrace();
flag = 0;
}
if(flag == 1)
{
return workspace+":"+storename;
}
else
return "";
}
b、根据Identifier
解析GeoServer
服务器获得WCSUrl
的函数getWCSGetCoverageUrl
/**
* @function 根据带参数的URL发送Get请求获取结果
* @author NoName
* @createdate 2022.2.14
* @param1 requestURLwithParams : cite:sample
*/
public static String sendGetMsg(String requestURLwithParams) //Get请求方式
{
String result = ""; //先设置请求地址
try
{
URL url = new URL(requestURLwithParams);//设置Http请求Header
URLConnection conn = url.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.connect();//发送请求,接收返回信息
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
for (line = br.readLine(); line != null; line = br.readLine())
{
result += line;
}
} catch (IOException ex)
{
return ex.getMessage();
}
return result;
}
/**
* @function 向指定WCS服务发送DescribeProcess请求获取XML结果并解析生成WCSGetCoverage的url,利用该url可下载Tif文件到本地电脑
* @author NoName
* @createdate 2022.2.14
* @param1 ipaddress : localhost
* @param2 port: 8080
* @param3 coverageidentifier : cite:sample
* @throws MalformedURLException
*/
public static String getWCSGetCoverageUrl(String ipaddress,String port,String coverageidentifier) throws MalformedURLException
{
String WCSUrl_Tif = "";
try
{
String socket=ipaddress+":"+port;
String WCSurl = "http://"+socket+"/geoserver/wcs";
String Service = "WCS";
String DescribeCovergeRequest= "DescribeCoverage",GetCoverageRequest = "GetCoverage";
String Version = "1.0.0";
String WCS_DescribeProcess=WCSurl+"?"+"service="+Service+"&version="+Version+"&request="+DescribeCovergeRequest+"&identifier="+coverageidentifier;
System.out.println(sendGetMsg(WCS_DescribeProcess));
String Crs ="EPSG:4326";
String Format = "GeoTIFF";
String BBox = "";
String width = "";
String height = "";
URL url = new URL(WCS_DescribeProcess);
SAXReader saxReader = new SAXReader();//创建DOM4J解析器对象
Document document = saxReader.read(url);//读取xml文件,并生成document对象 现可通过document来操作文档
Element rootElement = document.getRootElement();//获取到文档的根节点
System.out.println("根节点的名字是:" + rootElement.getName());
List list1 = rootElement.elements();//获取子节点列表
System.out.println(list1.size());
for(int i=0;i<list1.size();i++)
{
Element fistChild = (Element) list1.get(i);//一级节点
System.out.println(fistChild.getName()+" "+fistChild.elementTextTrim("name"));
if(fistChild.elementText("name").contains(coverageidentifier))
{
// String description = fistChild.elementTextTrim("description");
// String name = fistChild.elementTextTrim("name"); //获取head节点下的子节点name值
// String label = fistChild.elementTextTrim("label");
// String lonlatenvelope = fistChild.elementTextTrim("lonLatEnvelope");
List list2 = fistChild.elements();
for(int j=0;j<list2.size();j++)
{
Element secondChild = (Element) list2.get(j);//二级节点
if(secondChild.getName() == "description")
System.out.println("\t" +"description: "+ secondChild.getTextTrim()+" ");
if(secondChild.getName() == "name")
{
System.out.println("\t" +"name: "+ secondChild.getTextTrim()+" ");
//name = secondChild.getTextTrim();
}
if(secondChild.getName() == "label")
System.out.println("\t" +"label: "+ secondChild.getTextTrim()+" ");
if(secondChild.getName() == "lonLatEnvelope")
{
}
if(secondChild.getName() == "keywords")
{
System.out.println("\t" +"keywords: ");
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
System.out.println("\t" +"\t" +"keyword: "+ thirdChild.getTextTrim());
}
}
if(secondChild.getName() == "domainSet")
{
System.out.println("\t" +"domainSet: ");
Element spatialdomain = secondChild.element("spatialDomain");
System.out.println("\t" +"\t" +"domainSet: "+ spatialdomain.getTextTrim());
Element envelope = spatialdomain.element("Envelope");
System.out.println("\t" +"\t" +"\t" +"Envelope: "+ envelope.attribute("srsName").getValue());
String position="";
List poslist = envelope.elements();
for(int jj=0;jj<poslist.size();jj++)
{
Element pos = (Element) poslist.get(jj);
if(jj == 0)
position += pos.getTextTrim();
else
position += ","+ pos.getTextTrim();
}
BBox = position.replaceAll(" ", ",");
System.out.println("\t" +"\t" +"\t" +"\t" +BBox);
Element RectifiedGrid = spatialdomain.element("RectifiedGrid");
System.out.println("\t" +"\t" +"\t" +"RectifiedGrid: "+ RectifiedGrid.attribute("dimension").getValue()+ " "+RectifiedGrid.attribute("srsName").getValue());
Element lowhigh = RectifiedGrid.element("limits").element("GridEnvelope").element("high");
String widthhigh = lowhigh.getTextTrim().replaceAll(" ", ",");
width = widthhigh.split(",")[0];
height = widthhigh.split(",")[1];
System.out.println("\t" +"\t" +"\t" +"\t" +width +" "+ height);
}
if(secondChild.getName() == "rangeSet")
{
System.out.println("\t" +"rangeSet: ");
}
if(secondChild.getName() == "supportedCRSs")
{
System.out.println("\t" +"supportedCRSs: ");
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
if(thirdChild.getName() == "requestResponseCRSs")
{
System.out.println("\t" +"\t" +"requestResponseCRSs: "+thirdChild.getTextTrim()+" ");
Crs = thirdChild.getTextTrim();
}
}
}
if(secondChild.getName() == "supportedFormats")
{
System.out.println("\t" +"supportedFormats: "+ secondChild.attribute("nativeFormat").getValue());
Format = secondChild.attribute("nativeFormat").getValue();
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
if(thirdChild.getName() == "formats")
System.out.println("\t" +"\t" +"formats: "+thirdChild.getTextTrim()+" ");
}
}
if(secondChild.getName() == "supportedInterpolations")
{
System.out.println("\t" +"supportedInterpolations: "+ secondChild.attribute("default").getValue());
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
if(thirdChild.getName() == "interpolationMethod")
System.out.println("\t" +"\t" +"interpolationMethod: "+thirdChild.getTextTrim()+" ");
}
}
}
break;
}
}
WCSUrl_Tif=WCSurl+"?request="+GetCoverageRequest+"&service="+Service+"&version="+Version+"&sourceCoverage="+coverageidentifier+"&crs="+Crs+"&format="+Format+"&BBOX="+BBox+"&width="+width+"&height="+height;
} catch (DocumentException e) {
e.printStackTrace();
}
return WCSUrl_Tif;
}
c、根据WCSUrl
获取其元数据的函数getmetdataofWCS
/**
* @function 获取WCSUrl中的元数据metdata并输出
* @author NoName
* @createdate 2022.2.14
* @param1 WCSUrl : http://localhost:8080/geoserver/wcs?request=GetCoverage&service=WCS&version=1.0.0&sourceCoverage=cite:sample&crs=EPSG:4326&format=GeoTIFF&BBOX=114.13813710173059,30.423415944431966,114.52639379166072,30.726972419428588&width=1365&height=1067
*/
public static void getmetdataofWCS(String WCSUrl)
{
System.out.println(WCSUrl);
if(WCSUrl.contains("&crs=") && WCSUrl.contains("&format=") && WCSUrl.contains("&BBOX=") && WCSUrl.contains("width=") && WCSUrl.contains("&height="))
{
String CRS = WCSUrl.substring(WCSUrl.indexOf("&crs=")+5,WCSUrl.indexOf("&format=")),
BBOX = WCSUrl.substring(WCSUrl.indexOf("&BBOX=")+6,WCSUrl.indexOf("&width=")),
WIDTH = WCSUrl.substring(WCSUrl.indexOf("&width=")+7,WCSUrl.indexOf("&height=")),
HEIGHT = WCSUrl.substring(WCSUrl.indexOf("&height=")+8,WCSUrl.length());
System.out.println("Coordinate System: " + CRS);
System.out.println("Bouding Box : " + BBOX);
System.out.println("Width : " + WIDTH);
System.out.println("Height : " + HEIGHT);
}
else
System.out.println("No Result!");
}
d、根据WCSUrl
下载Tif
数据文件的函数getWCSGetCoverageFile
/**
* @param inStream 数据流
* @return 返回二进制数组
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=inStream.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
/**
* @function 向指定WCS服务发送GET方法的请求,进行 getcoverage操作下载Tif至本地 http://localhost:8080/geoserver/wcs?request=GetCoverage&service=WCS&version=1.0.0&sourceCoverage=cite:sample&crs=EPSG:4326&format=GeoTIFF&BBOX=114.13813710173059,30.423415944431966,114.52639379166072,30.726972419428588&width=1365&height=1067
* @author NoName
* @createdate 2022.2.14
* @param1 requestURL?name1=value1&name2=value2 :
* @param2 filename : "D:迅雷下载/resultSample.tif"
* @throws IOException
*/
public static void getWCSGetCoverageFile(String requestURLWithparams,String filename) throws IOException
{
try
{
URL url = new URL(requestURLWithparams);
URLConnection conn = url.openConnection();
conn.setRequestProperty("accept", "*/*");//设置Http请求Header
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.connect();//发送请求,接收返回信息
byte[] data= readInputStream(conn.getInputStream());//得到图片的二进制数据,以二进制封装得到数据
File imageFile = new File(filename);//创建一个文件对象用来保存栅格文件
System.out.println("开始写入");
FileOutputStream outStream = new FileOutputStream(imageFile);//创建输出流
outStream.write(data);//写入数据
outStream.close(); //关闭输出流
System.out.println("写入成功!");
} catch (Exception e)
{
e.printStackTrace();
}
}
MyFunctionWithGeoServer.java
完整代码
package com.test;
import it.geosolutions.geoserver.rest.GeoServerRESTManager;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.encoder.datastore.GSGeoTIFFDatastoreEncoder;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.UUID;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class MyFunctionWithGeoServer
{
/**
* @function 根据带参数的URL发送Get请求获取结果
* @author NoName
* @createdate 2022.2.14
* @param1 requestURLwithParams : cite:sample
*/
public static String sendGetMsg(String requestURLwithParams) //Get请求方式
{
String result = ""; //先设置请求地址
try
{
URL url = new URL(requestURLwithParams);//设置Http请求Header
URLConnection conn = url.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.connect();//发送请求,接收返回信息
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
for (line = br.readLine(); line != null; line = br.readLine())
{
result += line;
}
} catch (IOException ex)
{
return ex.getMessage();
}
return result;
}
/**
* @function 向指定WCS服务发送DescribeProcess请求获取XML结果并解析生成WCSGetCoverage的url,利用该url可下载Tif文件到本地电脑
* @author NoName
* @createdate 2022.2.14
* @param1 ipaddress : localhost
* @param2 port: 8080
* @param3 coverageidentifier : cite:sample
* @throws MalformedURLException
*/
public static String getWCSGetCoverageUrl(String ipaddress,String port,String coverageidentifier) throws MalformedURLException
{
String WCSUrl_Tif = "";
try
{
String socket=ipaddress+":"+port;
String WCSurl = "http://"+socket+"/geoserver/wcs";
String Service = "WCS";
String DescribeCovergeRequest= "DescribeCoverage",GetCoverageRequest = "GetCoverage";
String Version = "1.0.0";
String WCS_DescribeProcess=WCSurl+"?"+"service="+Service+"&version="+Version+"&request="+DescribeCovergeRequest+"&identifier="+coverageidentifier;
System.out.println(sendGetMsg(WCS_DescribeProcess));
String Crs ="EPSG:4326";
String Format = "GeoTIFF";
String BBox = "";
String width = "";
String height = "";
URL url = new URL(WCS_DescribeProcess);
SAXReader saxReader = new SAXReader();//创建DOM4J解析器对象
Document document = saxReader.read(url);//读取xml文件,并生成document对象 现可通过document来操作文档
Element rootElement = document.getRootElement();//获取到文档的根节点
System.out.println("根节点的名字是:" + rootElement.getName());
List list1 = rootElement.elements();//获取子节点列表
System.out.println(list1.size());
for(int i=0;i<list1.size();i++)
{
Element fistChild = (Element) list1.get(i);//一级节点
System.out.println(fistChild.getName()+" "+fistChild.elementTextTrim("name"));
if(fistChild.elementText("name").contains(coverageidentifier))
{
// String description = fistChild.elementTextTrim("description");
// String name = fistChild.elementTextTrim("name"); //获取head节点下的子节点name值
// String label = fistChild.elementTextTrim("label");
// String lonlatenvelope = fistChild.elementTextTrim("lonLatEnvelope");
List list2 = fistChild.elements();
for(int j=0;j<list2.size();j++)
{
Element secondChild = (Element) list2.get(j);//二级节点
if(secondChild.getName() == "description")
System.out.println("\t" +"description: "+ secondChild.getTextTrim()+" ");
if(secondChild.getName() == "name")
{
System.out.println("\t" +"name: "+ secondChild.getTextTrim()+" ");
//name = secondChild.getTextTrim();
}
if(secondChild.getName() == "label")
System.out.println("\t" +"label: "+ secondChild.getTextTrim()+" ");
if(secondChild.getName() == "lonLatEnvelope")
{
}
if(secondChild.getName() == "keywords")
{
System.out.println("\t" +"keywords: ");
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
System.out.println("\t" +"\t" +"keyword: "+ thirdChild.getTextTrim());
}
}
if(secondChild.getName() == "domainSet")
{
System.out.println("\t" +"domainSet: ");
Element spatialdomain = secondChild.element("spatialDomain");
System.out.println("\t" +"\t" +"domainSet: "+ spatialdomain.getTextTrim());
Element envelope = spatialdomain.element("Envelope");
System.out.println("\t" +"\t" +"\t" +"Envelope: "+ envelope.attribute("srsName").getValue());
String position="";
List poslist = envelope.elements();
for(int jj=0;jj<poslist.size();jj++)
{
Element pos = (Element) poslist.get(jj);
if(jj == 0)
position += pos.getTextTrim();
else
position += ","+ pos.getTextTrim();
}
BBox = position.replaceAll(" ", ",");
System.out.println("\t" +"\t" +"\t" +"\t" +BBox);
Element RectifiedGrid = spatialdomain.element("RectifiedGrid");
System.out.println("\t" +"\t" +"\t" +"RectifiedGrid: "+ RectifiedGrid.attribute("dimension").getValue()+ " "+RectifiedGrid.attribute("srsName").getValue());
Element lowhigh = RectifiedGrid.element("limits").element("GridEnvelope").element("high");
String widthhigh = lowhigh.getTextTrim().replaceAll(" ", ",");
width = widthhigh.split(",")[0];
height = widthhigh.split(",")[1];
System.out.println("\t" +"\t" +"\t" +"\t" +width +" "+ height);
}
if(secondChild.getName() == "rangeSet")
{
System.out.println("\t" +"rangeSet: ");
}
if(secondChild.getName() == "supportedCRSs")
{
System.out.println("\t" +"supportedCRSs: ");
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
if(thirdChild.getName() == "requestResponseCRSs")
{
System.out.println("\t" +"\t" +"requestResponseCRSs: "+thirdChild.getTextTrim()+" ");
Crs = thirdChild.getTextTrim();
}
}
}
if(secondChild.getName() == "supportedFormats")
{
System.out.println("\t" +"supportedFormats: "+ secondChild.attribute("nativeFormat").getValue());
Format = secondChild.attribute("nativeFormat").getValue();
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
if(thirdChild.getName() == "formats")
System.out.println("\t" +"\t" +"formats: "+thirdChild.getTextTrim()+" ");
}
}
if(secondChild.getName() == "supportedInterpolations")
{
System.out.println("\t" +"supportedInterpolations: "+ secondChild.attribute("default").getValue());
List thirdChilds = secondChild.elements();
for(int ii=0;ii<thirdChilds.size();ii++)
{
Element thirdChild = (Element)thirdChilds.get(ii);
if(thirdChild.getName() == "interpolationMethod")
System.out.println("\t" +"\t" +"interpolationMethod: "+thirdChild.getTextTrim()+" ");
}
}
}
break;
}
}
WCSUrl_Tif=WCSurl+"?request="+GetCoverageRequest+"&service="+Service+"&version="+Version+"&sourceCoverage="+coverageidentifier+"&crs="+Crs+"&format="+Format+"&BBOX="+BBox+"&width="+width+"&height="+height;
} catch (DocumentException e) {
e.printStackTrace();
}
return WCSUrl_Tif;
}
/**
* @param inStream 数据流
* @return 返回二进制数组
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=inStream.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
/**
* @function 向指定WCS服务发送GET方法的请求,进行 getcoverage操作下载Tif至本地 http://localhost:8080/geoserver/wcs?request=GetCoverage&service=WCS&version=1.0.0&sourceCoverage=cite:sample&crs=EPSG:4326&format=GeoTIFF&BBOX=114.13813710173059,30.423415944431966,114.52639379166072,30.726972419428588&width=1365&height=1067
* @author NoName
* @createdate 2022.2.14
* @param1 requestURL?name1=value1&name2=value2 :
* @param2 filename : "D:迅雷下载/resultSample.tif"
* @throws IOException
*/
public static void getWCSGetCoverageFile(String requestURLWithparams,String filename) throws IOException
{
try
{
URL url = new URL(requestURLWithparams);
URLConnection conn = url.openConnection();
conn.setRequestProperty("accept", "*/*");//设置Http请求Header
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.connect();//发送请求,接收返回信息
byte[] data= readInputStream(conn.getInputStream());//得到图片的二进制数据,以二进制封装得到数据
File imageFile = new File(filename);//创建一个文件对象用来保存栅格文件
System.out.println("开始写入");
FileOutputStream outStream = new FileOutputStream(imageFile);//创建输出流
outStream.write(data);//写入数据
outStream.close(); //关闭输出流
System.out.println("写入成功!");
} catch (Exception e)
{
e.printStackTrace();
}
}
/**
* @function 获取WCSUrl中的元数据metdata并输出
* @author NoName
* @createdate 2022.2.14
* @param1 WCSUrl : http://localhost:8080/geoserver/wcs?request=GetCoverage&service=WCS&version=1.0.0&sourceCoverage=cite:sample&crs=EPSG:4326&format=GeoTIFF&BBOX=114.13813710173059,30.423415944431966,114.52639379166072,30.726972419428588&width=1365&height=1067
*/
public static void getmetdataofWCS(String WCSUrl)
{
System.out.println(WCSUrl);
if(WCSUrl.contains("&crs=") && WCSUrl.contains("&format=") && WCSUrl.contains("&BBOX=") && WCSUrl.contains("width=") && WCSUrl.contains("&height="))
{
String CRS = WCSUrl.substring(WCSUrl.indexOf("&crs=")+5,WCSUrl.indexOf("&format=")),
BBOX = WCSUrl.substring(WCSUrl.indexOf("&BBOX=")+6,WCSUrl.indexOf("&width=")),
WIDTH = WCSUrl.substring(WCSUrl.indexOf("&width=")+7,WCSUrl.indexOf("&height=")),
HEIGHT = WCSUrl.substring(WCSUrl.indexOf("&height=")+8,WCSUrl.length());
System.out.println("Coordinate System: " + CRS);
System.out.println("Bouding Box : " + BBOX);
System.out.println("Width : " + WIDTH);
System.out.println("Height : " + HEIGHT);
}
else
System.out.println("No Result!");
}
/**
* @function 发布本地GeoTiff到GeoServer上形成WCS服务
* @author NoName
* @createdate 2022.2.14
* @param1 Tif_fileName: D:/迅雷下载/sample.tif
* @param2 saveIP GeoServer服务器的Ip地址
* @param3 savePort GeoServer服务器的端口号
* @param4 saveIP GeoServer服务器的用户名
* @param5 savePort GeoServer服务器的密码
* @param6 workspace 待发布WCS服务的工作空间名称
* @param7 storename 待发布WCS服务的数据存储名称
* @return WCS服务的identifier
*/
public static String PublishGeoTiffToGeoServer(String Tif_fileName,String saveIP,String savePort,String username,String password,String workspace,String storename)
{
/**
* 上传服务
*/
String serviceurl = "http://"+saveIP+":"+savePort+"/geoserver"; //GeoServer的连接配置
int flag=0;
try
{
URL u = new URL(serviceurl);
GeoServerRESTManager manager = new GeoServerRESTManager(u, username, password);
GeoServerRESTPublisher publisher = manager.getPublisher();
List workspaces = manager.getReader().getWorkspaceNames();
if (!workspaces.contains(workspace)) //判断工作区(workspace)是否存在,不存在则创建
{
boolean createws = publisher.createWorkspace(workspace);
System.out.println("create ws : " + createws);
} else {
System.out.println("workspace存在 :" + workspace);
}
//新建数据存储,如已经存在将覆盖
GSGeoTIFFDatastoreEncoder gsGeoTIFFDatastoreEncoder = new GSGeoTIFFDatastoreEncoder(storename);
gsGeoTIFFDatastoreEncoder.setWorkspaceName(workspace);
gsGeoTIFFDatastoreEncoder.setUrl(new URL("file:" + Tif_fileName));
boolean createStore = manager.getStoreManager().create(workspace, gsGeoTIFFDatastoreEncoder);
System.out.println("create store (TIFF文件创建状态) : " + createStore);
boolean publish = manager.getPublisher().publishGeoTIFF(workspace, storename, new File(Tif_fileName));
System.out.println("publish (TIFF文件发布状态) : " + publish);
if(publish==true)
{
flag=1;
}else
{
flag=0;
}
}catch(Exception e)
{
e.printStackTrace();
flag = 0;
}
if(flag == 1)
{
return workspace+":"+storename;
}
else
return "";
}
public static void main(String[] args) throws Exception
{
String ipaddress = "localhost",port="8080",username="admin",password="geoserver",coverageidentifier="cite:sample";
String Tif_filename="D:/搜狗高速下载/sample.tif",workspace="cite",storename ="sample"+UUID.randomUUID().toString().replaceAll("-","");
coverageidentifier = MyFunctionWithGeoServer.PublishGeoTiffToGeoServer(Tif_filename,ipaddress,port,username,password,workspace,storename);
if(coverageidentifier !="")
{
System.out.println("发布成功!");
String WCSUrl_Tif = getWCSGetCoverageUrl(ipaddress,port,coverageidentifier);
System.out.println(WCSUrl_Tif);
if(WCSUrl_Tif !="")
{
System.out.println(coverageidentifier+"对应的WCSUrl下载地址\n"+WCSUrl_Tif.replaceAll("amp;", ""));
MyFunctionWithGeoServer.getmetdataofWCS(WCSUrl_Tif.replaceAll("amp;", ""));//获取WCS数据服务的空间范围信息
MyFunctionWithGeoServer.getWCSGetCoverageFile(WCSUrl_Tif.replaceAll("amp;", ""),"D:/迅雷下载/ResultSample.tif");
}
else
{
System.out.println("获取WCSUrl失败,无法下载");
}
}
else
{
System.out.println("发布失败!");
}
}
}
GeoServer
服务器后台显示的上传Tif
日志,上传成功后可在GeoServer
主页的数据存储和图层预览中进行查看。
代码运行后解析的WCSUrl
结果如下,可放到浏览器里下载:
http://localhost:8080/geoserver/wcs?request=GetCoverage&service=WCS&version=1.0.0&sourceCoverage=cite:samplee1a305504cd6476ba4d2e782a1f8b113&crs=EPSG:4326&format=GeoTIFF&BBOX=114.13813710173059,30.423415944431966,114.52639379166072,30.726972419428588&width=1365&height=1067