3

How can I get base layers added to an OpenLayers map using the OpenLayers.Layer.XYZ method to print in MapFish/GeoServer?

The Geoserver/Mapfish print service is not printing any of my XYZ base layers (USGS and ESRI). The print works fine for my OpenStreetMap WMS layer and the WMS layers I get from Geoserver on my localhost. This is a new problem, prior to this I exclusively used WMS layers. Now I have a mix of WMS and XYZ (REST) layers. I am using GeoServer 2.8.1, OpenLayers 2.12, GeoExt 1.1, and MapFish. Upgrading to new versions of any of the software is out of the question. The example below shows my working code. The only issue is that the WMS layers print and the XYZ (REST) layer does not print so I know the code works - except for the XYZ issue;

This is how I reference one of the XYZ layers that are added to the OpenLayers map;

var usgs_imagerytopo = new OpenLayers.Layer.XYZ("USGS Imagery Topo",
                "https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/${z}/${y}/${x}",
              { isBaseLayer: false, layerID: "base_usgsimagerytopo", lyrClass: 'base', opacity: 1.0 });

This is how I reference the OpenStreetMap WMS layer that is added to the OpenLayers map;

var OSM = new OpenLayers.Layer.WMS("Street Maps",
           "http://ows.terrestris.de/osm/service?",
           { layers: 'OSM-WMS', isBaseLayer: false }, { layerID: "base_osm", lyrClass: 'base' });

Then I create the JSON that MapFish/Geoserver needs;

//we need the center location for the map so get the lon/lat from the OpenLayers map - this gets used in the JSON
    
    var bbox = map.getCenter();

//Then we need the map extent - this gets used in the JSON

var mxExtent = map.getExtent();

//Create the JSON we will use to get the map data
    var specs = {
        "layout": "Legal",//the name of page layoutfrom my config.yaml
        "srs": "EPSG:3857",//also tried using 4326 & 900913 here but did not fix the XYZ issue
        "units": "meters",//also tried degrees here but did not fix the XYZ issue
        "dpi": 96,
        "geodetic": true,//because all my base layers are Spherical Mercator
        "outputFormat": "pdf",
        "layers": [
            {
                "type": "WMS",
                "layers": ["Tracts"],
                "baseURL": "http://99.99.99.9996:8080/geoserver/wms",//generic IP to protect anonymity
                "format": "image/png"
            },
             {
                 "type": "XYZ",//required
                 "baseURL": "https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile",
                 //"maxExtent": [-2.0037507745622717E7, -3.024147837580217E7, 2.0039165759998567E7, 3.0240971992746655E7], //required
                 "maxExtent": mxExtent,
                 "tileSize": [256, 256],//required
                 "resolutions": [156543.03392800014, 78271.51696399994, 39135.75848200009, 9567.87924099992, 9783.93962049996, 4891.96981024998, 2445.98490512499,
                 1222.992452562495, 611.4962262813797, 305.74811314055756, 152.87405657041106, 76.43702828507324, 38.21851414253662, 19.10925707126831, 9.554628535634155,
                 4.77731426794937, 2.388657133974685, 1.1943285668550503, 0.5971642835598172, 0.29858214164761665], //current map resolution, i.e [40], required
                 "extension": "",//required
                 "path_format": '/${z}/${x}/${y}'//optional
             }
         ],
        "pages": [
             {
                "center": [bbox.lon, bbox.lat],
                "scale":24000
            }
        ],
            "printURL": "http:\/\/99.99.99.999:8080\/geoserver\/pdf\/print.pdf",
            "createURL": "http:\/\/99.99.99.999:8080\/geoserver\/pdf\/create.json"
        };

//Stringify the JSON so the parser can parse it.
        var json = encodeURI(JSON.stringify(specs));
        var newScale = "set";

Then construct the GeoExt stuff and print the map;

        // The printProvider that connects us to the print service
        var printProvider = new GeoExt.data.PrintProvider({
            url: 'http://99.99.99.999:8080/geoserver/pdf/print.pdf?spec=' + json,
            method: "POST", // "POST" recommended for production use
            autoLoad: true,
            capabilities: printCapabilities, // from my config.yaml
            customParams: {
                mapTitle: "Title <here>",
                comment: "Comment <here>",
                defScale: newScale
            }
        });
        // Our print page. Tells the PrintProvider about the scale and center of
        // our page.
        var printPage = new GeoExt.data.PrintPage({
            printProvider: printProvider

        });
        printPage.fit(mapPanel, true);
        printProvider.print(mapPanel, printPage);

And here is my config.yaml;

===========================================================================
allowed DPIs
===========================================================================
dpis: [75, 96, 150, 300]


===========================================================================
 the allowed scales
===========================================================================
scales:
  - 1
  - 94
  - 3960
  - 6000
  - 7920
  - 12000
  - 15840
  - 18000
  - 21600
  - 24000
  - 28800
  - 31680
  - 63360
  - 126720
  - 316800
  - 633600
  - 1267200


