1

I am currently using GIS to plot train stations within Wales I have currently made a custom circle marker to point to that of the stations latlng successfully adding it to the map. I am wanting the circle marker to be used to show the train stations within Wales and to change colour/style upon being clicked.

I do not wish for this to be the default marker within leaflet but to be that of the custom circle marker

<!--MAP SCRIPT-->
<script>
  <!--Instantiating the map-->
  var Leafmap = L.map("mapspce", {
    center: [51.5, -3.4],
    zoom: 9,
  });

  <!--Adding the tile-->
  L.tileLayer(
    "https://tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=2392bb5236f942d8897fbe6d6c2d0c66",
    {
      maxZoom: 19,
      transparent: true,
      attribution:
        'Tom Slater 18018815 &copy;, <a href="https://www.thunderforest.com/maps/transport/">Thunderforest</a> &copy;',
    }
  ).addTo(Leafmap);
  <!--Making a marker-->
  var tMarker = {
    radius: 6,
    fillColor: "#09f9df",
    color: "#ff0000",
    weight: 1,
    opacity: 1,
    fillOpacity: 1,
  };
  <!--Welsh train stations Data Layer-->
  var trainGeo = L.geoJSON(wtsGeo, {
    pointToLayer: function (feature, latlng) {
      return L.circleMarker(latlng, tMarker);
    },
  });
  <!--Adding the markers and data to map-->
  Leafmap.addLayer(trainGeo);

  <!--Stores clicked marker-->
  var clicked;

  <!--Clicked style-->
  function clickStyle(feature) {
    return {
      radius: 6,
      fillColor: "#ff0000",
      color: "#ff0000",
      opacity: 1,
      weight: 2,
      fillOpacity: 1,
    };
  }
  <!--unclicked style-->
  function unclickStyle(feature) {
    return {
      radius: 6,
      fillColor: "#09f9df",
      color: "#ff0000",
      weight: 1,
      opacity: 1,
      fillOpacity: 1,
    };
  }

  <!--Instantiating the click layer and its style-->
  var clickLayer = L.geoJSON(wtsGeo, {
    style: clickStyle,
    onEachFeature: addHandler,
  });
  <!--Add new layer to map when clicked-->
  Leafmap.addLayer(clickLayer);

  <!--Clickable function that displays data-->
  function clickOnFeature(e) {
    if (clicked) {
      clickLayer.resetStyle(clicked);
    }
    e.target.setStyle(unclickStyle()); //Error Here does not like e fucntion
    clicked = e.target;
  }

  function addHandler(feature, layer) {
    layer.on({
      click: clickOnFeature,
    });
  }
</script>

However The code which I believed would change the icon throws the error

Uncaught TypeError: e.target.setStyle is not a function

Is there a way to change this point markers colour upon being clicked?

UPDATE

Changing the code to that of below has removed the error however default markers still show as well as the circle markers, I am able to click this without an error but not colour/style change happens

<script>
<!--Instantiating the map-->
    var Leafmap = L.map('mapspce', {
    center: [51.5, -3.4],
    zoom: 9
    });

<!--Adding the tile-->
L.tileLayer('https://tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=2392bb5236f942d8897fbe6d6c2d0c66',{
    maxZoom: 19,
    transparent: true,
    attribution: 'Tom Slater 18018815 &copy;, <a href="https://www.thunderforest.com/maps/transport/">Thunderforest</a> &copy;'
    }).addTo(Leafmap);
<!--Making a marker-->
var tMarker = {
    radius:6,
    fillColor: '#09f9df',
    color:'#ff0000',
    weight:1,
    opacity: 1,
    fillOpacity:1
};
<!--Welsh train stations Data Layer-->
//var trainGeo = L.geoJSON(wtsGeo,{
//pointToLayer: function (feature, latlng){
//return L.circleMarker(latlng, tMarker);
//}
//});
<!--Adding the markers and data to map-->
//Leafmap.addLayer(trainGeo);

<!--Stores clicked marker-->
var clicked;

