Leaflet: How to add a text label to a custom marker icon? - leaflet

Is it possible to add text to a custom icon marker? I want to avoid having to edit the icon in an image editor just to add the text.
I've created my custom icon marker like so:
var airfieldIcon = L.icon({
iconUrl: 'images/airfield.png',
iconSize: [48,48]
});
var airfield = L.geoJson (airfield, {
pointToLayer: function(feature,latlng){
return L.marker(latlng, {
icon: airfieldIcon
})
}
}).addTo(map);
How would I add the text "Banff Airfield" as a label to this icon? Is the easiest and most efficient way through using an image editor? if so, I will do that method, but wondering if there was a better way. Thanks!

You could use a L.DivIcon:
Represents a lightweight icon for markers that uses a simple div element instead of an image.
http://leafletjs.com/reference.html#divicon
Put your image and text in it's HTML, sprinkle some CSS to make it appear the way you want and you're good to go
new L.Marker([57.666667, -2.64], {
icon: new L.DivIcon({
className: 'my-div-icon',
html: '<img class="my-div-image" src="http://png-3.vector.me/files/images/4/0/402272/aiga_air_transportation_bg_thumb"/>'+
'<span class="my-div-span">RAF Banff Airfield</span>'
})
});
Another option is to use the Leaflet.Label plugin:
Leaflet.label is plugin for adding labels to markers & shapes on leaflet powered maps.
Repository: https://github.com/Leaflet/Leaflet.label
Example: http://leaflet.github.io/Leaflet.label/

As of leaflet version 1.0.0, you can add a label without using a plugin (the plugin has been rolled into the core functionality).
Example:
var marker = L.marker(latlng)
.bindTooltip("Test Label",
{
permanent: true,
direction: 'right'
}
);
This yields a marker on the map with a label of "Test Label" which is always displayed to the right of the marker's icon.

To further explore Mark's answer, if you want to know an easy way to add text (number) over a marker like this:
You just have to proceed as follows:
1. Instantiate an icon (map.js)
var stepIcon = L.icon({
iconUrl: 'graphic/yellow-circle.png', // the background image you want
iconSize: [40, 40], // size of the icon
});
2.1 Setting the icon (map.js)
var marker = new L.marker([39.5, 77.3], { icon:stepIcon});
marker.bindTooltip("12" //specific number, {
permanent: true,
direction: 'center',
className: "my-labels"
});
marker.addTo(map);
2.2 Setting the icon (map.css)
.leaflet-tooltip.my-labels {
background-color: transparent;
border: transparent;
box-shadow: none;
font-weight: bold;
font-size: 30px;
}
Make sure you have imported your .css file into your .html page.

this is out of box solution it may not suitable for everyone but it works for me
simply you can add marker of icon then marker of text Like this :
var MarkerIcon = L.icon(feature.geometry.properties.icon);
var MarkerText = L.divIcon(
{className: TextPositionClass,
html:'<div>'+ displayText+'</div>',
iconSize: null
});
let marker = L.marker(latlng, {icon: MarkerIcon}).addTo(this.map); // add marker
let label = L.marker(latlng, {icon: MarkerText}).addTo(this.map); // add text on marker

Related

Add Maki Icon instead of Mapbox Geocoder Marker

Just a quick question, if anyone has ever replaced the Mapbox default marker with a Maki icon. I've only seen examples of using Maki icons for point tilesets/layers, but I'm wanting to use it for non-tileset features, specifically replacing the marker that adds after geocoding, at the location of the address just geocoded.
Or, trying to find something that is similar to Google Maps symbols below. Any suggestions appreciated.
var pinImage = {
path: google.maps.SymbolPath.CIRCLE,
fillColor: '#ff4b00',
fillOpacity: .9,
scale: 5,
strokeColor: '#CDDC39',
strokeWeight: 0,
strokeOpacity: .5
}
The MapboxGeocoder control has a marker option https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#parameters which controls the marker placed on the map when you select a result.
There is an example at https://docs.mapbox.com/mapbox-gl-js/example/custom-marker-icons/ to create a Marker with a custom icon.
So you could create an HTML Element which contains either an SVG or PNG icon from Maki and use that as your element in your custom Marker passed to the MapboxGeocoder control.
I think this sample is what you are looking for Use a custom render function with a geocoder
It allows you to add a custom render function including the icon...
var geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
types: 'poi',
// see https://docs.mapbox.com/api/search/#geocoding-response-object for information about the schema of each response feature
render: function(item) {
// extract the item's maki icon or use a default
var maki = item.properties.maki || 'marker';
return (
"<div class='geocoder-dropdown-item'><img class='geocoder-dropdown-icon' src='https://unpkg.com/#mapbox/maki#6.1.0/icons/" +
maki +
"-15.svg'><span class='geocoder-dropdown-text'>" +
item.text +
'</span></div>'
);
},
mapboxgl: mapboxgl
});
map.addControl(geocoder);

change the current clicked marker Icon using leaflet

I am using leaflet plugin to show the marker. When I click on the current marker the icon should change the current marker only.
Again when I click on another marker change that marker to new icon and keep all other marker icon original.
Like I have 2 marker Icon
1- original Icon which I am setting when showing the marker on map
2- new marker - I want this marker icon should be set when click on marker.Only current Marker Icon should be changed and keep all other Icon Original Icon.
you can try this.
When you click the marker1, its icon will change to the one you set.
let marker1 = L.marker([e.latitude, e.longitude], { icon: greenIcon }).on('click', ()=>{
marker1.setIcon(redIcon)
}).addTo(map)
Do you have a marker layer? If yes you could first create a new icon
var customIcon = L.Icon.extend({
options: {
iconSize: [40.4, 44],
iconAnchor: [20, 43],
popupAnchor: [0, -51]
}
});
var myCustomIcon = new CustomIcon({ iconUrl: '../images/marker.png' });
After that you should get clicked marker's index inside the Layer and update the icon like this:
markersLayer[markersIndex].setIcon(myCustomIcon);

