1. 程式人生 > >基於geoserver的偽三維地圖製作

基於geoserver的偽三維地圖製作

小夥伴在用百度高德這類地圖的時候有木有發現當地圖放大到一定倍數之後就會出現三維效果(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>