1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 基于geoserver开发地图发布服务

基于geoserver开发地图发布服务

时间:2020-12-03 09:11:29

相关推荐

基于geoserver开发地图发布服务

写在前面:我在github上创建了对应的项目,可点此跳转,本文的所有源码均可在项目里找到,欢迎大家访问交流

一、开发背景

gis领域,geoserver是后端地图发布的开源项目。目前我们在启动服务后,可通过自带的web应用进行地图发布操作,这个过程是简单有效的,但是,如果我们想要把地图发布的功能集成到自己的平台里,仍旧使用geoserverweb应用就显得格格不入,为此我们需要对geoserver的功能进行封装,开发自己的后端服务,并配套对应的前端功能(自带的web应用只将其当作管理工具)。本篇研究了基于python语言开发的geoserver-restconfig库,该库封装了geoserver的常用操作函数,考虑到自身的需求以及该库存在的问题,本篇在该库的基础上开发了新的服务类,主要用于发布shp普通tiff大型tiff,经过测试,该服务类可正常使用,可用于后端服务的构建

二、geoserver-restconfig

基于python语言开发的geoserver使用库,安装:pip install geoserver-restconfig

可进行工作区的创建删除、shp图层的创建删除、tiff图层的创建删除等。但是在使用时存在两个问题:

1、类实例化失败(requests版本为2.30):TypeError: Retry.__init__() got an unexpected keyword argument 'method_whitelist'

2、该库不支持切片tiff的发布

三、GeoServerCatalog

针对上述问题,对该库的核心类Catalog进行派生,主要做两个改动

3.1 重构create_coveragestore函数

该函数可用于栅格数据的发布,其中GeoTIFF类型就是tiff文件发布对应的类型,在我的另一篇文章:使用geoserver发布shp和tiff数据 中已经介绍了使用geoserver发布切片tiff目录的方法,对应的类型是ImagePyramid,但此类型在该类中没有(没有是正常的,因为切片tiff类型是通过插件方式增加的),所以我们重写该函数,在allowed_types中增加ImagePyramid即可,其他相同

3.2 重构setup_connection函数

经调试发现,Retry的报错是由于对象实例化时参数不对,主要是method_whitelist这个变量名不对,经过排查,确认是requests库的版本不对,2.30版本的Retry类用的是allowed_methods2.28版本用的是method_whitelist,为了兼容不同的版本,在派生类中重写该函数,通过try except来捕获由于版本差异导致的异常,在捕获异常时,使用另一版本的参数

3.3 源码

