In leaflet we have api calls and plugins to put placemarks, icons, images and geometric shapes. Yet I have no idea how to put just a piece of text. What do I do?
How about a L.Marker with a L.DivIcon?
Represents a lightweight icon for markers that uses a simple element instead of an image. Inherits from Icon but ignores the iconUrl and shadow options.
Reference: http://leafletjs.com/reference-1.2.0.html#divicon
new L.marker([0, 0], {
icon: new L.DivIcon({
html: '<h1>Some text...</h1>'
})
});
Related
I want to be able to hide and show/layers in Mapbox like this example provided by Mapbox.... https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/
I have some vector data saved as a tile set in Mapbox, but I don't know where to find the URL is shown in the example below as 'mapbox://mapbox.2opop9hr'. Can anyone tell me how to find it for my own data?
// Wait until the map has finished loading.
map.on('load', () => {
// Add a custom vector tileset source. This tileset contains
// point features representing museums. Each feature contains
// three properties. For example:
// {
// alt_name: "Museo Arqueologico",
// name: "Museo Inka",
// tourism: "museum"
// }
map.addSource('museums', {
type: 'vector',
url: 'mapbox://mapbox.2opop9hr'
});
mapbox://mapbox.2opop9hr is a reference to a mapbox custom vector tileset. You can make one of your own by uploading data in Mapbox Studio: https://docs.mapbox.com/studio-manual/reference/tilesets/. Mapbox will then serve this tileset for your map to consume.
However, this isn't necessary to toggle map layers using the technique shown in the example. map.setLayoutProperty() can be used to show or hide any layer, including layers that came with the base style, or layers added after the fact using vector tiles or geojson sources.
If you are working with small/simple data, you may want to just add a geojson source and layer, and then use setLayoutProperty() to show and hide it as in the example.
I am trying to use the leaflet-draw tool for two different things:
as a "regular" tool to create new geometries
if I draw a line, I perform some calculations with turf.js, giving me points nearby.
I've set up two individual draw controls for each purpose. For the second, I have all but the draw:polyline disabled. The problem: I save my elements with the
map.on('draw:created', function(){...});
"command". But this way I (or the eventhandler, respectively :)) cant differentiate, if the line was drawn with the first or the second button. So basically i can use the draw tool either for one thing or the other. Is there a way where I can use the same tool for different applications on the same map?
Thanks for any hints or work arounds.
An alternative would be to use Leaflet-Geoman instead of Leaflet-Draw.
There you can create copies of Draw instances and add them a new shape name:
// copy a rectangle and customize its name, block, title and actions
map.pm.Toolbar.copyDrawControl('Polygon', {
name: 'PolygonCopy',
block: 'custom',
title: 'Display text on hover button',
actions: ['cancel', 'removeLastVertex', 'finish'],
});
And then you can check the shape name in the create event:
// listen to when a new layer is created
map.on('pm:create', function(e) {
console.log(e)
if(e.shape === 'Polygon'){
alert('Original Polygon')
}else if(e.shape === 'PolygonCopy'){
alert('Copy Polygon')
}
});
https://jsfiddle.net/falkedesign/r0sm9auo/
I am using Mapbox Studio as basis for mapping and styling and then using HTML for additional map features.
One of the features is to change Icon opacity when hovering or mouse enter. I've checked other examples and all other refer to feature when you create it directly in HTML. I managed to change opacity but only for whole layer.
Can I use somehow e.features[0] command line to apply changes only to one feature rather than to whole layer?
I used this code which changer opacity for whole Layer 'Icon' (Layer contains 5 icons with text):
// Change the cursor to a default and change opacity when the it enters a feature in the 'Icons' layer.
map.on('mouseenter', 'Icons', function() {
map.getCanvas().style.cursor = 'default';
var feature = e.features[0];
map.setPaintProperty('Icons', 'icon-opacity', 0.5);
});
// Change it back to a pointer and reset opacity when it leaves.
map.on('mouseleave', 'Icons', function() {
map.getCanvas().style.cursor = '',
map.setPaintProperty('Icons', 'icon-opacity', 1);
});
Thank you!!!
There are a few ways which you could achieve this. One approach is to add each feature as separate layer, so that when you want to change the opacity of an icon added in a layer 'specific-icon-layer', you can pass 'specific-icon-layer' to the Map#on method. This is likely the most straightforward option if you have a relatively minimal number of markers.
Another approach is to add unique IDs to each icon feature, so that you can use a filter expression in conjunction with Map#setPaintProperty and Map#queryRenderedFeatures (or Map#querySourceFeatures). For example, suppose you add an 'id' property to each GeoJSON feature representing an icon in the source for the 'Icons' layer. Then, you could set up an event listener similar to this example, retrieve the 'id' of the returned feature, and use the 'id' (suppose here it is 'example-id') to update the paint property for the 'Icons' layer:
map.setPaintProperty(
'Icons',
'icon-opacity',
['match', ['get', 'id'], 'example-id', 0.5 , 1]
);
Here, we use match and get expressions to say "if the 'id' of a feature is 'example-id', paint its icon with opacity 0.5, otherwise use opacity 1."
Check the example at https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/
This approach makes use of setFeatureState and feature-state expressions
The problem with using map.setPaintProperty(layer, property, filter, matchValue, styleValue, fallbackStyleValue) every time is that it restyles every feature on the layer instead of only the feature being interacted with. This can cause poor performance when the layer has a high number of features.
simple question:
How can i set the draggability from all markers in a featureGroup on false?
Thanks, greets!
Simply loop through all markers within the Feature Group using the eachLayer() method, make sure the passed layer is a marker, and disable the dragging functionality using the marker interaction handler.
myFeatureGroup.eachLayer(function (layer) {
if (layer instanceof L.Marker) {
layer.dragging.disable();
}
});
You can also re-enable the dragging functionality using marker.dragging.enable().
Demo: http://jsfiddle.net/ve2huzxw/108/ (built on answer of Get multiple Markers in Leaflet).
In Leaflet, is it possible to define a marker or polyline with {clickable:false}, so that a click is passed through to whatever lies beneath - be it the map or a clickable geometry object?
At the moment I solve this problem by making the marker/polyline clickable and passing the event onwards myself. But this leads to the mouse cursor always showing as the hand symbol. Ideally, the mouse cursor should look like the normal pointer or the hand, depending on whether what is beneath the marker/polyline is clickable.
This may not be the answer you are looking for, but you can use featureGroups to have all of your clickable polylines come to the front so that the actions are surfaced.
var lg_noclick = new L.FeatureGroup().addTo(map);
var lg_click = new L.FeatureGroup().addTo(map);
// Add lines
lg_click.bringToFront();
updated fiddle
Also if you can afford to know your lines before hand, correct ordering of when you add the lines it will work as well.
I know this is not ideal but it suited my situation just fine, so it might be good for you as well.
This hides the icon and brings it back after a second using mouseenter and mouseleave events:
$('.leaflet-marker-icon').mouseenter(function() {
$(this).hide();
});
$('.leaflet-marker-icon').mouseleave(function() {
$(this).delay(1000).show(0);
});