I've searched how to draw the circle in the mapbox using Javascript but couldn't find out the correct solution.
var myCircle = new MapboxCircle({lat: data.lat, lng: data.lng}, data.radius, {
editable: true,
minRadius: data.minRadius,
fillColor: data.color
}).addTo(map);
The above code is provided by Mapbox but it allows just add the circle Layer in fixed radius on the map.
But what I wanted is to draw the circle in dynamic radius by dragging.
You can pass these radii in meters using the latest version of Leaflet. The radius will change relative to zoom levels.
Here's some more information via Leaflet's documentation
L.circle([lat,lng], radius).addTo(map);
More documentation here: https://www.mapbox.com/mapbox.js/api/v2.1.9/l-circlemarker/
Related
In my leaflet application I am using both canvas and svg renderers.
Canvas renderer is used for markers and svg for polygon.
But because of this i am unable to order the svg rendered polygon layers using layer.bringToBack() method.
Reason why I want polygon layer to back is shown in below image.
Polygon above markers
Polygon covers my markers making them unclickable I want polygon below my markers as foll image.
Polygon below marker
In html this is how the layers are arranged, all canvas and html elements.
HTML code
Please suggest me a suitable solution for my issue
You can create a new map pane and add the markers to that pane: https://leafletjs.com/reference.html#map-pane
map.createPane('canvasMarkers'); //https://leafletjs.com/reference.html#map-createpane
var canvas = L.canvas({
pane: 'canvasMarkers'
})
L.circleMarker(map.getCenter(), {renderer: canvas}).addTo(map);
.leaflet-canvasMarkers-pane{
z-index: 600;
}
or just use the image marker pane:
var canvas = L.canvas({
pane: 'markerPane'
})
L.circleMarker(map.getCenter(), {renderer: canvas}).addTo(map);
https://plnkr.co/edit/gVuJvUw7mCVNa6Xj
I have a Leaflet map with a geoJSON containing contour lines. The elevation corresponding to each line is located in feature.properties.Elevation of the geoJSON. I want to achieve the following:
What I've tried to achieve this in leaflet is to calculate the center of each polyline and then add a marker to that position containing the data from feature.properties.Elevation.
L.geoJson(contourJSON, {
onEachFeature: function(feature, layer) {
var label = L.marker(layer.getBounds().getCenter(), {
icon: L.divIcon({
className: 'label',
html: feature.properties.Elevation,
iconSize: [100, 40]
})
}).addTo(map);
}
});
Which kind of works, but does not have a nice styling and it's not really clear which value belongs to a specific line:
What would be a better method of adding the elevation labels in such a way that it is readable and maybe dynamic to the current zoom level? I'm using Leaflet 1.0.3 so maybe Tooltip could offer a solution? Thanks!
You might be interested in those Leaflet plugins, possibly combined: (not sure how easy it would be to combine them)
Leaflet.LabelTextCollision (demo)
…display[s] labels on vector data while avoiding label collisions.
Leaflet.TextPath (demo)
Shows a text along a Polyline.
You might also want to check out the rest of Leaflet plugins.
BTW, I am not sure placing your label / marker at the polyline "center" is appropriate. You might just pick one of its vertices, or for example the farthest to the right / East to have an effect similar to the example you provide.
So I'm using the latest version of leaflet (v1.0.2), and am trying to dynamically apply text labels to specific lat lng points on a custom (geo aligned) map.
My issue is that I need the text on the map to maintain it's the size (as though the text is actually part of the tile image) when zooming. Using a Marker of any kind results in the text staying at its correct size. If I use something like an image overlay and add an SVG with text in, it scales with the map zoom.
I've noticed that the image overlay has a CSS3 scale added to its transform property when zooming whereas the marker does not.
Can I extend the marker to scale as the image overlay does?
I've already written code that listens to the zoom event and adjusts the font size of markers but this is CPU intensive (especially for mobile browsers) and I don't really want to render the text dynamically within svgs either!
I've provided a demo so that this makes more sense. You can see that example_1 (the marker) maintains it's size however far you zoom in or out. Example_2 (the svg image) scales relative to the map when zooming. This (Example_2) is what I'm trying to get an L.DivIcon with html text content to do!
Any help or suggestions are appreciated!
https://jsfiddle.net/z96L7hdu/
Example Code
HTML
<div id="map" style="width:500px; height:600px;"></div>
JavaScript
var map = L.map('map', {
zoomSnap: 0
}).setView([0, 0], 3);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var img = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICAgICB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgNTAwIDQwIj4gIDx0ZXh0IHg9IjAiIHk9IjAiIGZvbnQtZmFtaWx5PSJWZXJkYW5hIiBmb250LXNpemU9IjM1Ij4gICAgRXhhbXBsZV8yICA8L3RleHQ+PC9zdmc+";
imageBounds = [[-8.636810901898114, -12.135975261193327], [-18.28136415046407, 17.181122017133486]];
L.imageOverlay(img, imageBounds).addTo(map);
var myIcon = L.divIcon({className: 'my-div-icon', html:"Example_1"});
L.marker({lat: 0.7800052024755708, lng: 0.010986328125}, {icon: myIcon}).addTo(map);
Apologies for the late answer, but I thought it was an interesting question. You can indeed extend the L.Marker class, to create markers that resize the font of their DivIcon to match the zoom level:
L.FixedSizeMarker = L.Marker.extend({
options: {
fontSize: 12, // starting size of icon in pixels
zoomBase: 3 // Zoom level where fontSize is the correct size
},
update: function () {
if (this._icon && this._icon.tagName === 'DIV' && this._map) {
let size = this.options.fontSize * Math.pow(2, (this._map.getZoom() - this.options.zoomBase));
this._icon.style.fontSize = size + 'px';
}
return L.Marker.prototype.update.call(this);
}
});
L.fixedSizeMarker = (latlng, options) => new L.FixedSizeMarker(latlng, options);
The code above defines a new FixedSizeMarker, which behaves just like a normal Marker, but if you add a DivIcon to it, it will resize the font. It takes two options, to specify the font size in pixels, and the zoom level that you want that font size to be correct for. In the example in the OP's JSFiddle, you would use it like this:
var myIcon3 = L.divIcon({className: 'my-div-icon', html:"Example_3"});
L.fixedSizeMarker({lat: 0.7800052024755708, lng: -12.135975261193327},
{icon: myIcon3, fontSize: 24, zoomBase: 3}).addTo(map);
When using these markers, it may look better to set {markerZoomAnimation: false} in the map options. The marker size change is otherwise quite obvious when you zoom the map.
const element = marker.getElement();
element.style[L.DomUtil.TRANSFORM] = `scale(3)`;
You can use this to modify the css of a marker
Is it possible to draw circles and polylines on Google maps based on pixel dimensions? Allow me to explain...
I have a marker on a map. Next, I want to draw a circle around it, with the marker being the exact center. I'd like the circle to have a fixed pixel-based radius. However, as the Google Maps API takes distance in meters to base the radius on, the size of the circle varies based on the zoom level, which is what I do not want.
Another example is an angled Polyline. I'm drawing such a line from the marker into a certain direction. Again the distance is based on meters, not pixels, thus the zoom shrinks or grows the size of the line. Another unwanted side effect is that due the sperical projection of the map (if I understand this correctly), a line angled at 90 degrees, will not draw it precisely at east.
What I'm looking for is the convenience of these drawing objects on the map, without tying them to map dimensions, just to hard pixels. Is such a thing possible, or does it mean I need to start from scratch with a custom div and some kind of SVG library?
It's easier than you might think, use Symbols.
For a circle there is a predefined path:
new google.maps.Marker({
position: centerLatLngOfTheCircle,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: yourDesiredRadius,
strokeWeight: 1,
},
map: map
});
For a polyline you must assign a custom path:
line = new google.maps.Marker({
position: startLatLngOfTheLine,
icon: {
path: ['M0 0 ',
(Math.cos(Math.PI * angle / 180)),
(Math.sin(Math.PI * angle / 180))].join(' '),
scale: desiredStrokeLength,
strokeWeight: 1
},
map: map
});
(the angle is counted clockwise, starting at 3:00)
Demo: http://jsfiddle.net/doktormolle/y8S8e/
I am using google map v3 and its drawingManager feature, I want to get the pixels of these Shapes either through Lat and Long or directly.
Here is the URL of drawingManager Shapes
https://developers.google.com/maps/documentation/javascript/examples/user-editable-shapes
I want to get the pixels as here with respect to the container of map
http://gmaps-samples-v3.googlecode.com/svn/trunk/latlng-to-coord-control/latlng-to-coord-control.html
like here, buts using overlay class and I want to use it for DrawingManager Shapes, need some help on it.
Thanks
To translate a LatLng to a Point use the method fromLatLngToPoint() of the current projection.
The current projection is returned by mapObject.getProjection()
However, a shape isn't always defined by LatLng's/Points.
For rectangles you must translate the points defined by the bounds, for a circle the center(and/or bounds), and for polylines/polygons the path.