# GeoServerCatalog.pyimport osfrom geoserver.catalog import Catalog, ConflictingDataError, _name, FailedRequestErrorfrom geoserver.store import UnsavedCoverageStorefrom geoserver.support import build_urlimport requestsfrom requests.packages.urllib3.util.retry import Retryfrom requests.adapters import HTTPAdaptertry:from urllib.parse import urlparseexcept ImportError:from urlparse import urlparseclass GeoServerCatalog(Catalog):"""geoserver.Catalog的派生类用于扩展基类的create_coveragestore函数,使其支持"ImagePyramid"类型"""def __init__(self, service_url, username="admin", password="geoserver", validate_ssl_certificate=True, access_token=None, retries=3, backoff_factor=0.9):super().__init__(service_url, username, password, validate_ssl_certificate, access_token, retries, backoff_factor)def create_coveragestore(self, name, workspace=None, path=None, type='GeoTIFF',create_layer=True, layer_name=None, source_name=None, upload_data=False, contet_type="image/tiff",overwrite=False):"""Create a coveragestore for locally hosted rasters.If create_layer is set to true, will create a coverage/layer.layer_name and source_name are only used if create_layer ia enabled. If not specified, the raster name will be used for both."""if path is None:raise Exception('You must provide a full path to the raster')if layer_name is not None and ":" in layer_name:ws_name, layer_name = layer_name.split(':')allowed_types = ['ImageMosaic','GeoTIFF','Gtopo30','WorldImage','AIG','ArcGrid','DTED','EHdr','ERDASImg','ENVIHdr','GeoPackage (mosaic)','NITF','RPFTOC','RST','VRT','ImagePyramid']if type is None:raise Exception('Type must be declared')elif type not in allowed_types:raise Exception(f"Type must be one of {', '.join(allowed_types)}")if workspace is None:workspace = self.get_default_workspace()workspace = _name(workspace)if not overwrite:stores = self.get_stores(names=name, workspaces=[workspace])if len(stores) > 0:msg = f"There is already a store named {name} in workspace {workspace}"raise ConflictingDataError(msg)if upload_data is False:cs = UnsavedCoverageStore(self, name, workspace)cs.type = typecs.url = path if path.startswith("file:") else f"file:{path}"self.save(cs)if create_layer:if layer_name is None:layer_name = os.path.splitext(os.path.basename(path))[0]if source_name is None:source_name = os.path.splitext(os.path.basename(path))[0]data = f"<coverage><name>{layer_name}</name><nativeName>{source_name}</nativeName></coverage>"url = f"{self.service_url}/workspaces/{workspace}/coveragestores/{name}/coverages.xml"headers = {"Content-type": "application/xml"}resp = self.http_request(url, method='post', data=data, headers=headers)if resp.status_code != 201:raise FailedRequestError('Failed to create coverage/layer {} for : {}, {}'.format(layer_name, name,resp.status_code, resp.text))self._cache.clear()return self.get_resources(names=layer_name, workspaces=[workspace])[0]else:data = open(path, 'rb')params = {"configure": "first", "coverageName": name}url = build_url(self.service_url,["workspaces",workspace,"coveragestores",name,f"file.{type.lower()}"],params)headers = {"Content-type": contet_type}resp = self.http_request(url, method='put', data=data, headers=headers)if hasattr(data, "close"):data.close()if resp.status_code != 201:raise FailedRequestError('Failed to create coverage/layer {} for : {}, {}'.format(layer_name, name, resp.status_code, resp.text))return self.get_stores(names=name, workspaces=[workspace])[0]def setup_connection(self, retries=3, backoff_factor=0.9):self.client = requests.session()self.client.verify = self.validate_ssl_certificateparsed_url = urlparse(self.service_url)try:retry = Retry(total = retries or self.retries,status = retries or self.retries,read = retries or self.retries,connect = retries or self.retries,backoff_factor = backoff_factor or self.backoff_factor,status_forcelist = [502, 503, 504],allowed_methods = set(['HEAD', 'TRACE', 'GET', 'PUT', 'POST', 'OPTIONS', 'DELETE'])) # allowed_methods : requests > 2.30.0except TypeError:retry = Retry(total = retries or self.retries,status = retries or self.retries,read = retries or self.retries,connect = retries or self.retries,backoff_factor = backoff_factor or self.backoff_factor,status_forcelist = [502, 503, 504],method_whitelist = set(['HEAD', 'TRACE', 'GET', 'PUT', 'POST', 'OPTIONS', 'DELETE'])) # method_whitelist : requests <= 2.30.0self.client.mount(f"{parsed_url.scheme}://", HTTPAdapter(max_retries=retry))

四、GeoServerService

Catalog类提供的都是一些基本功能函数,为了能快速的发布数据,我们对GeoServerCatalog进行封装,构建GeoServerService类,该类主要用于实现发布shptiff金字塔tiff的功能

4.1 发布shp图层

函数名:createShapeLayer,参数如下。此函数可用于发布shp文件,其中styleParas是图层样式参数,用于控制图层的显示,主要支持点、线、多边形

workspaceName: 图层所在的工作空间的名称

layerName:图层的名称

shapePath:shape文件的路径

charset:dbf的字符集

styleParas:图层的样式参数,

