基于geoserver的伪三维地图制作

实现2.5维地图
本文介绍如何使用geoserver和openlayers等开源工具实现2.5维地图效果,并通过不同比例尺设置来切换二维与2.5维显示。

小伙伴在用百度高德这类地图的时候有木有发现当地图放大到一定倍数之后就会出现三维效果(2.5纬)。作为一个爱寻根究底的人,我们一定会问,这种地图是如何实现的呢?基于arcgis或者超图吗?NONONO,这类软件太贵!基于Unity3D这类开源的三维引擎做的?NONONO,这是真三维地图。笔者的原则就是能用开源软件就绝不会用商业软件。由于现在主流的制作web地图的开源软件是geoserver+openlayers+postgresql。因此笔者就思索如何基于geoserver和openlayer制作一个伪三维地图。

由于geoserver不支持直接导入三维模型,隐藏笔者直接着眼于sld,看看能不能通过sld来表达三维效果,经过网上的搜索,找到了类似的配置,试验一下成功。

<?xml version="1.0" encoding="ISO-8859-1"?>  
<StyledLayerDescriptor version="1.0.0"   
    xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"   
    xmlns="http://www.opengis.net/sld"   
    xmlns:ogc="http://www.opengis.net/ogc"   
    xmlns:xlink="http://www.w3.org/1999/xlink"   
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
    <!-- a Named Layer is the basic building block of an SLD document -->  
    <NamedLayer>  
        <Name>default_polygon</Name>  
        <UserStyle>  
            <!-- Styles can have names, titles and abstracts -->  
            <Title>Default Polygon</Title>  
            <Abstract>A sample style that draws a polygon</Abstract>  
            <!-- FeatureTypeStyles describe how to render different features -->  
            <!-- A FeatureTypeStyle for rendering polygons -->  
            <FeatureTypeStyle>  
                <Rule>  
                    <PolygonSymbolizer>  
                        <Geometry>  
                            <ogc:Function name="isometric">  
                                <ogc:PropertyName>geom</ogc:PropertyName>  
                                <ogc:Literal>0.00001</ogc:Literal>  
                            </ogc:Function>  
                        </Geometry>  
                        <Fill>  
                            <CssParameter name="fill">#dddddd</CssParameter>  
                        </Fill>  
                        <Stroke>  
                            <CssParameter name="stroke">#999999</CssParameter>  
                            <CssParameter name="stroke-width">0.1</CssParameter>  
                        </Stroke>  
                    </PolygonSymbolizer>  
                </Rule>  
            </FeatureTypeStyle>  
            <FeatureTypeStyle>  
                <Rule>  
                    <PolygonSymbolizer>  
                        <Geometry>  
                            <ogc:Function name="offset">  
                                <ogc:PropertyName>geom</ogc:PropertyName>  
                                <ogc:Literal>0</ogc:Literal>  
                                <ogc:Literal>0.00001</ogc:Literal>  
                            </ogc:Function>  
                        </Geometry>  
                        <Fill>  
                            <CssParameter name="fill">#ffffe0</CssParameter>  
                        </Fill>  
                        <Stroke>  
                            <CssParameter name="stroke">#999999</CssParameter>  
                            <CssParameter name="stroke-width">0.1</CssParameter>  
                        </Stroke>  
                    </PolygonSymbolizer>  
                </Rule>  
            </FeatureTypeStyle>  
        </UserStyle>  
    </NamedLayer>  
</StyledLayerDescriptor>

OK,可以看到三维效果。

但是,总感觉有点不对劲。于是打开百度地图,看看别人家的实现。发现他们在地图缩小的时候是二维效果,只有当地图放大到一定级别之后才会显示2.5纬效果。这种效果如何实现呢?很简单。把地图的样式设为按照比例尺进行表达,不同的比例尺有不同的效果了,当放大到设定的比例尺时显示三维效果。

