2

Using GeoExt 3.1.0, OL 4.4.1 and ExtJS 6.2.0

I have only been using GIS for a few days.

I am trying to make the fit function to make the center of the layer appear in the middle of the panel marked as the center region. Similar to using the ZoomToExtent function but I want it to happen right from the moment the map shows on screen.

This is the code in full - notice the MARKED LINE:

//map.js
Ext.require([
    'GeoExt.component.Map',
    'GeoExt.data.store.LayersTree'
]);
var mapComponent;
var mapPanel;
var treePanel;
var descriptionPanel;
var title;

Ext.application({
    name: 'BasicTree',
    launch: function() {
        var source1 = new ol.source.TileWMS({
            url: 'http://localhost:8080/geoserver/wms',
            params: {'LAYERS': 'ws_geodeleg:prov', 'VERSION': '1.3.0'}
        });
        var layer1 = new ol.layer.Tile({
            source: source1,
            name: 'P'
        });
        var source2 = new ol.source.TileWMS({
            url: 'http://localhost:8080/geoserver/wms',
            params: {'LAYERS': 'ws_geodeleg:muni', 'VERSION': '1.3.0'}
        });
        var layer2 = new ol.layer.Tile({
            source: source2,
            name: 'M'
        });

        var view = new ol.View({
            center: ol.proj.fromLonLat([-79, 22.7]), // <-- MARKED LINE
            zoom: 8
        });
        var map = new ol.Map({
            layers: [
                layer1, layer2
            ],
            view: view,
            controls: ol.control.defaults({
                attributionOptions: {
                    collapsible: false
                }
            }).extend([
                new ol.control.ZoomToExtent({
                    extent: view.getProjection().getExtent()
                }),
                new ol.control.MousePosition({numDigits: 2})
            ])
        });
//        var layerExtent = layer1.getExtent();
//        console.log(layerExtent);                      <-- COMMENTED LINES
//        map.getView().fit(layerExtent, map.getSize());
        mapComponent = Ext.create('GeoExt.component.Map', {
            map: map
        });
        var treeStore = Ext.create('GeoExt.data.store.LayersTree', {
            layerGroup: map.getLayerGroup()
        });

        treePanel = Ext.create('Ext.tree.Panel', {
            title: 'Tree Example',
            viewConfig: {
                plugins: {ptype: 'treeviewdragdrop'}
            },
            store: treeStore,
            rootVisible: false,
            border: false
        });
        descriptionPanel = Ext.create('Ext.panel.Panel', {
            contentEl: 'content-el',
            title: 'Description',
            border: false,
        });

        Ext.create('Ext.panel.Panel', {
            width: '100%',
            height: document.documentElement.clientHeight,
            title: 'Title',
            layout: {
                type: 'border'
            },
            items: [
                {
                    title: 'South Region is resizable',
                    region: 'south',
                    height: '20%',
                    split: true,
                    collapsible: true,
                    margin: '0 5 5 5'
                },
                {
                    title: 'West Region is collapsible',
                    region: 'west',
                    margin: '5 0 0 5',
                    width: '15%',
                    split: true,
                    collapsible: true,
                    id: 'west-region-container',
                    items: [treePanel, descriptionPanel]
                },
                {
                    title: 'Map',
                    region: 'center',
                    margin: '5 5 0 0',
                    items: [mapComponent]
                }],
            renderTo: Ext.getBody()
        });
    }
});

The MARKED LINE contains the coordinates that make the layer show on the center of the map (as desired) I got to them via trial and error, the whole point is to achieve this without having to hard-code the coordinates.

The COMMENTED LINES contain the code that is supposed to let me achieve the goal but instead results in: AssertionError: Assertion failed. See https://openlayers.org/en/v4.4.1/doc/errors/#24 for details.; when I indeed follow the link it shows `Invalid extent or geometry provided as geometry.

EDIT

//@ThomasG77: this is your code with slight mods
    <script>
        var parser = new ol.format.WMSCapabilities();

        fetch('http://localhost:8080/geoserver/ows?service=wms&version=1.3.0&request=GetCapabilities', {mode: 'cors'}).then(function(response) {
          return response.text();
        }).then(function(text) {

          var result = parser.read(text);
          var extent = result.Capability.Layer.Layer.find(l => l.Name === 'ws_geodeleg:prov').EX_GeographicBoundingBox;

        proj4.defs("EPSG:3795","+proj=lcc +lat_1=23 +lat_2=21.7 +lat_0=22.35 +lon_0=-81 +x_0=500000 +y_0=280296.016 +datum=NAD27 +units=m +no_defs");
          var extentTransform = ol.proj.transform(extent, 'EPSG:4326', 'EPSG:3795');
          var layers = [
            new ol.layer.Tile({
              source: new ol.source.OSM()
            }),
            new ol.layer.Image({
              source: new ol.source.ImageWMS({
                url: 'http://localhost:8080/geoserver/wms',
                params: {'LAYERS': 'ws_geodeleg:prov'},
                ratio: 1,
                serverType: 'geoserver'
              })
            })
          ];
          var map = new ol.Map({
            layers: layers,
            target: 'map',
            view: new ol.View({
              center: ol.extent.getCenter(extentTransform),
              zoom: 4
            })
          });
        });
</script>
0

1 Answer 1

4

In your code, you are using getExtent for layer1. According to the API docs, it "returns the extent of the layer".

Then if you look at what is an extent for an ol.layer.Tile (e.g layer1). It's "the bounding extent for layer rendering. The layer will not be rendered outside of this extent."

Conclusion: you need to get the extent from somewhere but as you are not using an ol.layer.Vector, you can't get geometries and deduce the extent (as a WMS is not a vector layer)

The way to get extent & center "magically" is to get the "capabilities" from the WMS layer considering you already set in GeoServer the extent using the layer data (see http://docs.geoserver.org/latest/en/user/data/webadmin/layers.html#bounding-boxes)

What are "capabilities"? It's informations about available layers using OGC web Services (here WMS). You can get more detailed informations about each layer including bounds.

You can find a prototype showing how you can use them. As I don't own the remote demo GeoServer, I suffered some limitations in the prototype. The layer center seems to be the CRS center instead of the layer data center.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.