<!--Clicked style-->
function clickStyle(feature) {
    return {
    radius:6,
    fillColor:'#ff0000',
    color:'#ff0000',
    opacity:1,
    weight:2,
    fillOpacity:1
};
}
<!--unclicked style-->
function unclickStyle(feature) {
    return {
    radius:6,
    fillColor: '#09f9df',
    color:'#ff0000',
    weight:1,
    opacity: 1,
    fillOpacity:1
};
}

function SetMarkerStyle(target) {
if (clicked) {
clicked.setStyle(clickStyle);
}
target.setStyle(unclickStyle);
clicked=target;
}

function clickOnMarker1(e){
SetMarkerStyle(e.target);
}

function clickOnMarker2(e){
SetMarkerStyle(e.target.tMarker);
}

var clickLayer = L.geoJSON(wtsGeo,{
pointToLayer: function (feature,latlng) {
var Marker1 = L.circleMarker(latlng,unclickStyle);
var Marker2 = L.marker(latlng);
Marker2.tMarker = Marker1;
var markerGroup = L.layerGroup([Marker1, Marker2]);
Marker1.on('click', clickOnMarker1);
Marker2.on('click', clickOnMarker2);
return(markerGroup);
}
}).addTo(Leafmap);
    


</script>

Current version stand at Map points within wales on trainstations

Live version link https://ces-web2.southwales.ac.uk/students/18018815/mitchtut/giscw2/leaflet.htm

UPDATE

Colour changes and error removed however it changes after a click and is in need of slight refining this was fixed through reversing the click/unclick styles

Final Code

<!--MAP SCRIPT-->
<script>
<!--Instantiating the map-->
    var Leafmap = L.map('mapspce', {
    center: [51.5, -3.4],
    zoom: 9
    });

<!--Adding the tile-->
L.tileLayer('https://tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=2392bb5236f942d8897fbe6d6c2d0c66',{
    maxZoom: 19,
    transparent: true,
    attribution: 'Tom Slater 18018815 &copy;, <a href="https://www.thunderforest.com/maps/transport/">Thunderforest</a> &copy;'
    }).addTo(Leafmap);
<!--Making a marker-->
var tMarker = {
    radius:6,
    fillColor: '#09f9df',
    color:'#ff0000',
    weight:1,
    opacity: 1,
    fillOpacity:1
};
<!--Welsh train stations Data Layer-->
//var trainGeo = L.geoJSON(wtsGeo,{
//pointToLayer: function (feature, latlng){
//return L.circleMarker(latlng, tMarker);
//}
//});
<!--Adding the markers and data to map-->
//Leafmap.addLayer(trainGeo);

<!--Stores clicked marker-->
var clicked;

<!--Clicked style-->
var clickStyle = {
    radius:6,
    fillColor:'#ff0000',
    color:'#ff0000',
    opacity:1,
    weight:2,
    fillOpacity:1
}
<!--unclicked style-->
var unclickStyle = {
    radius:6,
    fillColor: '#09f9df',
    color:'#ff0000',
    weight:1,
    opacity: 1,
    fillOpacity:1
}

function SetMarkerStyle(target) {
if (clicked) {
clicked.setStyle(unclickStyle);
}
target.setStyle(clickStyle);
clicked=target;
}

function clickOnMarker1(e){
SetMarkerStyle(e.target);
}

function clickOnMarker2(e){
SetMarkerStyle(e.target.tMarker);
}

var clickLayer = L.geoJSON(wtsGeo,{
pointToLayer: function (feature,latlng) {
var Marker1 = L.circleMarker(latlng,unclickStyle);
var Marker2 = L.marker(latlng);
Marker2.tMarker = Marker1;
var markerGroup = L.layerGroup([Marker1, Marker2]);
Marker1.on('click', clickOnMarker1);
Marker2.on('click', clickOnMarker2);
return(markerGroup);
}
}).addTo(Leafmap);
    