<?xml version="1.0" encoding="UTF-8"?>
<sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0">
    <sld:UserLayer>
        <sld:LayerFeatureConstraints>
            <sld:FeatureTypeConstraint/>
        </sld:LayerFeatureConstraints>
        <sld:UserStyle>
            <sld:Name>hikvision2qi b3 tingchewei</sld:Name>
            <sld:FeatureTypeStyle>
                <sld:Name>group 0</sld:Name>
                <sld:FeatureTypeName>Feature</sld:FeatureTypeName>
                <sld:SemanticTypeIdentifier>generic:geometry</sld:SemanticTypeIdentifier>
                <sld:SemanticTypeIdentifier>simple</sld:SemanticTypeIdentifier>
                <sld:Rule>
                    <sld:Name>Large</sld:Name>
                    <sld:MaxScaleDenominator>200.0</sld:MaxScaleDenominator>
                    <sld:PolygonSymbolizer>
					 <sld:Geometry>  
                            <ogc:Function name="isometric">  
                                <ogc:PropertyName>geom</ogc:PropertyName>  
                                <ogc:Literal>0.00001</ogc:Literal>  
                            </ogc:Function>  
                        </sld:Geometry>  
                        <sld:Fill>
                            <sld:CssParameter name="fill">#FFE7A6</sld:CssParameter>
                        </sld:Fill>
                        <sld:Stroke>
                            <sld:CssParameter name="stroke">#E8D1AE</sld:CssParameter>
                            <sld:CssParameter name="stroke-width">0.2</sld:CssParameter>
                        </sld:Stroke>
                    </sld:PolygonSymbolizer>
                    <sld:TextSymbolizer>
                        <sld:Label>
                            <ogc:PropertyName>number</ogc:PropertyName>
                        </sld:Label>
                        <sld:Font>
                            <sld:CssParameter name="font-family">Arial</sld:CssParameter>
                            <sld:CssParameter name="font-size">12.0</sld:CssParameter>
                            <sld:CssParameter name="font-style">normal</sld:CssParameter>
                            <sld:CssParameter name="font-weight">normal</sld:CssParameter>
                        </sld:Font>
                        <sld:LabelPlacement>
                            <sld:PointPlacement>
                                <sld:AnchorPoint>
                                    <sld:AnchorPointX>0.5</sld:AnchorPointX>
                                    <sld:AnchorPointY>0.5</sld:AnchorPointY>
                                </sld:AnchorPoint>
                                <sld:Displacement>
                                    <sld:DisplacementX>0.0</sld:DisplacementX>
                                    <sld:DisplacementY>0.0</sld:DisplacementY>
                                </sld:Displacement>
                                <sld:Rotation>
                                    <ogc:PropertyName>lblrotate</ogc:PropertyName>
                                </sld:Rotation>
                            </sld:PointPlacement>
                        </sld:LabelPlacement>
                        <sld:Fill>
                            <sld:CssParameter name="fill">#404040</sld:CssParameter>
                        </sld:Fill>
                        <sld:VendorOption name="maxDisplacement">0</sld:VendorOption>
						<sld:VendorOption name="spaceAround">-5</sld:VendorOption>
                    </sld:TextSymbolizer>
                </sld:Rule>
                <sld:Rule>
                    <sld:Name>small</sld:Name>
                    <sld:MinScaleDenominator>200.0</sld:MinScaleDenominator>
                    <sld:MaxScaleDenominator>400.0</sld:MaxScaleDenominator>
                    <sld:PolygonSymbolizer>
                        <sld:Fill>
                            <sld:CssParameter name="fill">#FFE7A6</sld:CssParameter>
                        </sld:Fill>
                        <sld:Stroke>
                            <sld:CssParameter name="stroke">#E8D1AE</sld:CssParameter>
                            <sld:CssParameter name="stroke-width">0.2</sld:CssParameter>
                        </sld:Stroke>
                    </sld:PolygonSymbolizer>
                    <sld:TextSymbolizer>
                        <sld:Label>
                            <ogc:PropertyName>number</ogc:PropertyName>
                        </sld:Label>
                        <sld:Font>
                            <sld:CssParameter name="font-family">Arial</sld:CssParameter>
                            <sld:CssParameter name="font-size">10.0</sld:CssParameter>
                            <sld:CssParameter name="font-style">normal</sld:CssParameter>
                            <sld:CssParameter name="font-weight">normal</sld:CssParameter>
                        </sld:Font>
                        <sld:LabelPlacement>
                            <sld:PointPlacement>
                                <sld:AnchorPoint>
                                    <sld:AnchorPointX>0.5</sld:AnchorPointX>
                                    <sld:AnchorPointY>0.5</sld:AnchorPointY>
                                </sld:AnchorPoint>
                                <sld:Displacement>
                                    <sld:DisplacementX>0.0</sld:DisplacementX>
                                    <sld:DisplacementY>0.0</sld:DisplacementY>
                                </sld:Displacement>
                                <sld:Rotation>
                                    <ogc:PropertyName>lblrotate</ogc:PropertyName>
                                </sld:Rotation>
                            </sld:PointPlacement>
                        </sld:LabelPlacement>
                        <sld:Fill>
                            <sld:CssParameter name="fill">#404040</sld:CssParameter>
                        </sld:Fill>
                        <sld:VendorOption name="maxDisplacement">0</sld:VendorOption>
            <sld:VendorOption name="spaceAround">-5</sld:VendorOption>
                    </sld:TextSymbolizer>
                </sld:Rule>
         <sld:Rule>
                    <sld:Name>medium</sld:Name>
                    <sld:MinScaleDenominator>400.0</sld:MinScaleDenominator>
                    <sld:MaxScaleDenominator>600.0</sld:MaxScaleDenominator>
                    <sld:PolygonSymbolizer>
                        <sld:Fill>
                            <sld:CssParameter name="fill">#FFE7A6</sld:CssParameter>
                        </sld:Fill>
                        <sld:Stroke>
                            <sld:CssParameter name="stroke">#E8D1AE</sld:CssParameter>
                            <sld:CssParameter name="stroke-width">0.2</sld:CssParameter>
                        </sld:Stroke>
                    </sld:PolygonSymbolizer>
                    <sld:TextSymbolizer>
                        <sld:Label>
                            <ogc:PropertyName>number</ogc:PropertyName>
                        </sld:Label>
                        <sld:Font>
                            <sld:CssParameter name="font-family">Arial</sld:CssParameter>
                            <sld:CssParameter name="font-size">6.0</sld:CssParameter>
                            <sld:CssParameter name="font-style">normal</sld:CssParameter>
                            <sld:CssParameter name="font-weight">normal</sld:CssParameter>
                        </sld:Font>
                        <sld:LabelPlacement>
                            <sld:PointPlacement>
                                <sld:AnchorPoint>
                                    <sld:AnchorPointX>0.5</sld:AnchorPointX>
                                    <sld:AnchorPointY>0.5</sld:AnchorPointY>
                                </sld:AnchorPoint>
                                <sld:Displacement>
                                    <sld:DisplacementX>0.0</sld:DisplacementX>
                                    <sld:DisplacementY>0.0</sld:DisplacementY>
                                </sld:Displacement>
                                <sld:Rotation>
                                    <ogc:PropertyName>lblrotate</ogc:PropertyName>
                                </sld:Rotation>
                            </sld:PointPlacement>
                        </sld:LabelPlacement>
                        <sld:Fill>
                            <sld:CssParameter name="fill">#404040</sld:CssParameter>
                        </sld:Fill>
                        <sld:VendorOption name="maxDisplacement">0</sld:VendorOption>
            <sld:VendorOption name="spaceAround">-5</sld:VendorOption>
                    </sld:TextSymbolizer>
                </sld:Rule>
                <sld:Rule>
                    <sld:Name>Smallest</sld:Name>
                    <sld:MinScaleDenominator>600.0</sld:MinScaleDenominator>
                    <sld:PolygonSymbolizer>
                        <sld:Fill>
                            <sld:CssParameter name="fill">#FFE7A6</sld:CssParameter>
                        </sld:Fill>
                        <sld:Stroke>
                            <sld:CssParameter name="stroke">#E8D1AE</sld:CssParameter>
                            <sld:CssParameter name="stroke-width">0.2</sld:CssParameter>
                        </sld:Stroke>
                    </sld:PolygonSymbolizer>
                </sld:Rule>
            </sld:FeatureTypeStyle>
			<sld:FeatureTypeStyle>  
                <sld:Rule>
					<sld:Name>Large</sld:Name>
                    <sld:MaxScaleDenominator>200.0</sld:MaxScaleDenominator>				
                    <sld:PolygonSymbolizer>  
                        <sld:Geometry>  
                            <ogc:Function name="offset">  
                                <ogc:PropertyName>geom</ogc:PropertyName>  
                                <ogc:Literal>0</ogc:Literal>  
                                <ogc:Literal>0.00001</ogc:Literal>  
                            </ogc:Function>  
                        </sld:Geometry>  
                        <sld:Fill>  
                            <sld:CssParameter name="fill">#d8e5f2</sld:CssParameter>  
                        </sld:Fill>  
                        <sld:Stroke>  
                            <sld:CssParameter name="stroke">#999999</sld:CssParameter>  
                            <sld:CssParameter name="stroke-width">0.1</sld:CssParameter>  
                        </sld:Stroke>  
                    </sld:PolygonSymbolizer>  
                </sld:Rule>  
            </sld:FeatureTypeStyle>   
        </sld:UserStyle>
    </sld:UserLayer>
