Strange behavior leaflet when adding a marker - leaflet

Working example: http://markercluster.meteor.com/
If you double click on the map to add a marker, then this place will be the upper left corner marker, not pin.
The coordinates of the mouse pointer and marker coordinates coincide: it can be seen in the browser console.
Actually the question: What am I doing wrong? How to make a marker added correctly?

Solved by adding option iconAnchor
EDIT:
myIcon = L.icon(
iconUrl: "packages/leaflet/images/marker-icon.png"
shadowUrl: "packages/leaflet/images/marker-shadow.png"
iconAnchor: [12, 41] #[iconWidth/2, iconHeight]
)

Related

Why does my Leaflet circle only show as a dot?

I'm trying to add circles to my map, but for some reason the circles only show as dots, irrespective of the radius size.
var circle = L.circle(map.unproject([9541, 7658], map.getMaxZoom()), {
radius: 500
}).addTo(map);
I'm using pixel coordinates, but as you can see I'm converting them, so even though I only get dots on the map, they show at the right coordinates. I would hope this isn't the issue, but...?
I've successfully added circleMarkers, but the radius doesn't grow when zooming. At least not that I could see.
So the question is: how can I get the dots to show as circles?
Using Leaflet 1.9.3
Update
It appears that with pixel coordinates you need to enter a really high value for the radius. Thought I had already tried this before asking the question but apparently not.
var circle = L.circle(map.unproject([9541, 7658], map.getMaxZoom()), {
radius: 50000
}).addTo(map);
Unfortunately they're all showing at different sizes, even with the same radius, but that's a different question...
I originally misread your question and gave an incorrect answer, sorry. Circle radius is static. I think that the best way to change it with zoom level would be to use a zoom event listener:
let currZoom = map.getZoom();
let circles = [/* Store your circles here as you create them */];
map.on("zoomend", () => {
const zoomDiff = map.getZoom() - currZoom;
currZoom = map.getZoom();
for (const circle of circles) {
circle.setRadius(circle.getRadius() * 2 ** zoomDiff);
}
});
It's been a while since I've worked with Leaflet, but I think that will do the trick.
Edited to account for your comment regarding multiple circles.

Leaflet disable vertical dragging out of bounds

Is it possible to only have vertical bounds in leaflet to remove grey bands above and below the leaflet map?
Grey bands around map
I still want to keep horizontal wrap but just want to remove the grey areas.
you can simply use the minZoom option, and set it to 3, that's what I do ;)
this.map.setView(new L.LatLng(31.585692323629303, 35.19333585601518), 2);
L.tileLayer(`https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png`, {
maxZoom: 20,
minZoom: 3,
attribution: 'HOT'
}).addTo(this.map);
in my case using angular, hope it help

Explanation of Leaflet Custom Icon LatLng vs XY Coordinates

Can someone provide an explanation on how to use the Leaflet Marker Icon XY Coordinates listed here:
http://leafletjs.com/examples/custom-icons/
Is lng/lat directly mapped to x/y? For example, sometimes in game engines, the Y pixel increases in value, but goes down the page.
Here is it the same? I can't quite wrap my head around it.
Not exactly sure what you mean by "Is lng/lat directly mapped to x/y?", but here are some explanations that should talk enough:
(tile courtesy MapQuest)
As in most image manipulation software:
X increases from left to right
Y increases from top to bottom
When specifying iconAnchor and shadowAnchor for Leaflet custom icons, these directions still apply. Furthermore, like in most image software as well, the origin is the top left corner of your image.
var myIcon = L.icon({
iconUrl: 'path/to/image.png', // relative to your script location, or absolute
iconSize: [25, 41], // [x, y] in pixels
iconAnchor: [12, 41]
});
As explained in the doc, if you specify iconSize but not iconAnchor, Leaflet will assume your icon tip is at the center of your image and position it accordingly (same for shadow).
But if you do specify neither iconSize nor iconAnchor, Leaflet will position your icon image "as is", i.e. as if its tip was its top left corner. Then you can apply a className option and define it in CSS with negative left and top margins to re-position your image.
var myIcon = L.icon({
iconUrl: 'path/to/image.png',
// iconSize: [25, 41],
// iconAnchor: [12, 41], // [x, y]
className: 'custom-icon'
});
.custom-icon {
margin-left: -12px; /* -x */
margin-top: -41px; /* -y */
}
This usage might be more interesting when using a DivIcon, for which you may not know the size in advance, and use CSS transforms to position it.
As for the popupAnchor, it uses the icon tip as origin, so you will most likely specify a negative y value, so that the popup appears above the icon.
popupAnchor: [1, -34] // [x, y]
Finally when adjusting your anchor values, a useful trick is to add a normal default marker at the exact same Lat/Lng location as the marker with your custom icon, so that you can compare both icon tip positions easily.

