Igor-Vladyka / leaflet.browser.print

A leaflet plugin which allows users to print the map directly from the browser
https://igor-vladyka.github.io/leaflet.browser.print/
MIT License
154 stars 76 forks source link

The print page does not show the style created with leaflet.pattern.js plugin #98

Closed sgrandstrand closed 3 years ago

sgrandstrand commented 3 years ago

I have a layer styled with a stripe pattern using the leaflet.pattern.js plugin. When I print that layer it converts the style to leaflet's default blue and I receive the error " Unknown layer, cannot clone this layer. Leaflet version 1.5+HEAD.2e30ff'.

what_it_should_look_like

printissue

Console_Error

Here is the layer object: layerObject

Below is the style function:

function stylegwdepbuff(feature) {
    var pattern_gwdepbuff = new L.StripePattern({
        weight: 2,
        spaceWeight: 10,
        color: '#000000',
        opacity: 1.0,
        spaceOpacity: .5,
        angle: 315
    });
    pattern_gwdepbuff.addTo(map);
    var x = document.getElementById("fillop_gwdepbuff");
    var currentfillop = x.value;
    return {
        fillOpacity: currentfillop,
        stroke: false,
        interactive: true,
        fillPattern: pattern_gwdepbuff
    };
}

I also tried adding the pattern at 'print start' which did not work:

var pattern_gwdepbuff = new L.StripePattern({
    weight: 2,
    spaceWeight: 10,
    color: '#000000',
    opacity: 1.0,
    spaceOpacity: .5,
    angle: 315
});
pattern_gwdepbuff.addTo(map);

map.on("browser-print-start", function (e) {
    L.control.scale({
        position: 'bottomright',
        metric: false,
        maxWidth: 200
    }).addTo(e.printMap);
    pattern_gwdepbuff.addTo(e.printMap);
});

Is there a work around to show the pattern?

Igor-Vladyka commented 3 years ago

Hi Sarah,

Please refer to this section on registering unknown layers: new-print-layersrenderers-registration

But in general it should look like something like this: You need to add next section before first print action (preferably at the same time when you add plugin to the map)

L.Control.BrowserPrint.Utils.registerLayer(
    L.StripePattern,
    'L.StripePattern',
    function (layer, utils) {
        return new L.StripePattern(layer.options); // You may need to play here to create proper new object.
    });

Regards. Igor

sgrandstrand commented 3 years ago

I appreciate the quick response! I've implemented your code before my first print action as below:

var pattern_gwdepbuff = new L.StripePattern({
    weight: 2,
    spaceWeight: 10,
    color: '#000000',
    opacity: 1.0,
    spaceOpacity: .5,
    angle: 315
});
pattern_gwdepbuff.addTo(map);

L.Control.BrowserPrint.Utils.registerLayer(
    L.StripePattern,
    'L.StripePattern',
    function (layer, utils) {
        return new L.StripePattern(layer.options); 
    }
);

I don't receive the error anymore however, now the layer doesn't show up at all. When I console log the 'layer.options' I see the correct style information but I must be missing a step for the layer/data to be added to the print page?

image

I've tried the following variations which showed the same results (no error and no layer). Any guidance would be greatly appreciated!

Variation 1.

L.Control.BrowserPrint.Utils.registerLayer(
    L.StripePattern,
    'L.StripePattern',
    function (layer, utils) {
        return new L.StripePattern(utils.cloneOptions(layer.options)); 
    }
);

Variation 2.

L.Control.BrowserPrint.Utils.registerLayer(
    L.StripePattern,
    'L.StripePattern',
    function (layer, utils) {
        var pattern = new L.StripePattern(layer.options);
        pattern.addLayers(utils.cloneLayer(layer));
        return pattern
       }
);

Variation 3.

L.Control.BrowserPrint.Utils.registerRenderer(
    L.StripePattern,
    'L.StripePattern');

Thank you! Sarah

Igor-Vladyka commented 3 years ago

Hello again,

Strange, I would need to take a look/debug it a bit. Would you like to setup a jsbin(or any different) with a simple example so that we can validate any future fix? And I may use it for debugging.

Regards, Igor

sgrandstrand commented 3 years ago

Yes, here is a simple example in js bin:

https://jsbin.com/qobunom/edit?html,css,js,console,output

I have the "L.Control.BrowserPrint.Utils.registerLayer" function commented out because it was giving an error that it was not a function which wasn't happening on my actual project.

Igor-Vladyka commented 3 years ago

Hello.

Okay, I found the problem. Pattern plugin design is not fully consistent with Leaflet architecture(what I mean is that you should not add stripe_pattern object itself to the map, if you are adding it as an other layer option), therefore more code needs to be added.

-- Here we register needed layer
L.Control.BrowserPrint.Utils.registerLayer(
    L.StripePattern,
    'L.StripePattern',
    function (layer, utils) {
        return new L.StripePattern(layer.options);
    });

-- Here we get freshly cloned stripe pattern object and add it to print overly map.
map.on(L.Control.BrowserPrint.Event.PrintStart, function(e){ 
  e.printObjects["L.Polygon"].forEach(f => f.options.fillPattern ? f.options.fillPattern.addTo(e.printMap) : null);
});

Regards, Igor

sgrandstrand commented 3 years ago

That worked! Thank you very much for taking the time to debug with me.

Cheers! Sarah