How to pause a leaflet panTo() animation - javascript

I am trying to make a map that automatically pan to several locations, one after the other, using Leaflet 1.7.1. This is working quite well using the panTo() function :
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<style>
html,body,#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
</body>
<script type='text/javascript' src='script.js'></script>
</html>
script.js
var map = L.map('map');
var osm = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'OpenStreetMap contributors'
}).addTo(map);
map.dragging.disable();
map.setView([48.980, 4.373], 7);
var athens = [37.9844, 23.7398]
var stockholm = [59.3272, 18.0830]
setTimeout(function() {
map.panTo([athens[0], athens[1]], {
animate: true,
duration: 20,
easeLinearity: 0.9
})
}, 2000);
setTimeout(function() {
map.panTo([stockholm[0], stockholm[1]], {
animate: true,
duration: 15,
easeLinearity: 0.9
})
}, 22000);
I would like to add a pause/resume function, but I cannot figure how to do this. I am able to stop the animation using the following command :
map.setView(map.getCenter(), map.getZoom(), {"animate": false});
But I cannot resume the animation afterwards, and the later timed panTo events will happen anyway.
Any leads or ideas on how to achieve that ?

Related

How to detect in JavaScript if request made in getTileUrl (Google Maps) was successful or not?

I am new to the community,
I have a simple google Map overlay, I get the tiles (format png) from an external service, example: https://example.tiles.com/
I need to monitor or some mechanism in JavaScript to track or detect successful, failed requests made by getTileUrl to the external service, I have searched the official documentation and found nothing.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<style>
#map {
width: 600px;
height: 500px;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
let gmap;
function initMap() {
gmap = new google.maps.Map(document.getElementById('map'), {
center: {lat: 44.9648, lng: -93.252},
zoom: 5
});
const layers = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return ['https://example.tiles.com/', zoom, '/', coord.x, '/', coord.y, '/current.png'].join('');
},
tileSize: new google.maps.Size(256, 256)
});
gmap.overlayMapTypes.push(layers);
};
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=GOOGLE_API_KEY&callback=initMap" async defer></script>
</body>
</html>
I have tried with the tilesloaded listener but it does not support function arguments.
google.maps.event.addListenerOnce(gmap, 'tilesloaded', function(){
..
});
tilesloaded
What is wanted is simply to count the successful requests made to https://example.tiles.com/ by getTileUrl
I tried using the 'tilesloaded' and it worked for me using this:
google.maps.event.addListenerOnce(gmap, 'tilesloaded', function(){
alert("Tile is loaded!")
});
I just changed the first parameter map into gmap because that's how you defined the map instance on your code.
Here's a snippet for you to check if this is how you want it to happen:
let gmap;
function initMap() {
gmap = new google.maps.Map(document.getElementById('map'), {
center: {lat: 44.9648, lng: -93.252},
zoom: 5
});
const layers = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return ['https://example.tiles.com/', zoom, '/', coord.x, '/', coord.y, '/current.png'].join('');
},
tileSize: new google.maps.Size(256, 256)
});
gmap.overlayMapTypes.push(layers);
google.maps.event.addListenerOnce(gmap, 'tilesloaded', function(){
alert("Tile is loaded!")
});
};
#map {
width: 600px;
height: 500px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>
</body>
</html>
What happens here is when the tilesloaded is triggered, it will send an alert with text "Tile is Loaded!".
Hope this helps.

How to listen different click events in map using javascript?

How to listen for different click events in mapbox using JavaScript? The following is the code for displaying a map using map box.
Can someone suggest how to listen to click events that differentiates land from water bodies?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Display a map on a webpage</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZGphZWJvIiwiYSI6ImNrbzJoYjhodTAxeDUyb211eTF2anZ0bmQifQ.62m9LNQhEPZNCwqxEW9pPQ';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v11', // style URL
center: [-74.5, 40], // starting position [lng, lat]
zoom: 9 // starting zoom
});
</script>
</body>
</html>
I'm being able to listen to click events using the following code:
map.on('click', (e) => {
console.log(e.lngLat)
})
But is there a way to differentiate coordinates land from water bodies?
if you try this:
map.on('load', function () {
let style = map.getStyle();
})
then you can see all the details about the style such as sources, layers, glyphs and etc .
Also for listening to click events on different layers, you can just use:
map.on('click', 'land', function (e) {
// some code
});
or you can query the rendered features within multiple layers by code below:
map.on('click', function (e) {
let featureSelected = map.queryRenderedFeatures(e.point, {layers: ['land', 'water']
});
});

Javascript event handlers using Leaflet UTFGrid

