2

I wanted to put a hyperlink for each station of my layer "dots" and I would like thereafter in my web page: to click directly on a station to send me to the concerned page.

Indeed, I added a hyperlink for each entity in the table of matter of my layer dots under QGIS but afterwards when I click on each station in the web page, it shows me first the link and then you must click on this link to send me on the page concerned.

enter image description here

enter image description here

My goal is to click on a station and then it sends me directly on the concerned page without seeing the hyperlink.

Would it be possible to do this under QGIS> qgis2web> leaflet ?

Or Is there a possibility to put a hyperlink in the code of my layer dots under leaflet code ?

I created a local folder (station.rar see link below) including the code and files needed to display the web page.

https://www.mediafire.com/file/57uo7lmey0jfr2z/station.rar/file

Indeed I created a station named "station" with a hyperlink: https://en.wikipedia.org/wiki/Mediterranean_Sea

I also display the code (index.html) below:

Can you please test your answer above from the attached file?

I am really grateful for your help!

cordially

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1,user-scalable=no,maximum-scale=1,width=device-width">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <link rel="stylesheet" href="css/leaflet.css">
    <link rel="stylesheet" href="css/qgis2web.css"><link rel="stylesheet" href="css/fontawesome-all.min.css">
    <link rel="stylesheet" href="css/leaflet-control-geocoder.Geocoder.css">
    <link rel="stylesheet" href="css/leaflet-measure.css">
    <style>
    html, body, #map {
        width: 100%;
        height: 100%;
        padding: 0;
        margin: 0;
    }
    </style>
    <title></title>
