I'm trying to add the Leaflet Editable functionality to my current map which map is created by the leaflet directive. I'm getting the L.map instance with:
leafletData.getMap().then(function(map) {
// where map is the Leaflet map instance
}
However the Leaflet editable needs to set editable: true when the map is created.
So, is there a way to create a L.map instance
var map = L.map('map', {editable: true});
and then attach it to the Leaflet angular directive?
UPDATE:
I tried to add a hook to Leaflet
L.Map.addInitHook(function () {
this.whenReady(function () {
this.editTools = new L.Editable(this, this.options.editOptions);
console.log('L.map', this);
});
}
It creates the editTools successfully but the
map.editTools.startPolyline();
is still not working
Did you try adding editable: true to your defaults?
angular.extend($scope, {
defaults: {
editable: true
},
center: {
lat: 51.505,
lng: -0.09,
zoom: 8
}
});
<leaflet defaults="defaults" lf-center="center" height="480px" width="640px"></leaflet>
For anyone looking like me to make an existing map editable
var map = L.map('map', {editable: true});
is the same as
var map = L.map('map');
map.editTools = new L.Editable(map);
Related
I've been working on creating a dynamically updated Mapbox GL integration inside Webflow's CMS. I've succeeded in creating an array of features that can be read by Mapbox's API, but these features won't show on the map because the coordinates are not being read by the function that creates the map markers.
I receive the following error Cannot read property 'coordinates' of undefined at map-test-page:139 which is where a longitude and latitude is assigned to the current marker via this line: .setLngLat(marker.geometry.coordinates)
Partial solution was found here, but the code I've integrated into my site doesn't have featuresIn or featuresAt functions which seem to be the only way to include a includeGeometry: true parameter.
I'm curious if I need to rethink how I've created markers and do something with a function like map.on('click', ...) reference here.
Here is a minimal version that reproduces my issue.
If you're familiar with the Webflow interface you can view a read-only version of the site.
Any help would be greatly appreciated!
Here is the Mapbox script I'm using on the page:
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/strawpari/ckp2nu3dw6cwu17nt4kqwf1vv',
center: [-13.723969, 48.360542],
zoom: 2,
pitch: 0,
bearing: 0,
antialias: true,
interactive: true
});
var geojson = {
type: 'FeatureCollection',
features: farmerArray,
};
// add markers to map
geojson.features.forEach(function(marker) {
// create a HTML element for each feature
var el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add to the map
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML('<img src=\'' + marker.properties.image + '\' width=\'50\' height=\'50\' border-radius=\'50%\'>' + '<h3>' + marker.properties.title + '</h3><p>' + marker.properties.description + '</p>'))
.addTo(map);
});
And here is the code embedded in each CMS item that adds a farmer's information to the farmerArray which is being read by Mapbox. Text in double-quotations "" is a placeholder for the dynamic information populated by the CMS.
var farmerArrayItem =
JSON.stringify({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: ["longitude", "latitude"]
},
properties: {
title: "name",
description: "text",
image: "imagepath"
}
});
farmerArray.push(farmerArrayItem);
It doesn't appear that you have tried using the Developer Tools to debug your code. That's definitely a skill you should pick up.
With the dev tools, you will quickly see that the value of marker at the critical point is a string:
So you just need to use JSON.parse:
geojson.features.forEach(function(markerString) {
const marker = JSON.parse(markerString);
// create a HTML element for each feature
var el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add to the map
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
I have 2 different divs which using by leaflet as map object. I want to define my map objects into a function such as
html
<div id="mymap"></div>
<div id="mymap2"></div>
javascript
var map;
function define_map(map_id) {
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osm = L.tileLayer(osmUrl, {
maxZoom: 7
}),
map = new L.Map(map_id, {
center: new L.LatLng(51.505, -0.04),
zoom: 7
}),
drawnItems = L.featureGroup().addTo(map);
});
define_map("mymap");
define_map("mymap2");
$(".btnmarker").on("click", function() {
console.log(map);
L.DomUtil.addClass(map._container, 'my_crosshair-cursor-enabled'); // ON THIS LINE GETTING ERROR CODE Cannot read property '_container' of undefined
selected_tool = $(this).attr("id");
});
There is no problem, my maps seems working good until accessing features of them from button click event (this button will add a marker class to a map which i clicked on it)
But i'm getting map is not defined error. map is a variable and defined on top line of page.
Thanks inadvance
Map` like this:
L.Map = L.Map.extend({
openPopup: function(popup) {
this._popup = popup;
return this.addLayer(popup).fire('popupopen', {
popup: this._popup
});
}
});
But I am using leaflet. Is there anyway to extent like so that i can prevent closing my marker popup?
L.mapbox.accessToken = constant.accessToken;
var map = L.mapbox.map('map', 'mapbox.streets', {zoomControl: true});
Update Dec 2017
Leaflet popup options have been extended to include { autoClose: false } which has the required effect :
var my_marker = L.marker([my_lat, my_lng], {icon: my_icon})
.addTo(map)
.bindPopup('My Popup HTML', {closeOnClick: false, autoClose: false});
Let me quote the Leaflet documentation on L.Popup:
Used to open popups in certain places of the map. Use Map.openPopup to open popups while making sure that only one popup is open at one time (recommended for usability), or use Map.addLayer to open as many as you want.
In order to open several popups, instantiate them using L.popup(latlng, options), then .addTo(map) them.
Define an array:
let map=L.map('mymap');
...
var markers = L.markerClusterGroup();
...
var marker=[];
marker[0]= L.marker([latitud1,longitud1]).addTo(map).bindPopup('Hola 0',{autoClose: false, closeOnClick: false});
marker[1]= L.marker([latitud2,longitud2]).addTo(map).bindPopup('Hola 1',{autoClose: false, closeOnClick: false});
To put on the map:
marker.forEach(function(marker) {
markers.addLayer(marker);
map.addLayer(markers);
});
Show the popup for only one:
var curPos = marker[0].getLatLng();
map.setView(new L.LatLng(curPos.lat,curPos.lng), 13);
marker[0].openPopup();
Show all popups:
marker.forEach(function(marker) {
var popup = marker.getPopup();
marker.bindPopup(popup.getContent()).openPopup();
});
Close all popups:
map.eachLayer(function (layer) {
layer.closePopup();
});
When the application starts, I want to center the map view on the users current position. I have tried two different approaches and can't get them work. The first one worked properly in leaflet, but in the development process I have decided to use OL3 instead.
First approach (worked in leaflet):
var myProjectionName = "EPSG:25832";
proj4.defs(myProjectionName,
"+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs");
var centerPosition;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (pos) {
centerPosition =
ol.proj.transform(
[position.coords.longitude,
position.coords.latitude],
'EPSG:4326',
myProjectionName);
},
function (err) {centerPosition = [724844,6178000];},
{
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 1000
});
}
My second approach was using the ol.Geolocation class:
var proj1 = ol.proj.get(myProjectionName);
var geolocation = new ol.Geolocation({
projection: proj1
});
var centerPosition= geolocation.getPosition();
The center position is used in creating the view/map object:
var map = new ol.Map({
target: 'map',
logo : false,
layers: [ GSTGroup, OVLGroup, SheatLayer],
view: new ol.View({
projection: myProjectionName,
center: centerPosition,
resolutions : AVLresolutions,
resolution : 2
})
});
I have some suspecions that the cause of the problem is the projection, but on the other hand the projection works properly in transforming layers (WMTS, Vector), source from Geojson in different coordinatesystem and in ol.control.MousePosition.
I am using Firefox 32.0.3 and the geolocator plugin to development/test
Working example in http://jsfiddle.net/AndersFinn/ak4zotn8/
Add after the map declaration the following (tested):
var proj1 = ol.proj.get(myProjectionName);
var geolocation = new ol.Geolocation({
projection: myProjectionName,
tracking: true
});
geolocation.on('change', function(evt) {
console.log(geolocation.getPosition());
map.getView().setCenter(geolocation.getPosition());
});
The most important part is tracking: true in the code: it means you check regularly the position to center.
The second important part is to bind event on geolocation object (an instance of ol.Geolocation)
See in the official examples the geolocation samples and the API docs to make some changes depending of your requirements
How to disable mobile touch event after the bing map is initialized?
We can disable before initializing by below code, using MapOptions object. However I'm looking after the Bing Map is initialized.
// Set the map and view options, setting the map style to Road and
// removing the user's ability to change the map style
var mapOptions = {credentials:"Bing Maps Key",
height: 400,
width: 400,
mapTypeId: Microsoft.Maps.MapTypeId.road,
disableTouchInput : true,
};
// Initialize the map
var map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), mapOptions);
Any help is highly appreciated. Thanks in advance!!!
Most of the MapOptions do work when passed into the setOptions method of the map. For instance try this: map.setOptions({disableTouchInput: true});
Note that I've only tested this in IE. If you simply want to disable panning and zooming you can do this in a number of different ways. The first is to use map options, the other is to use the viewchange event, store the original map position and keep setting the map to the same view to lock it.
Since you can't set most of the MapOptions once the map is created you can only do this by swapping out your map for a new map with the options you want. This is a very basic example, but here is an example that shows and hides the bing logo which is one of the settings that you can't change with setOptions.
function switchMapOptions(active, inactive) {
try {
var newMap = new MM.Map($(inactive)[0], options);
for (var i = 0; i < map.entities.getLength(); i++) {
var loc = map.entities.get(i).getLocation();
newMap.entities.push(new MM.Pushpin(loc));
}
newMap.setView({center: map.getCenter(), zoom: map.getZoom(), animate: false});
map.dispose();
map = newMap;
}
catch (e) {
alert(e.message);
}
}
Full code at Jsfiddle: http://jsfiddle.net/bryantlikes/zhH5g/4/