I have a feeling this is an obvious question, but it's stumping me and I'm not quite sure how to debug it. Probably just my javascript ignorance.
I'm using the leaflet utfgrid script from here: https://github.com/danzel/Leaflet.utfgrid
I'm mostly just following the example script, and I can't get the event handlers to work. At this point, I've got what I believe to be a very basic script. Here's the code - I'm looking to get the utfGrid.on('click') function to log to the console but it won't. I'd appreciate any help for feedback.
<head>
<meta charset="UTF-8">
<title>Leaflet Test</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.3/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.0.3/dist/leaflet.js"></script>
<script src="http://danzel.github.io/Leaflet.utfgrid/src/leaflet.utfgrid.js"></script>
<style>
#map{ width: auto; height: 800px; }
</style>
</head>
<body>
Map Data Test
<div id ="hover"></div>
<div id="map"></div>
<script>
// load a tile layer
var basemap = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {attribution: 'CartoDB.', maxZoom: 18, minZoom: 2});
var cmamap = L.tileLayer('http://localhost:8080/tiles/{z}/{x}/{y}.png');
var utfGrid = new L.UtfGrid('http://localhost:8080/grid/{z}/{x}/{y}.json');
//event data
utfGrid.on('click', function (e) {
console.log('clicked');
});
//Create our map with just the base TileLayer
var map = L.map('map')
.setView([38, -94], 5)
.addLayer(basemap);
//Set up the base map and interactive stuff
var cmaLayers = L.layerGroup([
cmamap,
utfGrid
]).addTo(map);
</script>
</body>
So this looks like a version issue between the leaflet plugin and leaflet.utfgrid. When I use an old version of leaflet - it works.

Manually setting basemap using ArcGIS API for JavaScript?

Looked over the example can NOT figure out how to set basemap MANUALLY. I don't want a dijit widget, or any other libraries or anything like that. Just want to manually set a basemap to any of the already available types like Topographic, Satellites, Streets, etc.
Following this API reference:
Object: esri/basemaps
The part I can't figure out is marked with question marks. If some could help me out, would really appreciate it.
require([
"esri/basemaps",
"esri/map",
"dojo/domReady!"
], function (esriBasemaps, Map) {
/* ------------------------------------- */
/* Basemap add one of the existing maps. */
/* ------------------------------------- */
esriBasemaps.myBasemap = {
baseMapLayers ???
};
var map = new Map("map", {
basemap: "myBasemap",
center: [-118, 34.5],
zoom: 8
});
});
The code in the esri/basemaps documentation works fine, combined with the create a map sample.
Here's the part you wondered about:
esriBasemaps.myBasemap = {
baseMapLayers: [
{
url: "http://services.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer"
}
],
title: "My Basemap"
};
Here's a full example. Copy and paste the following into the ArcGIS API for JavaScript Sandbox to see how it works.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title>Simple Map</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.13/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
</style>
<script src="http://js.arcgis.com/3.13/"></script>
<script>
var map;
require(["esri/basemaps", "esri/map", "dojo/domReady!"], function(esriBasemaps, Map) {
esriBasemaps.myBasemap = {
baseMapLayers: [
{
url: "http://services.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer"
}
],
title: "My Basemap"
};
map = new Map("map", {
basemap: "myBasemap",
center: [-122.45, 37.75], // longitude, latitude
zoom: 13
});
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>

Editing polygons in leaflet.js and leaflet.snap

I'm using leaflet.snap (http://makinacorpus.github.io/Leaflet.Snap/) which lets me snap points to lines when drawing a polygon - just what I need. BUT I'm having a hard time trying to get set the polygons to be editable.
Here's my code, which uses Leaflet.Snap, and allows drawing but not editing of a polygon. Any help getting the polygons editable is much appreciated.
<!DOCTYPE html>
<html>
<head>
<title>Leaflet Snap Test</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Leaflet -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<style>
.leaflet-editing-icon.marker-snapped {
background-color: yellow;
}
</style>
<link rel="stylesheet" href="http://makinacorpus.github.io/Leaflet.Snap/Leaflet.draw/dist/leaflet.draw.css" />
<script src="http://makinacorpus.github.io/Leaflet.Snap/Leaflet.draw/dist/leaflet.draw.js"></script>
<script src="http://makinacorpus.github.io/Leaflet.Snap/Leaflet.GeometryUtil/dist/leaflet.geometryutil.js"></script>
<script src="http://makinacorpus.github.io/Leaflet.Snap/leaflet.snap.js"></script>
</head>
<body>
<div id="map" class="map" style="height: 500px; width: 800px"></div>
<script>
var theTileLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © 2013 OpenStreetMap contributors',
});
var map = L.map('map').setView([45.4835656, -122.7332588], 12).addLayer(theTileLayer);
var guideLayers = new Array();
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
position: 'topright',
draw: {
polyline: false,
polygon: {
shapeOptions: {
color: '#009900'
}
},
circle: false, // Turns off this drawing tool
rectangle: false,
marker: false
},
edit: {
featureGroup: drawnItems, //REQUIRED!!
remove: true
}
});
map.addControl(drawControl);
// Editing lines works fine on the sample (http://makinacorpus.github.io/Leaflet.Snap/) but not below.
drawControl.setDrawingOptions({
polygon: { guideLayers: guideLayers, snapDistance: 15 },
});
map.on('draw:created', function (e) {
var layer = e.layer;
map.addLayer(layer);
guideLayers.push(layer);
});
</script>
</body>
</html>
It's just you missed to add layer to drawnItems while any drawing is complete. Just replace "map" by "drawnItems" in your code like following and it will work:
map.on('draw:created', function (e) {
var layer = e.layer;
drawnItems.addLayer(layer);
guideLayers.push(layer);
});
Enjoy!

Categories