use a small circle icon marker instead of default marker icon with polyline

I am using leaflet plugin to show google map with marker and polyline.
When I use default marker I am getting marker attached properly with polyline.
but when I changed the default marker with small circle icon image then that is not properly attached .
I am attching the screenshot . Please let me know How can I solve this ?
As far as I remember, there are some heights/widths You need to give when changing markers, as the center of the marker is not at the coordinate it depicts.
This example from the documentation shows that You set them on the Icon
var myIcon = L.icon({
iconUrl: 'my-icon.png',
iconSize: [38, 95],
iconAnchor: [22, 94],
popupAnchor: [-3, -76],
shadowUrl: 'my-icon-shadow.png',
shadowSize: [68, 95],
shadowAnchor: [22, 94]
});
L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);

leaflet editable restrict draw to a specific area

In Leaflet.Editable I want to confine/limit my customers to draw only in a specific area/bounds.
actually im trying to limit them to (90, -90, 180, -180) bounds of map..
maxBounds: [[-90, -180], [90, 180]]
I was not able to find anything anywhere and it seems that i am missing something.
CODEPEN DEMO
please help.
EDIT:
the Y axis is blocking correctly and mouse cannot stretch shape beyond top and bottom.
the problem is in X axis (as seen in pictures)
as for now i solved it with after save check and clear shape if it out of map bounds (BAD USER EXPERIENCE). i need a mouse confinement just like y axis does.
Without knowing your use case (why the whole world map??) Quickest and easiest fix would be to simply set the map's minZoom to something a bit higher, for example, I found that minZoom: 5 was adequate except for cases where the map was both really short and really wide (which is rarely the case in most apps I've seen).
But the real fix involves writing your own custom overrides for dragging markers and shapes.
According to API doc the L.Editable plugin allows you to override a bunch of stuff including the VertexMarker class, via map.editTools.options.vertexMarkerClass.
Fixed codepen: http://codepen.io/anon/pen/GrPpRY?editors=0010
This snippet of code that allows you to constrain the longitude for dragging vertex markers by correcting values under -180 and over 180 is this:
// create custom vertex marker editor
var vertexMarkerClass = L.Editable.VertexMarker.extend({
onDrag: function(e) {
e.vertex = this;
var iconPos = L.DomUtil.getPosition(this._icon),
latlng = this._map.layerPointToLatLng(iconPos);
// fix out of range vertex
if (latlng.lng < -180) {
e.latlng.lng = latlng.lng = -180;
this.setLatLng(latlng);
}
if (latlng.lng > 180) {
e.latlng.lng = latlng.lng = 180;
this.setLatLng(latlng);
}
this.editor.onVertexMarkerDrag(e);
this.latlng.update(latlng);
this._latlng = this.latlng; // Push back to Leaflet our reference.
this.editor.refresh();
if (this.middleMarker) this.middleMarker.updateLatLng();
var next = this.getNext();
if (next && next.middleMarker) next.middleMarker.updateLatLng();
}
});
// attach custom editor
map.editTools.options.vertexMarkerClass = vertexMarkerClass;
I didn't code for dragging the shape as a whole (the rectangle, in this case). While the VertexMarker fix should address all kinds of vertex dragging, you need to override each shape's drag handler to properly constrain the bounds. And if bounds are exceeded, crop the shape appropriately. As was pointed out, Leaflet already does this for latitude, but because Leaflet allows wrapping the map around horizontally you have your essential problem. Using rec.on("drag") to correct the bounds when they cross over your min/max longitude is the only way to address it. It is basically the same solution as I have laid out for the vertexMarkerClass - actual code left as exercise for the diligent reader.