leaflet markercluster single marker color

I successfully create a clustermarkergroup with custom style. But I can't change the color of the black marker when there is only one marker in the cluster, please see image Black marker when alone in the cluster
How to change that default marker color?
Here is how I create the clustergroup
var clusterGroup = new L.MarkerClusterGroup({
iconCreateFunction: function(cluster) {
var childCount = cluster.getChildCount();
return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster marker-mycluster', iconSize: new L.Point(40, 40) });
}
})
Some CSS
.marker-mycluster {
background-color: rgba(255,191,84, 0.6);
}
.marker-mycluster div {
background-color: rgba(255,191,84, 1);
}
Your single black marker is just your normal marker, outside any cluster since it is far away from other markers.
If you want to replace the visual appearance of ALL your markers, including when they do not cluster (i.e. when they are shown as single markers), you can conveniently use the singleMarkerMode option of MarkerCluster plugin:
var clusterGroup = L.markerClusterGroup({
singleMarkerMode: true,
iconCreateFunction: function(cluster) {
// your code
});
}
})
This will override the icon of all your markers, so that they look like clusters of size 1.

How to apply css on polylines : leaflet

I am working with the application which uses leaflet api.
Introduction
I needed to draw different types of fences, using decorators i can somewhat apply good visuals to the polylines but not much.
Problem
I was willing to show twisted wires instead of dashes, dots or plain lines and I know the twisted wire line will be an image but can't find help about applying custom css to polylines.
Script Example
var fence2Icon = L.icon({
iconUrl: 'xxxx.png',
iconSize: [5, 20]
iconAnchor: [5, 18]
});
// Add coordinate to the polyline
var polylineFence2 = new L.Polyline([], { color: 'red' });
function fencePlace2(e) {
// New marker on coordinate, add it to the map
new L.Marker(e.latlng, { icon: fence2Icon, draggable: false }).addTo(curr);
// Add coordinate to the polyline
polylineFence2.addLatLng(e.latlng).addTo(curr);
var decorator = L.polylineDecorator(polylineFence2, {
patterns:[{offset:5,repeat:'20px',symbol:new L.Symbol.Dash({pixelSize:5})
}]
}).addTo(curr);
}
L.easyButton('fa-flash', function () {
$('.leaflet-container').css('cursor', 'crosshair');
map.on('click', fencePlace2);
polylineFence2 = new L.Polyline([], { color: 'red' });
}).addTo(map);
If someone know anything about polyline or another way please do help.
Thanks for your time:-)
You can add a class in the options of your polyline ...
var polyline = L.polyline(latlngs, { className: 'my_polyline' }).addTo(map);
and add your own settings in the CSS ...
.my_polyline {
stroke: green;
fill: none;
stroke-dasharray: 10,10;
stroke-width: 5;
}
Here is an example: http://jsfiddle.net/FranceImage/9dggfhnc/
You can also access some options directly ...
var polyline = L.polyline(latlngs, { dashArray: '10,10' }).addTo(map);
See Path Options
If you create a polyline you're in fact adding an element to the SVG element which Leaflet uses to draw it's overlays. Styling SVG path elements is different from styling regular HTML elements. There's no such thing as border and background-color etc. It has different properties, if you're interested here's a nice read on the matter:
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Fills_and_Strokes
You can style Leaflet's path elements when you instanciate them via options or via CSS using the properties (related to styling) described in the documentation here:
http://leafletjs.com/reference.html#path
Via options:
new L.Polyline([...], {
weight: 3,
color: 'red',
opacity: 0.5
}).addTo(map);
Via CSS:
new L.Polyline([...], {
className: 'polyline'
}).addTo(map);
.polyline {
weight: 3,
color: red,
opacity: 0.5
}
However, what you want, using an image simply isn't possible. You can use images as fill for SVG paths, but it would be impossible for your usecase. You'de need to add a pattern definition to the SVG Leaflet is using and then you could use that id as the fill property as outlined in this answer:
https://stackoverflow.com/a/3798797/2019281 but will always fill/tile the image horizontally which won't work if your polyline is vertical.

infoWindow in google map not showing properly in an iPhone phonegap app

I am showing custom marker with click event on it. It shows information when I clicked but the info window is not showing well. I used some css in it. I also need to customize it further. This map is shown in phonegap app in iPhone (iOS 5). Every other thing working find (including direction, GPS).
I have used google map js v3 API.
I got this output.
How to show correct infoWindow? And customize as my need.
here is the code
function setMap(myLat, myLng){
// Define Marker properties
var image = new google.maps.MarkerImage('images/pick.png',
new google.maps.Size(30, 40),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 9,36.
new google.maps.Point(9, 36)
);
var my_place = new google.maps.LatLng(myLat, myLng);
var myOptions = {
zoom:14,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
center: my_place
}
mer_map = new google.maps.Map(document.getElementById("mer_map_canvas"), myOptions);
mer_marker = new google.maps.Marker({
position: my_place,
map: mer_map,
clickable : true,
animation: google.maps.Animation.DROP,
icon: image
});
var contentString = '<div id="mer_map_info" style="border:3px solid red; color:#FFF; background-color:#000;"><p>this is just a test...</p></div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(mer_marker, 'click', function(event) {
infowindow.open(mer_map,mer_marker);
});}
Give this a try. I had a similar problem with phonegap and google maps.
#map_canvas img {
max-width: none;
}