</head>
<body>
    <div id="map">
    </div>
    <script src="js/qgis2web_expressions.js"></script>
    <script src="js/leaflet.js"></script>
    <script src="js/leaflet.rotatedMarker.js"></script>
    <script src="js/leaflet.pattern.js"></script>
    <script src="js/leaflet-hash.js"></script>
    <script src="js/Autolinker.min.js"></script>
    <script src="js/rbush.min.js"></script>
    <script src="js/labelgun.min.js"></script>
    <script src="js/labels.js"></script>
    <script src="js/leaflet-control-geocoder.Geocoder.js"></script>
    <script src="js/leaflet-measure.js"></script>
    <script src="data/Station_1.js"></script>
    <script>
    var map = L.map('map', {
        zoomControl:true, maxZoom:28, minZoom:1
    }).fitBounds([[35.3701192694662,0.6251400322704415],[42.89228098757654,10.473650199904672]]);
    var hash = new L.Hash(map);
    map.attributionControl.setPrefix('<a href="https://github.com/tomchadwin/qgis2web" target="_blank">qgis2web</a> &middot; <a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>');
    var measureControl = new L.Control.Measure({
        position: 'topleft',
        primaryLengthUnit: 'meters',
        secondaryLengthUnit: 'kilometers',
        primaryAreaUnit: 'sqmeters',
        secondaryAreaUnit: 'hectares'
    });
    measureControl.addTo(map);
    document.getElementsByClassName('leaflet-control-measure-toggle')[0]
    .innerHTML = '';
    document.getElementsByClassName('leaflet-control-measure-toggle')[0]
    .className += ' fas fa-ruler';
    var bounds_group = new L.featureGroup([]);
    function setBounds() {
    }
    var layer_OpenStreetMap_0 = L.tileLayer('http://a.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        opacity: 1.0,
        attribution: '',
    });
    layer_OpenStreetMap_0;
    map.addLayer(layer_OpenStreetMap_0);
    function pop_Station_1(feature, layer) {
        var popupContent = '<table>\
                <tr>\
                    <th scope="row">Nom</th>\
                    <td>' + (feature.properties['Nom'] !== null ? Autolinker.link(String(feature.properties['Nom'])) : '') + '</td>\
                </tr>\
                <tr>\
                    <th scope="row">Lien</th>\
                    <td>' + (feature.properties['Lien'] !== null ? Autolinker.link(String(feature.properties['Lien'])) : '') + '</td>\
                </tr>\
            </table>';
        layer.bindPopup(popupContent, {maxHeight: 400});
    }

    function style_Station_1_0() {
        return {
            pane: 'pane_Station_1',
            radius: 8.0,
            opacity: 1,
            color: 'rgba(35,35,35,1.0)',
            dashArray: '',
            lineCap: 'butt',
            lineJoin: 'miter',
            weight: 1,
            fill: true,
            fillOpacity: 1,
            fillColor: 'rgba(227,26,28,1.0)',
        }
    }
    map.createPane('pane_Station_1');
    map.getPane('pane_Station_1').style.zIndex = 401;
    map.getPane('pane_Station_1').style['mix-blend-mode'] = 'normal';
    var layer_Station_1 = new L.geoJson(json_Station_1, {
        attribution: '',
        pane: 'pane_Station_1',
        onEachFeature: pop_Station_1,
        pointToLayer: function (feature, latlng) {
            var context = {
                feature: feature,
                variables: {}
            };
            return L.circleMarker(latlng, style_Station_1_0(feature));
        },
    });
    bounds_group.addLayer(layer_Station_1);
    map.addLayer(layer_Station_1);
    var osmGeocoder = new L.Control.Geocoder({
        collapsed: true,
        position: 'topleft',
        text: 'Search',
        title: 'Testing'
    }).addTo(map);
    document.getElementsByClassName('leaflet-control-geocoder-icon')[0]
    .className += ' fa fa-search';
    document.getElementsByClassName('leaflet-control-geocoder-icon')[0]
    .title += 'Search for a place';
    var baseMaps = {};
    L.control.layers(baseMaps,{'<img src="legend/Station_1.png" /> Station': layer_Station_1,"OpenStreetMap": layer_OpenStreetMap_0,},{collapsed:false}).addTo(map);
    setBounds();
    var i = 0;
    layer_Station_1.eachLayer(function(layer) {
        var context = {
            feature: layer.feature,
            variables: {}
        };
        layer.bindTooltip((layer.feature.properties['Nom'] !== null?String('<div style="color: #e31a1c; font-size: 14pt; font-family: \'MS Shell Dlg 2\', sans-serif;">' + layer.feature.properties['Nom']) + '</div>':''), {permanent: true, offset: [-0, -16], className: 'css_Station_1'});
        labels.push(layer);
        totalMarkers += 1;
          layer.added = true;
          addLabel(layer, i);
          i++;
    });
    resetLabels([layer_Station_1]);
    map.on("zoomend", function(){
        resetLabels([layer_Station_1]);
    });
    map.on("layeradd", function(){
        resetLabels([layer_Station_1]);
    });
    map.on("layerremove", function(){
        resetLabels([layer_Station_1]);
    });
    </script>
</body>

  • You'll have to look into the leaflet documentation to see if this is possible as qgis2web only creates a popup with the attributes. – Techie_Gus Oct 7 at 13:11
2

One possible solution for this would be to attach click event to circle marker and on mouse click open desired web page in new window. Text info could be bound to marker tooltip to be shown upon mouse over.

Relevant code could then look something like this:

function tooltip_Sonde_2(feature, layer) {
  var tooltipContent = '<table>\
    <tr>\
        <th scope="row">Nom</th>\
        <td>' + feature.properties['Nom'] + '</td>\
    </tr>\
    <tr>\
        <th scope="row">Lien</th>\
        <td>' + feature.properties['Lien'] + '</td>\
    </tr>\
  </table>';
  layer.bindTooltop(tooltipContent, {maxHeight: 400});
}

function link_from_property(property) {
  var link
  // code to get hyperlink from property 
  return link;
}

var layer_Sonde_2 = new L.geoJson(json_Sonde_2, {
  attribution: '',
  pane: 'pane_Sonde_2',
  onEachFeature: tooltip_Sonde_2,
  pointToLayer: function (feature, latlng) {
    var marker = L.circleMarker(latlng, style_Sonde_2_0(feature));
    if (feature.properties['Nom'] !== null) {
      marker.on('click', function(evt) {
        window.open(link_from_property(String(evt.target.feature.properties['Nom'])), '_blank');
      });
      }
    else if (feature.properties['Lien'] !== null) {
      marker.on('click', function(evt) {
        window.open(link_from_property(String(evt.target.feature.properties['Lien'])), '_blank');
      });
    }
    return marker;
  }
});

