I am creating a map that the user will be able to draw lines on using the Leaflet.Draw toolbar. I would like the running distance of the line to be displayed in feet/miles instead of the default yards/miles. Looking at the project in GitHub, it seems to me the following code should do this:
var drawControl = new L.Control.Draw({
draw: {
polyline: {
shapeOptions: {
color: 'red',
},
metric: false,
feet: true,
}
}
});
But the length is still displayed in yards. Any insight into why this is would be helpful.
Which version of Leaflet.draw plugin are you using?
Note that:
Leaflet.draw version v0.2.4 / 0.2.4-dev (as used in the plugin GitHub demo) does not have the feet option yet.
Leaflet.draw version v0.3.0 / 0.3.0-dev (latest release for Leaflet 0.7) has the feet option.
Leaflet.draw from leaflet-master branch, for compatibility with Leaflet 1.0, is based on version 0.2.4 and does not have the feet option.
Related
I am using Mapbox GL JS (v2.8.0) to programmatically add a Style layer to my map, and I am trying to use a set of fonts that I have uploaded to my map via the Mapbox Studio.
I currently have this inside my code for my Style layer:
const layer = {
id: this.getLayerId(),
type: 'symbol',
layout: {
'text-field': ['get', 'name'],
'text-font': [
"Chakra Petch Italic", // My custom font inside Mapbox
"Arial Unicode MS Regular" // Fallback font
]
},
paint: {
'text-color': '#ffffff',
}
}
However when it comes to rendering my map, I am getting 404 errors in relation to trying to fetch my font.
It is trying to fetch the font from the following url:
https://api.mapbox.com/fonts/v1/mapbox/Chakra%20Petch%20Italic,Arial%20Unicode%20MS%20Regular/0-255.pbf?access_token={access_token}
And I believe this issue here is that instead of /mapbox/ it should be /{username}/ as when I go to the following url in the browser:
https://api.mapbox.com/fonts/v1/{username}/Chakra%20Petch%20Italic,Arial%20Unicode%20MS%20Regular/0-255.pbf?access_token={access_token}
I correctly get the .pbf data.
How am I able to specify that it should look under my username, rather than the public mapbox user, in my style layer json?
Additionally, as a test, if I create a simple layer inside Mapbox Studio - and set a label to use the custom font, in the Network tab in devtools I can see it fetching the font using the username url above. And unfortunately the "code inspector" in the Studio for this label shows the same two string array as I have inside my code.
You need to set the glyphs property of your style:
}, glyphs: 'mapbox://fonts/yourusername/{fontstack}/{range}.pbf'
}
More info: https://docs.mapbox.com/mapbox-gl-js/style-spec/glyphs/
I'm using leaflet + leaflet-draw + #ngx-leaflet + #ngx-leaflet-draw in an Angular application.
I've tried everything, versions change, importing the modules .forRoot() and not, adding the js files in my angular.json file, remove node_modules, reinstall them, followed the guide on #ngx-leaflet-draw from scratch a hundred times.
No matter what I do, when I try to draw a rectangle it always throws this error:
Even though the handlers are present and ALL of them works perfectly except for the rectangle one (the only one I need)
I don't even know how to provide you with more specific informations if not for this:
leaflet: 1.5.1
leaflet-draw: 1.0.4
#asymmetrik/ngx-leaflet: 6.0.1
#asymmetrik/ngx-leaflet-draw: 5.0.1
I'm stuck on this stupid error and I don't know how to get over it. Please help!
here's a repo for demo: https://github.com/caiusCitiriga/leaflet-rect-drawer
There are a couple of issues:
The draw options aren't quite right. This isn't actually causing the error, though.
There's a bug leaflet-draw that causes the exception you're seeing.
Leaflet Draw Options
square is not a draw option. The correct option is rectangle. Additionally, all of the handlers are enabled by default. So, you only need to turn off the ones you don't want.
So, I think what you want is in your app.component.ts file:
public drawOptions = {
position: 'topright',
draw: {
marker: {
icon: L.icon({
iconSize: [25, 41],
iconAnchor: [13, 41],
iconUrl: 'assets/marker-icon.png',
shadowUrl: 'assets/marker-shadow.png'
})
},
polygon: false,
circlemarker: false
}
};
The above will make sure that marker, circle, rectangle, and polyline are enabled and the others are disabled. You want to make sure to add the leaflet assets png files to the list of assets being exported by Angular CLI in your angular.json file.
Identifying and Fixing The Error
There's something weird about leaflet-draw's build that's causing the source maps to not work. To get them working, I had to directly import the leaflet.draw-src.js file.
At the top of app.component.ts, I added:
import * as L from 'leaflet';
import '../../node_modules/leaflet-draw/dist/leaflet.draw-src.js'; // add this
That allows you to put a breakpoint in the leaflet-draw code to figure out what's going on. Upon doing that, it looks like there's a variable called type that isn't declared before it's assigned to. The code is being run in strict mode, so this will throw an exception. This looks to be a bug in leaflet-draw.
Solution 1: Disable ShowArea
First, you can disable showArea, which will prevent the problem code from running. To do this, modify the drawOptions:
public drawOptions = {
position: 'topright',
draw: {
marker: {
icon: L.icon({
iconSize: [25, 41],
iconAnchor: [13, 41],
iconUrl: 'assets/marker-icon.png',
shadowUrl: 'assets/marker-shadow.png'
})
},
rectangle: { showArea: false }, // disable showArea
polyline: true,
polygon: false,
circlemarker: false
}
};
This isn't a great solution, cause you lose the showArea functionality.
Solution 2: Disable Strict Mode
The other solution is to disable strict mode for the Typescript compiler.
To do this, edit your tsconfig.json and tsconfig.app.json files, adding "noImplicitUseStrict": true under the compilerOptions property.
This solves the problem, but now you're not running your code in strict mode, which can lead to other issues.
there is a typing probleme inside leaflet draw file
Unfortunatly, there is no more support on this project
You can update node-package module and fix the problem, here is my solution :
install last leaflet and leaflet-draw version
for me :
"leaflet": "^1.7.1",
"leaflet-draw": "^1.0.4",
And install patch-package : https://www.npmjs.com/package/patch-package
go to node-module/leaflet-draw/dist/leaflet.draw.js
update the package
replace this part of code : (I can't give you the line cause it's a minified file, so you have to ctrl+f to find the location.)
{var a,n,o=L.Util.extend({},t,o)
by this :
{var type;var a,n,o=L.Util.extend({},t,o)
After node module package updated, you have to create a node module patch
to do this, use patch-package command :
npx patch-package leaflet-draw
Last things is to tell angular to replace the correct leaflet-draw file
To do this, you have to go inside your angular package.json
and add this line :
"postinstall": "patch-package"
like this:
"scripts": {
"postinstall": "patch-package",
"build": "ng build",
"lint": "ng lint",
"ng": "ng",
},
Remove your node-module package
Make new install (npm install)
Now you can use the rectangle draw fnunctionnality
if you just need in local, you just need to update the leaflet-draw.js file.
I 'fixed' it with
rectangle: <any>{ showArea: false },
I'm trying to display a clustered map with Mapbox GL JS.
Using this example from the documentation: https://www.mapbox.com/mapbox-gl-js/example/cluster/, I'd like to show a marker icon instead of a circle for unclustered points.
I modified the last addLayer call like this :
map.addLayer({
id: "unclustered-point",
type: "symbol",
source: "companies",
filter: ["!has", "point_count"],
layout: {
"icon-image": "marker-15", // THIS SHOULD BE A MARKER
"icon-size": 5 // ZOOMED FOR DEMO
},
});
Here is the result I got :
Why can't I get access to Maki Icons like it is suggested here : Mapbox GL js available icons
Without a link to your (non) working example, it's hard to diagnose fully, but one possibility is that that icon is not included in your style.
You could try starting from a style that definitely includes them, like these: https://github.com/mapbox/mapbox-gl-styles
We use leafletJS to show maps with round about 100 markers. Some of these markers are located on exact the same position. Marker2 is above Marker1 so Marker1 isn't visible. Is there a way to rotate Markers in a way that you can see there are more then one marker?
may be you should look at https://github.com/Leaflet/Leaflet.markercluster plugin
here demo - http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.388.html
The drawback with walla's answer is that Leaflet.markercluster requires clustering, which may not be an option depending on your requirements i.e. you need to always display individual markers.
OverlappingMarkerSpiderfier-Leaflet (a bit of a mouthful) works well in this case and it's fairly well documented. It displays a 'spider' of markers on click only if they overlap i.e. if the zoom level increases so markers don't overlap, then it won't 'spider' on click, which is quite nice. Demo.
It's available as a NPM package but it isn't a proper ES module, so usage is a bit trickier than usual if you're expecting an ES module:
// Need to specifically import the distributed JS file
import 'overlapping-marker-spiderfier-leaflet/dist/oms';
// Note access to constructor via window object
// map refers to your leaflet map object
const oms = new window.OverlappingMarkerSpiderfier(map);
oms.addListener('click', (marker) => {
// Your callback when marker is clicked
});
// Markers need to be added to OMS to spider overlapping markers
markers.forEach((marker) => {
oms.addMarker(marker);
});
// Conversely use oms.removeMarker(marker) if a marker is removed
Alternatively there is a forked version (confusingly) called OverlappingMarkerSpiderfier that is a proper ES module so you can do:
import OverlappingMarkerSpiderfier from 'overlapping-marker-spiderfier'
const oms = new OverlappingMarkerSpiderfier(map);
However as of 24 Jan 2020 there's a fair bit of divergence based on commits between the two so YMMV.
FWIW I'm using the original.
If anyone is looking working sample for Angular below are the steps,
Install it via npm: npm i --save overlapping-marker-spiderfier-leaflet
Then import it into the component where you need it: import 'overlapping-marker-spiderfier-leaflet/dist/oms';
Add this line on top of the file where you import it: const OverlappingMarkerSpiderfier = (<any>window).OverlappingMarkerSpiderfier;
Add the oms markup like that: this.oms = new OverlappingMarkerSpiderfier(this.map, { nearbyDistance: 20, keepSpiderfied: true });
Add the markers to oms at the same place where you add your markers to the map so oms can track them properly this.oms.addMarker(marker);
xlm is already gave a complete answer. Thanks to him for that answer. But this is a slightly changed answer that worked for me in angular.
we had the same problem, follows the jsFiddle with the solution we found http://jsfiddle.net/atma_tecnologia/mgkuq0gf/2/
var marker1 = new google.maps.Marker({
position: myLatLng,
map: map,
icon: {
url: image,
size: new google.maps.Size(134,130), //different sizes
},
zIndex: 2, //different overlays
title: '1ยบ marker',
});
How do you manually trigger the native popup on a Leaflet polygon?
I can bind the native popup to each layer like this:
geojsonLayer.on("featureparse", function (e){
// bind the native popup
var popupContent = "popup content goes here";
e.layer.bindPopup(popupContent);
});
And I have manually assigned an ID to each polygon so I can reference them later like this:
map._layers['poly0']
I've tried triggering the popup like this:
map._layers['poly0'].openPopup();
But that gives me an error like this:
map._layers['poly0'].openPopup is not a function
Any idea where I'm going wrong?
openPopup for vector layers only recently appeared in the latest version, it wasn't there before.
Also, check out the Leaflet 0.4 release announcement: http://leaflet.cloudmade.com/2012/07/30/leaflet-0-4-released.html (and note that GeoJSON API was changed and it's not backwards compatible, so you also have to update your code)