Search code examples
javascriptphppromiseleafletpdfmake

How i can rotate a custom markers in Leaflet for PDF (in website works)


i work on create a PDF from Leaflet map with custom icons, and I rotate these icons to angle for track report(cars). I use leaflet-image plugin to create the image from map and then I use pdfmake to add the image to PDF (PDF contains map, table and canvas JS charts). Everything works fine (the markers rotate on website) but when I add map image to my PDF the markers don't have a rotation.

I add the image with rotation with these code

var marker=[
  <?php foreach($track as $key => $value){ ?>L.marker([
  <?php echo $value['Y']; ?>,
  <?php echo $value['X']; ?>],{icon: icon
  <?php echo $value['Eng']; ?>, rotationAngle: 
  <?php echo $value['Angle']; ?> }).bindPopup("
  <?php echo date("Y-m-d H:i:s", $key); ?> / speed: 
  <?php echo $value['Speed']; ?> km/h." ),
  <?php } ?>
<?php ?>]

I was looking for other libraries that can solve my problem.

I get the image with these code

 var icon3 = L.icon({
    iconUrl: 'images/direction_green.png',
    iconSize:     [12, 12],
    iconAnchor:   [0, 0],
    popupAnchor:  [15, -8]
    });

    var icon2 = L.icon({
    iconUrl: 'images/stop_green.png',
    iconSize:     [12, 12],
    iconAnchor:   [0, 0],
    popupAnchor:  [15, -8]
    });

    var icon1 = L.icon({
    iconUrl: 'images/stop_blue.png',
    iconSize:     [12, 12], 
    iconAnchor:   [0, 0],
    popupAnchor:  [15, -8]
    });

    var icon0 = L.icon({
    iconUrl: 'images/stop_black.png',
    iconSize:     [12, 12],
    iconAnchor:   [0, 0],
    popupAnchor:  [15, -8]
    });

Then I use the corresponding status marker for the car (engine onn, engine off, etc...)

I see the problem is this rotation is the html rotation. Can i rotate the image with js/jQuery before add to my map? I get the image with:

iconUrl: 'images/stop_black.png

I have one more problem: I do not have the circles and the line in my PDF. In website everything in fine again.

Thanks for your help


Solution

  • This is the answer for my question. I hope to help someone. The plugin leaflat-rotate-marker use css to rotate the markers and when i use plugin leaflat-image to create the image from map the markers in PDF don't have a rotation becouse leaflat image don't work with html and css. My compleate code is this:

    processArray(js_tracks); //call processArray with my array
    
    async function processArray(array) {
        shelterMarkers.eachLayer(function(layer){ //remove previous markers because i call this function onload and on map zoomed.  
            mymap.removeLayer(layer);
        });
    
        for (let item of array) {
            if(icontmp[item['Reakt']][item['Angle']] != -1){ //array icontmp is my cash for previous created markers.
                var iUrl = icontmp[item['Reakt']][item['Angle']];
            }
            else{ // if i don't have cashed markers with same angel await for delayedLog where i rotate the markers by angle and specific condition (item['Reakt'])
                icontmp[item['Reakt']][item['Angle']] = await delayedLog(item['Angle'], item['Reakt']);
                var iUrl = icontmp[item['Reakt']][item['Angle']];           
            }
    
            var ico = L.icon({ //create a object with marker
                iconUrl: iUrl,
                iconSize: [(4.5*(mymap.getZoom()))/2, (4.5*(mymap.getZoom()))/2], // resize by map zoom
                iconAnchor: [15, 15],
                popupAnchor: [-10, -10]
            });
    
            L.marker([item['Y'], item['X']], // add X and Y cordinats
            {icon: ico})
            .bindPopup("<p>Време: "+item['dateTime']+" </p><p> скорост: "+item['Speed']+" км/ч.</p><p> Реакция: "+item['Reaktion']+" </p><p> "+item['Engine']+" </p>" ).addTo(shelterMarkers); // add to shelterMarkers
        }
        shelterMarkers.addTo(mymap); // add to map when ready
    }
    
    
    function delayedLog(angles, reak){
         if(reak == 0){
             var imgs = '<?php echo base_url();?>/images/stop_blue.png';
         }
         else if(reak == 1){
             var imgs = '<?php echo base_url();?>/images/stop_green.png';
         }
         else if(reak == 2){
             var imgs = '<?php echo base_url();?>/images/direction_green.png';
         }
         else if(reak == 3){
             var imgs = '<?php echo base_url();?>/images/stop_red.png';
         } 
         else if(reak == 4){
             var imgs = '<?php echo base_url();?>/images/direction_red.png';
         }
         else{
             var imgs = '<?php echo base_url();?>/images/stop_black.png';
         }
    
        var image = loadImage(imgs).then(function (img) { //there i wait for load a image resource. Without it sometimes loading an empty blank instead of a finished image. loadImage is a function from plugin image-promise.min.js
    
            let canvass = document.createElement('canvas');
            let context = canvass.getContext('2d');
            canvass.width = 50;
            canvass.height = 50;
            context.translate(15, 15);
            context.rotate(angles*Math.PI/180); //rotate by angle
            context.translate(-15, -15);
            context.drawImage(img, 0, 0, img.width, img.height);
            return canvass.toDataURL(); // when ready return dataurl
        })
        return image; // return dataurl to processArray
    }