I used mock function link_from_property to get link from feature property, since I'm not familiar with the logic of Autolinker.link function.

EDIT: Applying the above logic to your additionally published full code, where I could test it, I did the following modifications:

  1. Replaced your popup_Station_1 function with tooltip_Station_1 function, where I moved your popup definition.
  2. Added click event processing function to your circle marker definition, where click event opens new browse windows with desired hyperlink.

So the changed parts of code now look like this (vertical points denote that code is missing there):

.
.
// popup_Station_1  replaced with tooltip_Station_1
function tooltip_Station_1(feature, layer) {
  layer.bindTooltip((feature.properties['Nom'] !== null?String('<div style="color: #e31a1c; font-size: 14pt; font-family: \'MS Shell Dlg 2\', sans-serif;">' + feature.properties['Nom']) + '</div>':''), {permanent: true, offset: [-0, -16], className: 'css_Station_1'});
}
.
.
var layer_Station_1 = new L.geoJson(json_Station_1, {
  attribution: '',
  pane: 'pane_Station_1',
  onEachFeature: tooltip_Station_1,
  pointToLayer: function (feature, latlng) {
    var context = {
      feature: feature,
      variables: {}
    };
    var marker = L.circleMarker(latlng, style_Station_1_0(feature));
    marker.on('click', function(evt) {
      window.open(String(evt.target.feature.properties['Lien']), '_blank');
    });
    return marker;
  },
});
.
.
layer_Station_1.eachLayer(function(layer) {
  var context = {
    feature: layer.feature,
    variables: {}
  };
  labels.push(layer);
  totalMarkers += 1;
  layer.added = true;
  addLabel(layer, i);
  i++;
});
.
.

