图层和数据源

图层(Layer)是在地图上的一种数据组织方法。

图层可以是栅格层(raster)或矢量层(vector),栅格层由栅格图像(像素矩阵)组成,而矢量层由矢量几何图形组成。

瓦片层(TileLayer)

瓦片层(Tile Layer)的源需要能提供预渲染的地图瓦片,这些瓦片按缩放级别不同(在特定分辨率展示)提供不同的瓦片矩阵。

更多详情请参阅 TileLayer 文档

TileLayer 支持三种源:

OsmSource

这个源的瓦片数据是从 OpenStreetMap 瓦片服务和 XYZ tile 服务加载。更多详情请参阅 OSM 文档

下面的示例演示了如何展示 OpenStreetMap 瓦片层。

<maps:geoMap id="map"
             height="100%"
             width="100%">
    <maps:layers>
        <maps:tile>
            <maps:osmSource/>
        </maps:tile>
    </maps:layers>
</maps:geoMap>

XyzSource

这个源的瓦片数据是在 URL 模板中定义一组 XYZ 格式的 URL。默认情况下,遵循 Google 矩阵的定义:x 0 和 y 0 位于左上角。XyzSource 可以加载 XYZ tile 服务提供的瓦片。更多详情请参阅 XYZ 文档

下面的示例演示了如何展示 Thunderforest 瓦片层。

<maps:geoMap id="mapxyz"
             width="100%"
             height="100%">
    <maps:layers>
        <maps:tile>
            <maps:xyzSource
                    url="https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=YOUR_API_KEY">
            </maps:xyzSource>
        </maps:tile>
    </maps:layers>
</maps:geoMap>

WmsSource

这个源的瓦片数据是从 WMS(Web Map Service)服务加载。更多详情请参阅 TileWMS 文档

下面的示例演示了如何展示 WmsSource 瓦片层。

<maps:geoMap id="mapwms"
             width="100%"
             height="100%">
    <maps:layers>
        <maps:tile>
            <maps:tileWmsSource url="https://ahocevar.com/geoserver/wms"
                                serverType="GEO_SERVER">
                <maps:parameters>
                    <maps:parameter name="LAYERS" value="topp:states"/>
                    <maps:parameter name="TILED" value="true"/>
                </maps:parameters>
            </maps:tileWmsSource>
        </maps:tile>
    </maps:layers>
</maps:geoMap>

图像层(ImageLayer)

ImageLayer 用于处理静态图片或 WMS 图片。

ImageStaticSource

这个源展示单一静态图片。更多详情请参阅 Static 文档

展示 URL 图片的示例。这个示例取自 OpenLayers → Examples → Static image

<maps:geoMap id="mapimagestatic"
             width="100%"
             height="100%">
    <maps:mapView centerX="512" centerY="479" zoom="2">
        <maps:projection code="static-image"
                         units="PIXELS">
            <maps:extent minX="0" minY="0" maxX="1024" maxY="968"/>
        </maps:projection>
    </maps:mapView>
    <maps:layers>
        <maps:image id="imageLayer">
            <maps:imageStaticSource projection="static-image"
                                    url="https://imgs.xkcd.com/comics/online_communities.png">
                <maps:projection code="static-image"
                                 units="PIXELS">
                    <maps:extent minX="0" minY="0" maxX="1024" maxY="968"/>
                </maps:projection>
                <maps:imageExtent minX="0" minY="0" maxX="1024" maxY="968"/>
            </maps:imageStaticSource>
        </maps:image>
    </maps:layers>
</maps:geoMap>

如需展示 classpath 中的图片,可以按照下面示例中的方法在 XML 定义:

<maps:geoMap id="declarativeMap"
             width="100%"
             height="100%">
    <maps:mapView centerX="450" centerY="522" zoom="2">
        <maps:projection code="static-image"
                         units="PIXELS">
            <maps:extent minX="0" minY="0" maxX="900" maxY="1044"/>
        </maps:projection>
    </maps:mapView>
    <maps:layers>
        <maps:image id="dImageLayer">
            <maps:imageStaticSource url="maps/map.png">
                <maps:projection code="static-image"
                                 units="PIXELS">
                    <maps:extent minX="0" minY="0" maxX="900" maxY="1044"/>
                </maps:projection>
                <maps:imageExtent minX="0" minY="0" maxX="900" maxY="1044"/>
            </maps:imageStaticSource>
        </maps:image>
    </maps:layers>
</maps:geoMap>

此外,在 Java 控制器中可以通过 StreamResource 实现:

@ViewComponent
protected GeoMap programmaticMap;

@Subscribe
protected void onInit(final InitEvent event) {
    ImageLayer imageLayer = programmaticMap.getLayer("pImageLayer");
    ImageStaticSource staticSource = imageLayer.getSource();
    staticSource.setResource(new StreamResource("map.png", () -> {
        try {
            return new ClassPathResource("META-INF/resources/maps/map.png").getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }));
}

ImageWmsSource

这个源从 WMS 服务加载单一未命名图片。更多详情请参阅 ImageWMS 文档

使用 ImageWmsSource 的示例取自 OpenLayers → Examples → Single Image WMS

<maps:geoMap id="mapimagewms"
             width="100%"
             height="100%">
    <maps:layers>
        <maps:tile>
            <maps:osmSource/>
        </maps:tile>
        <maps:image>
            <maps:imageWmsSource url="https://ahocevar.com/geoserver/wms"
                                 ratio="1"
                                 serverType="GEO_SERVER">
                <maps:parameters>
                    <maps:parameter name="LAYERS" value="topp:states"/>
                </maps:parameters>
            </maps:imageWmsSource>
            <maps:extent minX="-124.43" minY="24.57" maxX="-66.58" maxY="49.22"/>
        </maps:image>
    </maps:layers>
</maps:geoMap>

矢量层(VectorLayer)

矢量层用于处理几何图形。一个地图可以添加多个矢量层。

VectorSource

这个源处理地图要素。更多详情请参阅 VectorSource 文档

下面的示例演示了如何展示 VectorSource 矢量层。首先,在 XML 中定义一个地图:

<maps:geoMap id="mapwithvector"
             width="100%"
             height="100%">
    <maps:layers>
        <maps:tile>
            <maps:osmSource/>
        </maps:tile>
        <maps:vector id="vectorLayer">
            <maps:vectorSource/>
        </maps:vector>
    </maps:layers>
</maps:geoMap>

然后,打开视图控制器并在地图中添加标记:

@ViewComponent
private GeoMap mapwithvector;

@Subscribe
protected void onInit(final InitEvent event) {
    VectorLayer vectorLayer = mapwithvector.getLayer("vectorLayer"); (1)
    VectorSource vectorSource = vectorLayer.getSource(); (2)
    vectorSource.addFeature(new MarkerFeature(createPoint(0, 0)));(3)
}
1 通过 ID 获取矢量层。
2 用矢量源处理要素(Polygon, LineString, Point)。
3 添加标记要素。

DataVectorSource

DataVectorSource 支持通过 dataContainerproperty 属性绑定 Jmix 数据容器。property 可以是属性名或者属性路径。

<maps:geoMap id="map" height="100%" width="100%">
    <maps:layers>
        <maps:tile>
            <maps:osmSource/>
        </maps:tile>
        <maps:vector id="vectorLayer">
            <maps:dataVectorSource dataContainer="locationDc"
                                   property="building"/>
        </maps:vector>
    </maps:layers>
    <maps:mapView centerY="51.0">
        <maps:extent minX="-15.0"
                     minY="30.0"
                     maxX="40.0"
                     maxY="60.0"/>
    </maps:mapView>
</maps:geoMap>
<maps:vector id="vectorLayer">
    <maps:dataVectorSource dataContainer="ordersDc"
                           property="customer.address.point"/>
</maps:vector>