i want to implement in my leaflet app, feature that allows to find route between two selected points.To find route i want to use this library: mapquest
I have extended standard leaflet map class like this:
export class Map {
constructor(elementId, centerView, zoom ) {
this.layers = [];
this.map = this.init(elementId,centerView,zoom);
this.icons = {};
}
init(elementId, centerView, zoom) {
//console.log('Map::init('+elementId+', ['+centerView+'], '+zoom+')');
delete L.Icon.Default.prototype._getIconUrl;
const markerIcon = require('leaflet/dist/images/marker-icon.png');
const markerIcon2x = require('leaflet/dist/images/marker-icon-2x.png');
const markerShadow = require('leaflet/dist/images/marker-shadow.png');
L.Icon.Default.mergeOptions({
iconRetinaUrl: markerIcon2x.default,
iconUrl: markerIcon.default,
shadowUrl: markerShadow.default,
});
var map = L.map(elementId, {
center: [centerView[0], centerView[1]],
zoom: zoom
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
return map;
}
}
And i wrote few functions that helps me to work with map(add point, markers etc).
This is how i'm initializing extended map object:
let centerView = [35.791188, -78.636755];
let zoom = 9;
var map = new Map('map', centerView, zoom);
And i found code how to generate route mapquest-routing.I'am taking coords by clicking on map which works fine. My function to generate route looks like this:
function runDirection(start, end)
{
var dir = MQ.routing.directions();
dir.route({
locations: [
start,
end
]
});
map.map.addLayer(MQ.routing.routeLayer({
directions: dir,
fitBounds: true
}));
}
But i'm getting error:
Uncaught Error: The provided object is not a Layer.
Which means MQ.routing.routeLayer(),doesnt return me leyer object.
So the question is, how can i add route to standard leaflet map?
You're using a deprecated library. On the https://developer.mapquest.com/documentation/leaflet-plugins/geocoding/ webpage there's a deprecation warning in big red letters, I quote:
We recommend using MapQuest.js instead.
The documentation in the webpage for that mapquest plugin for Leaflet lists compatibility for Leaflet 0.7.7 (which was published back on 2013). Leaflet uses semantic versioning, which means stuff that worked with 0.x has no guarantee of working with 1.x. It's safe to assume that the Leaflet plugin in question only works with Leaflet 0.7.x and older, and does not work with Leaflet 1.x.
Related
I am working with a WordPress/jQuery/Google Maps setup to display a map of listings to users.
The jQuery.goMap.map code is used to load in the Google Maps instance used on the WordPress plugin.
I have wrote the following functions to store and load the latitude, longitude, and zoom level with local storage. The storing of the lat/lng and zoom levels is working, and the loading of the zoom level is working, but I cannot get the map to center on the loaded latitude and longitude position.
I have tried using bounds.extend(latLng); and jQuery.goMap.map.fitBounds(bounds); in the loadUserZoom function, but the result is a fully zoomed in map. This means the stored zoom level value is being ignored.
The current functioning code can be tested here.
The Clear text link in the header navigation can be used to clear the local storage values from the browser. This is implemented for testing purposes.
Any assistance is greatly appreciated.
Function: storeUserZoom
function storeUserZoom() {
let zoom = jQuery.goMap.map.getZoom();
localStorage.setItem( 'zoom', zoom);
let center = jQuery.goMap.map.getCenter();
let lat = center.lat();
let lng = center.lng();
let latLng = {
lat: lat,
lng: lng
}
localStorage.setItem( 'latLng', JSON.stringify(latLng));
}
Function: loadUserZoom
function loadUserZoom() {
if (localStorage.getItem( 'zoom' )) {
let zoom = parseInt(localStorage.getItem( 'zoom' ));
console.log(zoom);
// Logs correct zoom level
let latLng = JSON.parse(localStorage.getItem( 'latLng' ));
console.log(latLng);
// Logs Object { lat: 51.69124213478852, lng: -113.2478200914128 }
jQuery.goMap.map.setZoom(zoom);
jQuery.goMap.map.setCenter(latLng);
// latLng used is incorrect
}
}
I believe I have zeroed in on the problem by adjusting how the loadUserZoom function was executed in the initMap function.
The loadUserZoom function was wrapped in a Google Maps listen once event listener when the map was idle. The code is included below.
google.maps.event.addListenerOnce(jQuery.goMap.map, 'idle', function() {
loadUserZoom();
});
I had it set initially to addListener, which seemed to conflict with the required functionality. I assume this meant it was execute regularly whenever the map was in an idle state.
My updated loadUserZoom function is included below.
function loadUserZoom() {
if (localStorage.getItem( 'zoom' )) {
let zoom = parseInt(localStorage.getItem( 'zoom' ));
let latLng = JSON.parse(localStorage.getItem( 'latLng' ));
jQuery.goMap.map.setZoom(zoom);
jQuery.goMap.map.setCenter(latLng);
}
}
I have:
const map = L.map("mapid", {preferCanvas: true});
//....
const circle = L.circle([47.6652642, -122.3161248], {
color: '#ea647f',
fillOpacity: 0.4,
radius: 30
}).addTo(map);
but calling getBounds() on circle fails:
const bounds = circle.getBounds();
It fails inside function getBounds in Circle.js which is Leaflet code,
The Leaflet getBounds method code is:
getBounds: function () {
var half = [this._radius, this._radiusY || this._radius];
return new LatLngBounds(
this._map.layerPointToLatLng(this._point.subtract(half)),
this._map.layerPointToLatLng(this._point.add(half)));
}
Trying to access this._map.layerPointToLatLng fails
I get the error that this._map is undefined
Any ideas?
===================================================
Please Note: I also have a polygon defined,
and calling the getBounds() on the polygon passes fine and works correctly, shows correctly on the map.
=> It is only the Circle.getBounds() that fails
Add center and zoom to the map.
const map = L.map("map", {center:[47.6652642, -122.3161248], zoom: 16 ,preferCanvas: true});
You need to initialise the map state with setView() or some other mechanism. The layerPointToLatLng calls will fail otherwise.
I'm migrating from Google Maps API to Apple MapKit JS for the simple reason I have a developer account with them and they offer more free hits.
Anyway, actual examples of MapKit JS are a bit thin (or at least Google isn't finding them - draw what conspiracy theories you will), so although I've got the basics going of displaying an embeded map, I can't seem to do the next step which is route between two points (Apple's documentation also seems impenetrable as they don't show examples).
Here's my script for a basic map:
<script>
mapkit.init({
authorizationCallback: function(done) {
done('[MY-TOKEN]');
}
});
var MarkerAnnotation = mapkit.MarkerAnnotation
var myMarker = new mapkit.Coordinate(55.9496320, -3.1866360)
var myRegion = new mapkit.CoordinateRegion(
new mapkit.Coordinate(55.9496320, -3.1866360),
new mapkit.CoordinateSpan(0.003, 0.003)
);
var map = new mapkit.Map("map");
var myAnnotation = new MarkerAnnotation(myMarker, { color: "#9b6bcc", title: "theSpace On The Mile"});
map.showItems([myAnnotation]);
map.region = myRegion;
</script>
Now I want to:
• Show a walking route between two points
• Include waypoints on the route
Could someone show the code that would achieve this? Once I can see an example I know I'll get it ;-)
Ok, so I've found a solution to this so sharing it here for the benefit of others.
Let's start by saying Apple's MapKit JS doesn't appear to have a waypoints option as offered by Google Maps API - so the way around that is to create a map that stores the markers in an array and then routes from one to the next. The code stores the location of the last waypoint in a variable, and doesn't bother to draw a route to the last waypoint if this is the first one in the array (obviously).
<script>
// Initiallise MapKit - you'll need your own long-lived token for this
mapkit.init({
authorizationCallback: function(done) {
done('[MY-TOKEN]');
}
});
// Function to draw the route once MapKit has returned a response
function directionHandler(error, data) {
data["routes"].forEach(function(route, routeIdx) {
if (routeIdx !== 0) { return; }
overlays = [];
route['path'].forEach(function(path) {
// This styles the line drawn on the map
let overlayStyle = new mapkit.Style({
lineWidth: 3,
strokeColor: "#9b6bcc"
});
let overlay = new mapkit.PolylineOverlay(path, {
style: overlayStyle
});
overlays.push(overlay);
});
map.addOverlays(overlays);
});
}
// This asks MapKit for directions and when it gets a response sends it to directionHandler
function computeDirections(origin,destination) {
let directionsOptions = {
origin: origin,
destination: destination,
transportType: mapkit.Directions.Transport.Walking
};
directions.route(directionsOptions, directionHandler);
}
// This sets the initial region, but is overridden when all points have been potted to automatically set the bounds
var myRegion = new mapkit.CoordinateRegion(
new mapkit.Coordinate(55.9496320, -3.1866360),
new mapkit.CoordinateSpan(0.05, 0.05)
);
var map = new mapkit.Map("map");
map.region = myRegion;
var myAnnotations = [];
// lastWaypoint variable is 'unset' initially so the map doesn't try and find a route to the lastWaypoint for the first point of the route
var lastWaypoint = "unset";
var directions = new mapkit.Directions();
// Array of co-ordinates and label for marker
waypoints = [
{name:'Sofi’s Bar',lat:55.9746308,lon:-3.1722282},
{name:'TThe Roseleaf Cafe',lat:55.975992,lon:-3.173474},
{name:'Hemingway’s',lat:55.9763631,lon:-3.1706564},
{name:'Teuchter’s Landing',lat:55.9774693,lon:-3.1713826},
{name:'The King’s Wark',lat:55.9761425,lon:-3.1695419},
{name:'Malt and Hops',lat:55.975885,lon:-3.1698957},
{name:'The Carrier’s Quarters',lat:55.9760813,lon:-3.1685323},
{name:'Noble’s',lat:55.974905,lon:-3.16714},
{name:'The Fly Half',lat:55.9747906,lon:-3.1674496},
{name:'Port O’ Leith',lat:55.974596,lon:-3.167525}
];
// Loop through the array and create marker for each
waypoints.forEach(function(data) {
var myAnnotation = new mapkit.MarkerAnnotation(new mapkit.Coordinate(data['lat'],data['lon']), {
color: "#9b6bcc",
title: data['name']
});
myAnnotations.push(myAnnotation);
// As long as this isn't the first point on the route, draw a route back to the last point
if(lastWaypoint!="unset") {
computeDirections(lastWaypoint,new mapkit.Coordinate(data['lat'],data['lon']));
}
lastWaypoint = new mapkit.Coordinate(data['lat'],data['lon']);
});
map.showItems(myAnnotations);
</script>
This map is for a pub crawl around Leith, so the trasportType is 'Walking', but change that to 'Automobile' if you so wish.
With credit to Vasile whose MapKit JS Demo (https://github.com/vasile/mapkit-js-demo) helped me understand a lot more about the options.
I am trying to build a map app that use address name in data base and display marker in leaflet map. I had come across leaflet esri plugin but not sure how to use the code. Could anyone please teach me how to extract result(longitude and latitude) from the geocoding function and draw a marker? Thanks!
Geocode function:
L.esri.Geocoding.geocode(<Object> options)
Results:
{results: [
{
latlng: L.LatLng,
text: 'Formatted Address',
score: 100, // certainty ranking of the match
properties: {
// additional info like specific address components (Country Code etc.)
}
}
]
}
http://esri.github.io/esri-leaflet/api-reference/tasks/geocode.html
Here is an example using ES6:
import L from "leaflet";
// import library as ELG
import * as ELG from "esri-leaflet-geocoder";
// here is an example address in the US - use the one from your DB
const address = "380 New York St, Redlands, California, 92373";
// call geocode method of the library, no need to call L.esri.Geocoding.geocode() as in vanilla js
ELG.geocode()
// pass the address
.text(address)
.run((err, results, response) => {
console.log(results.results[0].latlng);
// retrieve latitude, longitude from related response
const { lat, lng } = results.results[0].latlng;
// build a marker using the retrieved address
L.marker([lat, lng])
.addTo(mymap)
.bindPopup(address)
.openPopup();
});
Demo
I am working with leaflet api where user can put markers on map. I have made a custom button for putting marker.
I am willing to draw line between those markers i.e. using
L.polylines() but as I am new to javascript and leaflet I can't
understand how to pass those latlng point to array which will later be
used in these functions. For initial working I have passed static
coordinates(working as req).
L.easyButton('fa-link', function () {
var secureThisArea = [[-81, 100.75], [-76.50, 245.75], [-145.50, 184.25], [-128, 311.75]];
map.on('click', function fencePlace(e) {
L.marker([-81, 100.75], { icon: fenceIcon, draggable: true }).bindPopup("this is first").addTo(map);
L.marker([-76.50, 245.75], { icon: fenceIcon, draggable: true }).bindPopup("this is second").addTo(map);
L.marker([-145.50, 184.25], { icon: fenceIcon, draggable: true }).bindPopup("this is third").addTo(map);
L.marker([-128, 311.75], { icon: fenceIcon, draggable: true }).bindPopup("this is fourth").addTo(map);
L.polyline(secureThisArea).addTo(map);
});
}).addTo(map);
Adding another value to an array is easy, e.g.:
secureThisArea.push([-81, 100.75]);
You can find more details (also about anything else JavaScript related) at Mozilla Developer Network.
If you want to use the coordinates from the marker objects, you can get those with:
var myMarker = L.marker([-81, 100.75], { icon: fenceIcon, draggable: true }),
latLng = null;
latLng = myMarker.getLatLng();
Also take a look at the Leaflet documentation.
If i understand you correctly you want to create markers on click and connect them via polylines. That's easy to do, in code with comments to explain:
// Create new empty polyline and add it to the map
var polyline = new L.Polyline([]).addTo(map);
// Handle map click event
map.on('click', function(event) {
// New marker on coordinate, add it to the map
new L.Marker(event.latlng).addTo(map);
// Add coordinate to the polyline
polyline.addLatLng(event.latlng);
});
Now afterwards if you want to get all the coordinates added to the polyline you can use the getLatLngs method of L.Polyline which returns an array of L.LatLng objects.
Reference: http://leafletjs.com/reference.html#polyline
Example: http://plnkr.co/edit/h7aMwc?p=preview