formats:
  - pdf
  - png
  - JPG
  - jpg



===========================================================================
 the list of allowed hosts
===========================================================================
hosts:
  - !localMatch
    dummy: true
  - !dnsMatch
    host: www.mywebportal.com
    port: 8080
  - !dnsMatch
    host: terraservice.net
    port: 80
  - !dnsMatch
    host: basemap.nationalmap.gov
  - !dnsMatch
    host: www.geocommunicator.gov
  - !dnsMatch
    host: demo.mapfish.org
  - !dnsMatch
    host: raster.nationalmap.gov
  - !dnsMatch
    host: services.nationalmap.gov
  - !dnsMatch
    host: ows.terrestris.de
  - !dnsMatch
    host: server.arcgisonline.com
  - !dnsMatch
    host: services.nationalmap.gov


layouts:
  Legal:
    mainPage:
      pageSize: LEGAL
      items:
        - !map
          spacingAfter: 30
          width: 500
          height: 700
  #===========================================================================
  Incorporated Inc.:
  #===========================================================================
    metaData:
#      title: '${mapTitle}'
      author: 'Incorporated Inc.'
      subject: 'Simple layout'
      keywords: 'map,print'
      creator: Incorporated Inc.'

    titlePage:
      pageSize: A4
      items:
        - !text
          spacingAfter: 150
        - !text
          font: Helvetica
          fontSize: 40
          spacingAfter: 25
          align: center
          text: '${layout}'
        - !text
          font: Helvetica
          fontSize: 11
          spacingAfter: 5
          align: center
          text: '100 Main Street'
        - !text
          font: Helvetica
          fontSize: 11
          spacingAfter: 5
          align: center
          text: 'Anywhere, US 99999'
        - !text
          font: Helvetica
          fontSize: 11
          spacingAfter: 50
          align: center
          text: 'xxx-xxx-xxxx'



    #-------------------------------------------------------------------------
    mainPage:
      pageSize: A4
      rotation: true
      header:
        height: 50
        items:
          - !text
            font: Helvetica
            fontSize: 20
            align: right
            text: '${layout}'
      items:
        - !text
          text: '${mapTitle}'
          fontSize: 20
          spacingAfter: 30
          align: 'center'
        - !map
          spacingAfter: 10
          width: 525
          height: 680
          borderWidth: 3
        - !columns
          # columns can have an absolute position. In that case, they need the 3 following fields:
          absoluteX: 420
          absoluteY: 100
          width: 100
          items:
            - !scalebar
              type: bar
              maxSize: 100
              barBgColor: white
              fontSize: 8
              align: right
              units: ft
        - !text
          text: '${comment}'
          spacingAfter: 10
        - !attributes
          source: data
          spacingAfter: 30
          columnDefs:
            id:
              columnWeight: 2
              header: !text
                text: ID
                backgroundColor: #A0A0A0
              cell: !text
                text: '${id}'
            name:
              columnWeight: 5
              header: !text
                text: Name
                backgroundColor: #A0A0A0
              cell: !columns
                config:
                  cells:
                    - backgroundColor: '${nameBackgroundColor}'
                      borderWidth: 1
                      borderColor: '${nameBorderColor}'
                items:
                  - !text
                    text: '${name}'
            icon:
              columnWeight: 2
              header: !text
                text: Symbol
                backgroundColor: #A0A0A0
              cell: !image
                align: center
                maxWidth: 15
                maxHeight: 15
                url: 'http://www.mapfish.org/svn/mapfish/trunk/MapFish/client/mfbase/mapfish/img/${icon}.png'
        - !text
          font: Helvetica
          fontSize: 9
          align: right
          text: 'Scale = N/A   Date: ${now MM.dd.yyyy}'
      footer: *commonFooter

So the actual printing works and any layers on top of the XYZ base layers print, but the base layers do not. How can I get the XYZ base layers to print?

5

1 Answer 1

0

SOLUTION:

Edit GeoExt/data/PrintProvider.js to include this block of code in the "encoders" section;

Line 649      "XYZ": function (layer) {
Line 650                var enc = this.encoders.layers.TileCache.call(this, layer);
Line 651                return Ext.apply(enc, {
Line 652                    type: 'XYZ',
Line 653                    baseURL: enc.baseURL.substr(0, enc.baseURL.indexOf("$")),
Line 654                    extension: enc.baseURL.substr(enc.baseURL.lastIndexOf("$")).split(".").pop(),
Line 655                    path_format: '${z}/${y}/${x}',//IMPORTANT - without this the XYZ layers wont print to MapFish because the x&y in the request HTTP will be reversed
Line 656                    tileOriginCorner: layer.tileOriginCorner
Line 657                });
Line 658            },
1
  • If it works for you, mark it as answered.
    – TomazicM
    Commented Feb 17, 2019 at 11:16

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.