EDIT2: And here is the whole code:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="initial-scale=1,user-scalable=no,maximum-scale=1,width=device-width">
        <meta name="mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <link rel="stylesheet" href="css/leaflet.css">
        <link rel="stylesheet" href="css/qgis2web.css"><link rel="stylesheet" href="css/fontawesome-all.min.css">
        <link rel="stylesheet" href="css/leaflet-control-geocoder.Geocoder.css">
        <link rel="stylesheet" href="css/leaflet-measure.css">
        <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            padding: 0;
            margin: 0;
        }
        </style>
        <title></title>
    </head>
    <body>
        <div id="map">
        </div>
        <script src="js/qgis2web_expressions.js"></script>
        <script src="js/leaflet.js"></script>
        <script src="js/leaflet.rotatedMarker.js"></script>
        <script src="js/leaflet.pattern.js"></script>
        <script src="js/leaflet-hash.js"></script>
        <script src="js/Autolinker.min.js"></script>
        <script src="js/rbush.min.js"></script>
        <script src="js/labelgun.min.js"></script>
        <script src="js/labels.js"></script>
        <script src="js/leaflet-control-geocoder.Geocoder.js"></script>
        <script src="js/leaflet-measure.js"></script>
        <script src="data/Station_1.js"></script>
        <script>
        var map = L.map('map', {
            zoomControl:true, maxZoom:28, minZoom:1
        }).fitBounds([[35.3701192694662,0.6251400322704415],[42.89228098757654,10.473650199904672]]);
        var hash = new L.Hash(map);
        map.attributionControl.setPrefix('<a href="https://github.com/tomchadwin/qgis2web" target="_blank">qgis2web</a> &middot; <a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>');
        var measureControl = new L.Control.Measure({
            position: 'topleft',
            primaryLengthUnit: 'meters',
            secondaryLengthUnit: 'kilometers',
            primaryAreaUnit: 'sqmeters',
            secondaryAreaUnit: 'hectares'
        });
        measureControl.addTo(map);
        document.getElementsByClassName('leaflet-control-measure-toggle')[0]
        .innerHTML = '';
        document.getElementsByClassName('leaflet-control-measure-toggle')[0]
        .className += ' fas fa-ruler';
        var bounds_group = new L.featureGroup([]);
        function setBounds() {
        }
        var layer_OpenStreetMap_0 = L.tileLayer('http://a.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            opacity: 1.0,
            attribution: '',
        });
        layer_OpenStreetMap_0;
        map.addLayer(layer_OpenStreetMap_0);

        function tooltip_Station_1(feature, layer) {
            layer.bindTooltip((feature.properties['Nom'] !== null?String('<div style="color: #e31a1c; font-size: 14pt; font-family: \'MS Shell Dlg 2\', sans-serif;">' + feature.properties['Nom']) + '</div>':''), {permanent: true, offset: [-0, -16], className: 'css_Station_1'});
        }

        function style_Station_1_0() {
            return {
                pane: 'pane_Station_1',
                radius: 8.0,
                opacity: 1,
                color: 'rgba(35,35,35,1.0)',
                dashArray: '',
                lineCap: 'butt',
                lineJoin: 'miter',
                weight: 1,
                fill: true,
                fillOpacity: 1,
                fillColor: 'rgba(227,26,28,1.0)',
            }
        }
        map.createPane('pane_Station_1');
        map.getPane('pane_Station_1').style.zIndex = 401;
        map.getPane('pane_Station_1').style['mix-blend-mode'] = 'normal';
        var layer_Station_1 = new L.geoJson(json_Station_1, {
            attribution: '',
            pane: 'pane_Station_1',
            onEachFeature: tooltip_Station_1,
            pointToLayer: function (feature, latlng) {
                var context = {
                    feature: feature,
                    variables: {}
                };
                var marker = L.circleMarker(latlng, style_Station_1_0(feature));
                marker.on('click', function(evt) {
                  window.open(String(evt.target.feature.properties['Lien']), '_blank');
                });
                return marker;
            },
        });
        bounds_group.addLayer(layer_Station_1);
        map.addLayer(layer_Station_1);
        var osmGeocoder = new L.Control.Geocoder({
            collapsed: true,
            position: 'topleft',
            text: 'Search',
            title: 'Testing'
        }).addTo(map);
        document.getElementsByClassName('leaflet-control-geocoder-icon')[0]
        .className += ' fa fa-search';
        document.getElementsByClassName('leaflet-control-geocoder-icon')[0]
        .title += 'Search for a place';
        var baseMaps = {};
        L.control.layers(baseMaps,{'<img src="legend/Station_1.png" /> Station': layer_Station_1,"OpenStreetMap": layer_OpenStreetMap_0,},{collapsed:false}).addTo(map);
        setBounds();
        var i = 0;
        layer_Station_1.eachLayer(function(layer) {
            var context = {
                feature: layer.feature,
                variables: {}
            };
            labels.push(layer);
            totalMarkers += 1;
              layer.added = true;
              addLabel(layer, i);
              i++;
        });
        resetLabels([layer_Station_1]);
        map.on("zoomend", function(){
            resetLabels([layer_Station_1]);
        });
        map.on("layeradd", function(){
            resetLabels([layer_Station_1]);
        });
        map.on("layerremove", function(){
            resetLabels([layer_Station_1]);
        });
        </script>
    </body>
</html>
  • Thank you very much TomazicM for your response. I tried to make the changes you made to my code, but it does not work. I think it's hard to test just a part of the code. That's why I created a local folder (station.rar see ) including the code and files needed to display the web page. Now I adapted my question above. Can you please test your answer above from the attached file? Thank you very much – tazrart Oct 8 at 14:27
  • I added the relevant code. – TomazicM Oct 8 at 16:17
  • I replaced this part of the code (start: "function style_Station_1_0 () {" end: "map.addLayer (layer_Station_1);" with yours, but the station disappears in the web page. Can you put all the code to better understand your changes. I thank you again. I am really grateful for your help. – tazrart Oct 9 at 6:56
  • All the code added to the answer. Remark: If you just copy and paste the code from others without understending it you'll be in trouble sooner or later. – TomazicM Oct 9 at 14:21
  • Thank you very much TomazicM. I am really far from that thought. This just allows me to better understand your changes and moving command lines. By the way I'm comparing line by line to better understand. My project is much more complicated than this example, so if I do not understand this solution, I will always be stuck in the first step. I am very grateful for your help. Thank you – tazrart Oct 10 at 8:19

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.