</script>
4
  • The way you implemented idea of changing marker on click with two versions of the same layer cannot work. Please edit you question and add missing style definitions (clicked, unclickStyle function), so it will be clear what you are trying to do and answer will be possible.
    – TomazicM
    Feb 10 at 21:14
  • @TomazicM Added the missing style definitions, thought I included them within the copy and paste
    – WMTS
    Feb 10 at 22:11
  • Ugh, you're putting HTML-style comments inside JS. Please try to avoid that and use C-style comments instead. Otherwise, you risk your code not being parsed correctly (under some circumstances+browser+toolchain combination). Feb 11 at 4:16
  • You edited your question, but again did not mention that you don't want regular marker. Please add that info. And style of circle marker does not change because you didn't change style functions to style objects. Check my answer again.
    – TomazicM
    Feb 11 at 17:16
1

Your code (which I adapted into a reproducible example here) is adding the dataset twice to the map, once as L.CircleMarkers...

  var trainGeo = L.geoJSON(wtsGeo, {
    pointToLayer: function (feature, latlng) {
      return L.circleMarker(latlng, tMarker);
    },
  });

...and once as default L.Markers...

  var clickLayer = L.geoJSON(wtsGeo, {
    style: clickStyle,
    onEachFeature: addHandler,
  });

... so at each datapoint there's a circle and a marker with the default icon, like circle+icon

Now, using two different symbols per data point is a questionable practice, and might be the source of the confusion here. I suggest you to consider using only one symbol per data point instead.

The error itself happens because you're trying to use a method (setStyle) specific to L.CircleMarkers (inherited from L.Path's setStyle) on a L.Marker (note that, when your event handler is running, e.target is an instance of L.Marker since the event handler is attached to clickLayer which is spawning default L.Markers).

While you might want to change the style of the circle when clicking on the spatially associated (but not logically-associated) marker, I urge you to use one symbol per datapoint.

2
  • I apologise for any confusion. Yes I am trying to have 1 marker being that of the circlemarker, "tMarker" in this case, and upon clicking it changes colour. I did not mean for 2 markers to appear thus being part of the problem. Is there a way to keep circle markers whilst making them clickable in which to change their colour like I want or not?
    – WMTS
    Feb 11 at 16:32
  • The most straightforward approach in your specific case is to have one instance of L.GeoJSON, and make sure to pass all the pointToLayer, style and onEachFeature options at once. Feb 11 at 17:02
1

As @IvanSanchez wrote in his answer, problem comes from clicking on the default marker, which has no setStyle method. And there is definitely no need for two layers from the same GeoJSON source.

Solution for what you want to achieve is to use just pointToLayer method to create marker and click event.

Code could the look something like this:

var clicked;

var clickStyle =  {
  radius: 6,
  fillColor: "#ff0000",
  color: "#ff0000",
  opacity: 1,
  weight: 2,
  fillOpacity: 1,
}
var unclickStyle = {
  radius: 6,
  fillColor: "#09f9df",
  color: "#ff0000",
  weight: 1,
  opacity: 1,
  fillOpacity: 1,
}

function clickOnMarker(e){
  if (clicked) {
    clicked.setStyle(unclickStyle);
  }
  e.target.setStyle(clickStyle);
  clicked = e.target;
}

var layer = L.geoJSON(wtsGeo, {
  pointToLayer: function (feature, latlng) {
    var marker = L.circleMarker(latlng, unclickStyle);
    marker.on('click', clickOnMarker);
    return(marker);
  }
}).addTo(map);
4
  • Thank you, errors are removed but I am still dealing with the multiple marker issue with a regular pin drop marker still appearing as well as the circle marker, I am also still unable to click the marker and make it change colour
    – WMTS
    Feb 11 at 17:04
  • So you don't want regular marker to appear? This is not mentioned in your question, so I thought it's a requirement.
    – TomazicM
    Feb 11 at 17:09
  • No sorry again for any confusion Just the circle markers and upon clicking it, it changes colour/style
    – WMTS
    Feb 11 at 17:10
  • Then please edit your question and mention that. I'll modify my answer then.
    – TomazicM
    Feb 11 at 17:11

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.