point-{type:circle/rectangle/star, color:“#000000”, transparency:0.5, size:10}

polyline/line-{color:“#000000”, width:1}

polygon-{fill_color:“#AAAAAA”, outline_color:“#000000”, outline_width:1}

点的样式参数:

type:类型,支持圆、正方形、五角星

color: 颜色

transparency: 透明度

size: 大小

线的样式参数:

color: 颜色

width: 宽度

多边形的样式参数:

fill_color:填充颜色

outlin_color: 边框颜色

outline_width: 边框宽度

4.2 发布普通tiff图层

函数名:createTiffLayer,参数如下。此函数可用于发布<2GBtiff文件

workspaceName: 图层所在的工作空间的名称

layerName:图层的名称

tiffPath:tiff文件的路径

4.3 tiff切片

tiff切片需要用到gdal库,对应的下载地址为:windows版、linux版

下载的是whl类型的,可通过pip直接安装

该类中的createPyramidTiff可将tiff文件切片生成金字塔级别的目录,参数介绍如下

tiffPath:tiff文件的路径

tiffDir:生成的金字塔文件夹的路径

level:金字塔层级,可选,默认为4

blockWidth: 金字塔切块的宽度分辨率,可选,默认为2048

blockHeight: 金字塔切块的高度分辨率,可选,默认为2048

4.4 发布金字塔切片tiff图层

函数名:createPyramidTiff,参数如下。此函数可用于发布>=2GBtiff文件,该函数会自动调用上述的切片函数,并发布

tiffPath:tiff文件的路径

tiffDir:生成的金字塔文件夹的路径

level:金字塔层级,可选,默认为4

blockWidth: 金字塔切块的宽度分辨率,可选,默认为2048

blockHeight: 金字塔切块的高度分辨率,可选,默认为2048

4.5 其他函数

除了上述4个比较常用的函数外,还有如创建工作空间获取工作空间列表修改样式等函数,可自行研究,不再详述

4.6 源码

# GeoServerService.pyimport subprocessimport geoserver.utilfrom GeoServerCatalog import GeoServerCatalogclass GeoServerService(object):"""基于GeoServerCatalog库封装的常用服务类"""def __init__(self, url, username, password) -> None:self.__cat = GeoServerCatalog(url, username, password)def save(self, obj):self.__cat.save(obj)def getWorkspace(self, workspaceName):"""通过名称获取工作空间workspaceName: 工作空间的名称return Workspace"""return self.__cat.get_workspace(workspaceName)def isWorkspaceExist(self, workspaceName):"""判断工作空间是否存在workspaceName: 工作空间的名称return True-存在;False-不存在"""res = self.getWorkspace(workspaceName)if res == None:return Falseelse:return Truedef createWorkspace(self, workspaceName):"""创建工作空间workspaceName: 工作空间的名称return {status: 状态,success-创建成功;fail-创建失败info: 信息, success-""; fail-工作空间已存在;其他信息data: None}"""res = {"status": "fail","info": "","data": None}try:if self.isWorkspaceExist(workspaceName):res["info"] = "工作空间已存在:{0}".format(workspaceName)return resself.__cat.create_workspace(workspaceName, "http://{0}.com".format(workspaceName))res["status"] = "success"return resexcept Exception as e:res["info"] = repr(e)return resdef deleteWorkspace(self, workspaceName):"""删除工作空间(会删除工作空间下的所有内容,包括图层和样式)workspaceName: 工作空间的名称"""workspace = self.getWorkspace(workspaceName)if workspace != None:self.__cat.delete(workspace, None, True)def getStore(self, workspaceName, storeName):"""通过名称获取数据存储workspaceName: 数据存储所在的工作空间的名称storeName:数据存储的名称return Store"""return self.__cat.get_store(storeName, workspaceName)def isStoreExist(self, workspaceName, storeName):"""判断数据存储是否存在workspaceName: 数据存储所在的工作空间的名称storeName:数据存储的名称return True-存在;False-不存在"""res = self.getStore(workspaceName, storeName)if res == None:return Falseelse:return Truedef deleteStore(self, workspaceName, storeName):"""删除数据存储workspaceName: 数据存储所在的工作空间的名称storeName:数据存储的名称"""store = self.getStore(workspaceName, storeName)if store != None:self.__cat.delete(store, None, True)def getLayer(self, workspaceName, layerName):"""通过名称获取图层workspaceName: 图层所在的工作空间的名称layerName:图层的名称return Layer"""layerNameReg = "{0}:{1}".format(workspaceName, layerName)return self.__cat.get_layer(layerNameReg)def isLayerExist(self, workspaceName, layerName):"""判断图层是否存在workspaceName: 图层所在的工作空间的名称layerName:图层的名称return True-存在;False-不存在"""res = self.getLayer(workspaceName, layerName)if res == None:return Falseelse:return Truedef createShapeLayer(self, workspaceName, layerName, shapePath, charset):"""创建Shp图层workspaceName: 图层所在的工作空间的名称layerName:图层的名称shapePath:shape文件的路径charset:dbf的字符集styleParas:图层的样式参数, point-{type:circle/rectangle/star, color:"#000000", transparency:0.5, size:10}polyline/line-{color:"#000000", width:1}polygon-{fill_color:"#AAAAAA", outline_color:"#000000", outline_width:1}return {status: 状态,success-创建成功;fail-创建失败info: 信息, success-""; fail-工作空间不存在/图层已存在/其他信息data: Layer}"""res = {"status": "fail","info": "","data": None}try:# 判断工作空间是否存在if not self.isWorkspaceExist(workspaceName):res["info"] = "工作空间不存在:{0}".format(workspaceName)return res# 判断图层是否存在if self.isLayerExist(workspaceName, layerName):res["info"] = "图层已存在:{0}".format(layerName)return res# 创建图层workspace = self.getWorkspace(workspaceName)try:data = geoserver.util.shapefile_and_friends(shapePath)self.__cat.create_featurestore(layerName, data, workspace, True, charset)except Exception as e:res["info"] = "文件解析错误"return res# 获取创建的图层layer = self.getLayer(workspaceName, layerName)styleType = layer.default_style.nameres["status"] = "success"res["data"] = {"layer": layer,"default_style": styleType}return resexcept Exception as e:res["info"] = repr(e)return resdef __createTiffLayer(self, workspaceName, layerName, tiffPath, pyramid=False):"""创建Tiff图层workspaceName: 图层所在的工作空间的名称layerName:图层的名称tiffPath:tiff文件/夹的路径pyramid: 是否为金字塔结构,默认falsereturn {status: 状态,success-创建成功;fail-创建失败info: 信息, success-""; fail-工作空间不存在/图层已存在/其他信息data: {layer:生成的图层对象,default_style: 图层的默认样式}}"""res = {"status": "fail","info": "","data": None}try:# 判断工作空间是否存在if not self.isWorkspaceExist(workspaceName):res["info"] = "工作空间不存在:{0}".format(workspaceName)return res# 判断图层是否存在if self.isLayerExist(workspaceName, layerName):res["info"] = "图层已存在:{0}".format(layerName)return res# 创建图层workspace = self.getWorkspace(workspaceName)try:tiffType = "GeoTIFF"if pyramid:tiffType = "ImagePyramid"self.__cat.create_coveragestore(name=layerName, workspace=workspace, path=tiffPath, type=tiffType, layer_name=layerName)except Exception as e:res["info"] = "文件解析错误"return res# 获取创建的图层layer = self.getLayer(workspaceName, layerName)styleType = layer.default_style.nameres["status"] = "success"res["data"] = {"layer": layer,"default_style": styleType}return resexcept Exception as e:res["info"] = repr(e)return resdef createTiffLayer(self, workspaceName, layerName, tiffPath):"""创建Tiff图层:适用于文件大小<2GB的TiffworkspaceName: 图层所在的工作空间的名称layerName:图层的名称tiffPath:tiff文件的路径return {status: 状态,success-创建成功;fail-创建失败info: 信息, success-""; fail-工作空间不存在/图层已存在/其他信息data: Layer}"""return self.__createTiffLayer(workspaceName, layerName, tiffPath)def createPyramidTiff(self, tiffPath, tiffDir, levels=4, blockWidth=2048, blockHeight=2048):"""对tiff进行金字塔切片tiffPath:tiff文件的路径tiffDir:生成的金字塔文件夹的路径level:金字塔层级,可选,默认为4blockWidth: 金字塔切块的宽度分辨率,可选,默认为2048blockHeight: 金字塔切块的高度分辨率,可选,默认为2048"""exeStr = 'python gdal_retile.py -v -r bilinear -ot BYTE -levels {0} -ps {1} {2} -co "ALPHA=YES" -targetDir {3} {4}'.format(levels, blockWidth, blockHeight, tiffDir, tiffPath)process = subprocess.Popen(exeStr, shell=True)process.wait()def createPyramidTiffLayer(self, workspaceName, layerName, tiffPath, tiffDir, levels=4, blockWidth=2048, blockHeight=2048):"""创建金字塔切片后的Tiff图层:适用于文件大小>=2GB的TiffworkspaceName: 图层所在的工作空间的名称layerName:图层的名称tiffPath:tiff文件的路径tiffDir:生成的金字塔文件夹的路径level:金字塔层级,可选,默认为4blockWidth: 金字塔切块的宽度分辨率,可选,默认为2048blockHeight: 金字塔切块的高度分辨率,可选,默认为2048return {status: 状态,success-创建成功;fail-创建失败info: 信息, success-""; fail-工作空间不存在/图层已存在/其他信息data: {layer:生成的图层对象,default_style: 图层的默认样式}}"""res = {"status": "fail","info": "","data": None}try:# 先对tiff进行切片,生成金字塔结构目录try:self.createPyramidTiff(tiffPath, tiffDir, levels, blockWidth, blockHeight)except Exception as e:res["info"] = "切片错误"return res# 再创建金字塔数据图层return self.__createTiffLayer(workspaceName, layerName, tiffDir, True)except Exception as e:res["info"] = repr(e)return resdef deleteLayer(self, workspaceName, layerName):"""删除图层workspaceName: 图层所在的工作空间的名称layerName:图层的名称"""layer = self.getLayer(workspaceName, layerName)if layer != None:self.__cat.delete(layer, None, True)def __getPointStyle(self, styleParas):"""生成点类型的样式xmlstyleParas:样式参数 {type:circle/rectangle/star, color:"#000000", transparency:0.5, size:10}return xml"""type = "circle"if "type" in styleParas:type = styleParas["type"]color = "#000000"if "color" in styleParas:color = styleParas["color"]transparency = 0if "transparency" in styleParas:transparency = styleParas["transparency"]size = 1if "size" in styleParas:size = styleParas["size"]style = '<?xml version="1.0" encoding="UTF-8"?>\r\n \<StyledLayerDescriptor version="1.0.0" \r\n \xsi:schemaLocation="/sld StyledLayerDescriptor.xsd" \r\n \xmlns="/sld" \r\n \xmlns:ogc="/ogc" \r\n \xmlns:xlink="/1999/xlink" \r\n \xmlns:xsi="/2001/XMLSchema-instance">\r\n \<NamedLayer>\r\n \<Name>default_point</Name>\r\n \<UserStyle>\r\n \<FeatureTypeStyle>\r\n \<Rule>\r\n \<PointSymbolizer>\r\n \<Graphic>\r\n \<Mark>\r\n \<WellKnownName>{0}</WellKnownName>\r\n \<Fill>\r\n \<CssParameter name="fill">{1}</CssParameter>\r\n \<CssParameter name="fill-opacity">{2}</CssParameter>\r\n \</Fill>\r\n \</Mark>\r\n \<Size>{3}</Size>\r\n \</Graphic>\r\n \</PointSymbolizer>\r\n \</Rule>\r\n \</FeatureTypeStyle>\r\n \</UserStyle>\r\n \</NamedLayer>\r\n\</StyledLayerDescriptor>'.format(type, color, 1.0-transparency, size)return styledef __getPolylineStyle(self, styleParas):"""生成线类型的样式xmlstyleParas:样式参数 {color:"#000000", width:1}return xml"""color = "#000000"if "color" in styleParas:color = styleParas["color"]width = 1if "width" in styleParas:width = styleParas["width"]style = '<?xml version="1.0" encoding="UTF-8"?>\r\n \<StyledLayerDescriptor version="1.0.0" \r\n \xsi:schemaLocation="/sld StyledLayerDescriptor.xsd" \r\n \xmlns="/sld" \r\n \xmlns:ogc="/ogc" \r\n \xmlns:xlink="/1999/xlink" \r\n \xmlns:xsi="/2001/XMLSchema-instance">\r\n \<NamedLayer>\r\n \<Name>default_line</Name>\r\n \<UserStyle>\r\n \<FeatureTypeStyle>\r\n \<Rule>\r\n \<LineSymbolizer>\r\n \<Stroke>\r\n \<CssParameter name="stroke">{0}</CssParameter>\r\n \<CssParameter name="stroke-width">{1}</CssParameter>\r\n \</Stroke>\r\n \</LineSymbolizer>\r\n \</Rule>\r\n \</FeatureTypeStyle>\r\n \</UserStyle>\r\n \</NamedLayer>\r\n\</StyledLayerDescriptor>'.format(color, width)return styledef __getPolygonStyle(self, styleParas):"""生成多边形类型的样式xmlstyleParas:样式参数 {fill_color:"#AAAAAA", outline_color:"#000000", outline_width:1}return xml"""fill_color = "#AAAAAA"if "fill_color" in styleParas:fill_color = styleParas["fill_color"]outline_color = "#000000"if "outline_color" in styleParas:outline_color = styleParas["outline_color"]outline_width = 1if "outline_width" in styleParas:outline_width = styleParas["outline_width"]style = '<?xml version="1.0" encoding="UTF-8"?>\r\n \<StyledLayerDescriptor version="1.0.0" \r\n \xsi:schemaLocation="/sld StyledLayerDescriptor.xsd" \r\n \xmlns="/sld" \r\n \xmlns:ogc="/ogc" \r\n \xmlns:xlink="/1999/xlink" \r\n \xmlns:xsi="/2001/XMLSchema-instance">\r\n \<NamedLayer>\r\n \<Name>default_polygon</Name>\r\n \<UserStyle>\r\n \<FeatureTypeStyle>\r\n \<Rule>\r\n \<PolygonSymbolizer>\r\n \<Fill>\r\n \<CssParameter name="fill">{0}</CssParameter>\r\n \</Fill>\r\n \<Stroke>\r\n \<CssParameter name="stroke">{1}</CssParameter>\r\n \<CssParameter name="stroke-width">{2}</CssParameter>\r\n \</Stroke>\r\n \</PolygonSymbolizer>\r\n \</Rule>\r\n \</FeatureTypeStyle>\r\n \</UserStyle>\r\n \</NamedLayer>\r\n\</StyledLayerDescriptor>'.format(fill_color, outline_color, outline_width)return styledef getStyle(self, workspaceName, styleName):"""通过名称获取样式workspaceName: 样式所在的工作空间的名称styleName:样式的名称return Style"""return self.__cat.get_style(styleName, workspaceName)def isStyleExist(self, workspaceName, styleName):"""判断样式是否存在workspaceName: 样式所在的工作空间的名称styleName:样式的名称return True-存在;False-不存在"""res = self.getStyle(workspaceName, styleName)if res == None:return Falseelse:return Truedef createStyle(self, workspaceName, styleName, styleType, styleParas):"""创建样式workspaceName: 样式所在的工作空间的名称styleName:样式的名称styleType:样式的类型 point/polyline/line/polygonstyleParas: 样式的参数, point-{type:circle/rectangle/star, color:"#000000", transparency:0.5, size:10}polyline/line-{color:"#000000", width:1}polygon-{fill_color:"#AAAAAA", outline_color:"#000000", outline_width:1}return {status: 状态,success-创建成功;fail-创建失败info: 信息, success-""; fail-不支持的样式类型data: Style}"""res = {"status": "fail","info": "","data": None}styleData = Noneif styleType == "point":styleData = self.__getPointStyle(styleParas)elif styleType == "polyline" or styleType == "line":styleData = self.__getPolylineStyle(styleParas)elif styleType == "polygon":styleData = self.__getPolygonStyle(styleParas)else:res["info"] = "不支持的样式类型"return resstyle = self.__cat.create_style(styleName, styleData, overwrite=True, workspace=workspaceName)res["status"] = "success"res["data"] = stylereturn resdef deleteStyle(self, workspaceName, styleName):"""删除样式workspaceName: 样式所在的工作空间的名称styleName:样式的名称"""style = self.getStyle(workspaceName, styleName)if style != None:self.__cat.delete(style, None, True)def updateStyle(self, workspaceName, styleName, styleType, styleParas):"""更新样式workspaceName: 样式所在的工作空间的名称styleName:样式的名称styleType:样式的类型 point/polyline/line/polygonstyleParas: 样式的参数, point-{type:circle/rectangle/star, color:"#000000", transparency:0.5, size:10}polyline/line-{color:"#000000", width:1}polygon-{fill_color:"#AAAAAA", outline_color:"#000000", outline_width:1}return {status: 状态,success-创建成功;fail-创建失败info: 信息, success-""; fail-样式不存在/不支持的样式类型data: Style}"""res = {"status": "fail","info": "","data": None}if not self.isStyleExist(workspaceName, styleName):res["info"] = "样式不存在:{0}".format(styleName)return res# 获取样式style = self.getStyle(workspaceName, styleName)if styleType == "point":data = self.__getPointStyle(styleParas)elif styleType == "polyline" or styleType == "line":data = self.__getPolylineStyle(styleParas)elif styleType == "polygon":data = self.__getPolygonStyle(styleParas)else:res["info"] = "不支持的样式类型"return resstyle.update_body(data)res["status"] = "success"return resdef getWorkSpaces(self):return self.__cat.get_workspaces()

五、案例

在此提供3demo程序,分别是发布shp发布普通tiff发布大型tiff,创建成功后可通过geoserverweb应用程序进行验证

5.1 发布shp

# demo_publish_shp.py 演示案例:使用GeoServerService发布SHP服务from GeoServerService import GeoServerService# 初始化服务url = "http://localhost:8080/geoserver/rest" # geoserver urlusername = "admin" # geoserver usernamepassword = "geoserver" # geoserver passwordservice = GeoServerService(url, username, password)# 准备参数workspaceName = "test" # geoserver 工作空间名称layerName = "shp_layer" # geoserver 图层名称shapePath = "" # 用于发布的shp文件路径,精确到文件,不带后缀charset = "utf-8" # dbf文件的编码格式,不影响发布,主要影响发布后的属性拾取,如果编码格式不对,拾取到的中文属性会乱码# 检查工作空间是否存在,如果不存在,则创建if not service.isWorkspaceExist(workspaceName):service.createWorkspace(workspaceName)# 检查图层是否已存在,如果存在,则删除if service.isStoreExist(workspaceName, layerName):service.deleteStore(workspaceName, layerName)# 发布图层 res = service.createShapeLayer(workspaceName, layerName, shapePath, charset)print(res)

5.2 发布普通tiff

# demo_publish_tiff.py 演示案例:使用GeoServerService发布普通TIFF(<2GB)服务from GeoServerService import GeoServerService# 初始化服务url = "http://localhost:8080/geoserver/rest" # geoserver urlusername = "admin" # geoserver usernamepassword = "geoserver" # geoserver passwordservice = GeoServerService(url, username, password)# 准备参数workspaceName = "test" # geoserver 工作空间名称layerName = "tiff_layer" # geoserver 图层名称tiffPath = "" # 用于发布的TIFF文件路径# 检查工作空间是否存在,如果不存在,则创建if not service.isWorkspaceExist(workspaceName):service.createWorkspace(workspaceName)# 检查图层是否已存在,如果存在,则删除if service.isStoreExist(workspaceName, layerName):service.deleteStore(workspaceName, layerName)# 发布图层 res = service.createTiffLayer(workspaceName, layerName, tiffPath)print(res)

5.3 发布大型tiff

# demo_publish_pyramid_tiff.py 演示案例:使用GeoServerService发布金字塔切片的TIFF(>=2GB)服务import osimport shutilfrom GeoServerService import GeoServerService# 初始化服务url = "http://localhost:8080/geoserver/rest" # geoserver urlusername = "admin" # geoserver usernamepassword = "geoserver" # geoserver passwordservice = GeoServerService(url, username, password)# 准备参数workspaceName = "test" # geoserver 工作空间名称layerName = "pyramid_tiff_layer" # geoserver 图层名称tiffPath = "" # 用于发布的TIFF文件路径tiffDir = "" # 切片后生成的TIFF金字塔文件夹路径levels = 4 # 金字塔层级blockWidth = 2048 # 金字塔每个块的宽度blockHeight = 2048 # 金字塔每个块的高度# 检查待生成的文件夹是否存在,如果存在则清空,否则创建if os.path.isdir(tiffDir):shutil.rmtree(tiffDir) os.mkdir(tiffDir)# 检查工作空间是否存在,如果不存在,则创建if not service.isWorkspaceExist(workspaceName):service.createWorkspace(workspaceName)# 检查图层是否已存在,如果存在,则删除if service.isStoreExist(workspaceName, layerName):service.deleteStore(workspaceName, layerName)# 发布图层res = service.createPyramidTiffLayer(workspaceName, layerName, tiffPath, tiffDir, levels, blockWidth, blockHeight)print(res)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。