0

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>
  • 1
    Replace ol.proj.transform(extent, 'EPSG:4326', 'EPSG:3795') with ol.proj.transform(extent, 'EPSG:4326', 'EPSG:3857') You original data in your GeoServer seems to be 3795 but if you use default configuration in OpenLayers, the SRS/CRS is 3857. You only need "EPSG:3795" if you need to visualise data in this projection as you didn't make this choice at the moment. Normally, 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"); is not needed the way you made your code. – ThomasG77 Jan 22 '18 at 19:48
  • @ThomasG77; I'm not sure what you mean by visualize data in this projection (is it showing info on the layer in the future? because if it is, I'm certainly going to be doing that) but for the sake of the problem at hand I just changed what you pointed in your comment and now I'm shipwrecked in the middle of the Atlantic, somewhere between the Leeward Antilles (East of the Caribbean) and Cabo Verde (West of Senegal). I promise I have not changed my code after this. But honestly, and this must be minimal-understanding-on-the-topic speaking how could it be otherwise, if what I need is for...... – Scaramouche Jan 22 '18 at 20:55
  • @ThomasG77;.....the map to center on my layer, how come any reference of my layer is nowhere in the code? – Scaramouche Jan 22 '18 at 20:57
  • 1
    It's start to be difficult to help more: I don't have access to your map server & normally if you do a console.log(ol.extent.getCenter(extent).slice(0).reverse()); you will be able to troubleshot the issue (to see if it's on client or server side). The JavaScript code will return the center in latitude, longitude. You can use these 2 values by copying them in search box of openstreetmap.org to find where it is. – ThomasG77 Jan 22 '18 at 21:11
  • i was just going to comment a retraction on my last comment, I forgot that in the declaration of var extent there IS a reference to my layer, now I'll get to it and debug using your last insight. 1up for your help, thanx – Scaramouche Jan 22 '18 at 21:15
3

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.

  • sorry for being off the grid for so long. I'm getting this warning (?): Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/geoserver/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities. (Reason: CORS header 'Access-Control-Allow-Origin' missing). and this error: TypeError: NetworkError when attempting to fetch resource.. And also, is it ok/the same using ol.layer.Image and source: new ol.source.ImageWMS instead of ol.layer.Tile and source: new ol.source.TileWMS? – Scaramouche Jan 22 '18 at 14:06
  • The usual suspect. Configure your GeoServer with CORS support. If using Jetty docs.geoserver.org/latest/en/user/production/… If using Tomcat enable-cors.org/server_tomcat.html Not "georelated", see developer.mozilla.org/en-US/docs/Web/HTTP/CORS to learn more about it – ThomasG77 Jan 22 '18 at 17:33
  • yeah, i have been running around that cors aspect for a couple hours now, think i got it working (for) now, after that with your code and a tiny modification to fit my needs it shows the OSM layer and mine but it centers somewhere around NW Africa, not on the desired location (my layer - ESPG:3759), please please review my edit and tell me if you (hopefully) see anything wrong – Scaramouche Jan 22 '18 at 18:08
  • sorry, it's ESPG:3795 – Scaramouche Jan 22 '18 at 19:49
  • Thanks for sharing this interesting solution. I am in the middle of trying it (see my question). Hopefully I'll be doing it right. – umbe1987 Apr 3 '18 at 10:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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