</sld:StyledLayerDescriptor>


### GeoServer 支持的三维地图服务类型及功能 GeoServer 虽然以其强大的二维地图服务能力闻名,但在三维地图服务的支持方面也有一定的扩展性和潜力。尽管其原生功能并不完全专注于三维领域,但可以通过与其他技术栈集成来实现丰富的三维地图服务。 #### 1. **WMS 3D 扩展** 虽然标准 WMS 主要针对二维地图设计,但一些客户端(如 OpenLayers 或 Cesium)已经实现了对 WMS 数据的三维渲染支持。这意味着即使 GeoServer 自身不直接提供专门的三维服务接口,也可以借助这些客户端工具将发布的 WMS 层转化为三维视图[^2]。例如,在 Cesium 中加载来自 GeoServer 的 WMS 图层后,可以利用地形数据叠加形成逼真的三维效果。 #### 2. **与外部三维框架结合** 为了更好地满足日益增长的三维需求,GeoServer 可以配合其他专业的三维 GIS 平台共同作业。比如提到过的企业级解决方案 GeniusWorld 2.0 C 版本便具备强大而全面的三维处理能力,包括但不限于 SG 格式、Geo3DML 格式以及初步兼容 BIM 和 3DTiles 数据的能力[^3]。这种组合方式不仅保留了 GeoServer 在传统矢量/栅格数据分发上的优势,还弥补了自身对于复杂三维场景构建经验不足的问题。 #### 3. **实验性质插件开发** 社区贡献者们也在不断探索新的可能性,尝试为 GeoServer 添加更多面向未来的三维特性。目前已有若干处于测试阶段或者有限可用状态下的插件项目致力于增强该产品的立体表现力,像 CityGML 插件就是其中一个例子,它允许导入并共享城市级别规模内的精细建筑模型集合[^4]。 综上所述,尽管当前版本下 GeoServer 对应于纯粹意义上的独立型完整三维地图服务体系尚显稚嫩;然而凭借灵活开放架构所带来的无限延展空间,再加上周边生态系统的鼎力相助,则完全可以胜任大多数常规性的三维地理信息展示任务。 ```javascript // 示例代码片段 - 在 Cesium 中加载 GeoServer 发布的 WMS 图层作为三维底图 var viewer = new Cesium.Viewer('cesiumContainer'); var imageryLayer = new Cesium.WebMapServiceImageryProvider({ url : 'http://localhost:8080/geoserver/wms', layers : 'topp:states' }); viewer.imageryLayers.addImageryProvider(imageryLayer); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值