Leaflet: pan map to new set of coordinates at new zoom-level on user action - leaflet

I have a web app with a list of GPS-check-ins from field agents.
I would like to pan/zoom the current map/view when a check-in item from the list is clicked.
I have setup the leaflet map and click event like so:
function checkin_clicked(dt, mobile, address, lat, lon) {
console.log(dt, mobile, address, lat, lon);
var html = '<div style="width: 300px;" class="message"><img class="message-avatar" src="media/profile-pics/{mobile}.jpg" alt=""> <a class="message-author" href="#"> {name} </a> <span class="message-date"> {date} </span> <span class="message-content"> {address} </span></div>'
html = html.replace("{address}", address);
html = html.replace("{mobile}", mobile);
html = html.replace("{date}", dt);
html = html.replace("{name}", mobile);
map.setView([lat, lon], 14);
var popup = L.popup()
.setLatLng([lat,lon])
.setContent(html)
.openOn(map);
}
function setup_map() {
var map = L.map('map').setView([8.2, 6.95], 7);
L.tileLayer('http://localhost/tileserver/tiles.aspx?z={z}&x={x}&y={y}', {
minZoom: 7, maxZoom: 18,
}).addTo(map);
}
Please how do I perform this action.
I have seen this: How to change the map center in leaflet and https://stackoverflow.com/a/12735612/44080
But in my case I need to adjust the zoom level while panning.
Edit: I added map.setview in my click event, now i get this error:
"Map container is already initialized"

Related

Embedding an OpenLayers slippy map into Sphinx reStructuredText page

I want to embed a slippy map into my sphinx page.
I'm trying this simple example: https://wiki.openstreetmap.org/wiki/OpenLayers_Marker_Example
So my rst document is:
.. raw:: html
<body>
<div id="mapdiv"></div>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script>
map = new OpenLayers.Map("mapdiv");
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat( -0.1279688 ,51.5077286 )
.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
var zoom=16;
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
map.setCenter (lonLat, zoom);
</script>
</body>
But nothing appears on the page.
I have tried and failed trying to use other javascript mapping api's such as leaflet but with no luck. I'm new to using sphinx/reStructuredText so maybe there's something obivous I am missing?
<body> already exists on your page, so you need to remove it from your rst.
You also need to specify height and width for the mapdiv element, for instance, something like this:
.. raw:: html
<div id="mapdiv" style="height: 200px; width: 100%"></div>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script>
map = new OpenLayers.Map("mapdiv");
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat( -0.1279688 ,51.5077286 )
.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
var zoom=16;
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
map.setCenter (lonLat, zoom);
</script>
#anatoly answer is correct but there was also another step.
I also had a Blocked loading mixed active content error found when checking the developer tools (thanks #giacomo for pointing me towards this), leading to this answer thread: Why am I suddenly getting a "Blocked loading mixed active content" issue in Firefox? which tells me that the cause is http protocol not being secure. The protocol can be removed altogether.
So the final code is:
.. raw:: html
<div id="mapdiv" style="height: 200px; width: 100%"></div>
<script src="//openlayers.org/api/OpenLayers.js"></script>
<script>
map = new OpenLayers.Map("mapdiv");
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat( -0.1279688 ,51.5077286 )
.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
var zoom=16;
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
map.setCenter (lonLat, zoom);
</script>

Leaflet Add Marker on click with pop up of lat lng coordinates?

I would like the ability to click on my map and have the following happen:
Add a temporary marker to the map that will display the lat lng coordinates of that marker.
This should help
<script src="https://cdn.jsdelivr.net/npm/leaflet#1.3.4/dist/leaflet-src.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet-extra-markers#1.0.6/src/assets/js/leaflet.extra-markers.min.js"></script>
<body>
...
<div id="carteDiv"> </div>
</body>
<script>
// Map object
var m_Carte = L.map('carteDiv').setView([45.469717, -73.563719], m_Zoom);
// Create click event handler
m_Carte.on('click', onMapClick);
// The function to create marker on click
var onMapClick = function (e) {
var marqueur = L.marker([e.latlng.lat, e.latlng.lng], {
icon : L.ExtraMarkers.icon({
icon : 'fa-number',
prefix : 'fa',
markerColor : red,
number : 0
})
}).addTo(m_Carte).bindPopup(e.latlng.lat + ' ' + e.latlng.lng);
};
</script>

Leaflet map in modal

I have this modal in my index.html:
<div id="myModal" class="modal">
<span class="close1">×</span>
<div id="mapImage1"></div>
<div id="caption"></div>
</div>
The <div id="mapImage1"> is the leaflet map <div>
Then I have the function, which should load the Leaflet map into the modal. The parameter image is the image which I would like to show on the leaflet map.
function modalImage(modal,image,modalDiv,text,close) {
// Get the modal
var modal = document.getElementById(modal);
var img = document.getElementById(image);
var modalDiv = document.getElementById(modalDiv);
console.log(modalDiv);
var captionText = document.getElementById(text);
img.onclick = function () {
modal.style.display = "block";
initLeafletimage(modalDiv,img);
captionText.innerHTML = this.alt;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName(close)[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function () {
modal.style.display = "none";
}
}
The map itself is generated by this code:
function initLeafletimage(map,image){
console.log(image.src)
var imgDimensions={width:300, height:300} //this is the height and width of the image. It hasn't been loaded yet.
var map = L.map(map, {
maxZoom: 24,
minZoom: -24,
crs: L.CRS.Simple
}).setView([imgDimensions.height/2, imgDimensions.width/2], 0);
var imageUrl = image.src;
var imageBounds = [
[imgDimensions.width , 0],
[0, imgDimensions.height]
];
L.imageOverlay(imageUrl, imageBounds).addTo(map);
}
modalImage('myModal','left','mapImage1','caption','close1');
The map is not even showing up in the modal.
What have I missed?
Unfortunately, like #ghybs pointed out, I missed to define the height and width of the map div. That is why no map was present. With this css it works perfectly:
#mapImage1{
height: 100%;
width: 100%;
position: fixed;
}

Leaflet JS + Leaflet.Deflate - Changing default marker icon to custom icon

In my previous post 'Leaflet JS - changing esri shape into marker on certain zoom level
' I was able to resolve an issue which i had with the leaflet JS library and changing the polygon shapes to markers icons when hitting a certain zoom level.
I was advised by 'Ivan Sanchez' to use the 'Leaflet.Deflate' plugin and this works like a charm, so now the various shapes are being transformed into markers after a certain zoomlevel, however now I'm struggling to change the default leaflet marker icon to a custom marker icon, so my question now is:
Is it possible to change the default marker icon to a custom marker icon while using the 'Leaflet.ShapeFile' and 'Leaflet.Deflate' plugin and what would be the best approach to do this?
I wanted to make a JSFiddle, but I don't JSFiddle allows me to attach the zip file contains the shapefiles, so I will post the code I have got so far below here, thanks for your help, advise and support:
<!doctype html>
<html lang="en">
<head>
<meta charset='utf-8' />
<title>v4</title>
<link rel="stylesheet" type="text/css" href="lib/leaflet/leaflet.css" />
<!--[if lte IE 8]> <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.ie.css" /> <![endif]-->
<link rel="stylesheet" type="text/css" href="lib/leaflet/L.Control.Sidebar.css" />
<style>
html { height: 100% }
body { height: 100%; margin: 0; padding: 0; }
#map { height: 100% }
</style>
</head>
<body>
<div id="map"></div>
<script src="lib/jquery/jquery-3.1.1.min.js"></script>
<script src="lib/leaflet/leaflet.js"></script>
<script src="lib/leaflet/catiline.js"></script>
<script src="lib/leaflet/leaflet.shpfile.js"></script>
<script src="lib/leaflet/shp.js"></script>
<script src="lib/leaflet/L.Control.Sidebar.js"></script>
<script src="lib/leaflet/L.Deflate.js"></script>
<script>
// init map
var m = L.map('map').setView([52.472833, 1.749609], 15);
// clicking on the map will hide the sidebar plugin.
m.on('click', function () {
sidebar.hide();
});
// init Deflate plugin
L.Deflate({ minSize: 10 }).addTo(m);
// Init side bar control
var sidebar = L.control.sidebar('sidebar', { closeButton: true, position: 'right' });
m.addControl(sidebar);
// Init esri shape file via leaflet.shapefile, shp.js plugin
var businessProperties = new L.Shapefile('data/businessshapes.zip', { style: propertyStyle, onEachFeature: propertyOnEachFeature }).addTo(m);
// create on-click Feature
function propertyOnEachFeature(feature, layer) {
layer.on( {
mouseover: highlightFeature,
mouseout: resetHighlight,
click: function populate() {
sidebar.toggle();
document.getElementById('pinfoHeader').innerHTML = "<h2>" + feature.properties.Building + " - Detailed Information</h2><br />";
document.getElementById('pTitle').innerHTML = "Name: " + feature.properties.Building
document.getElementById('pDetails').innerHTML = "SHAPE_Leng: " + feature.properties.SHAPE_Leng + "<br/ >SHAPE_Area: " + feature.properties.SHAPE_Area
}, highlightFeature, zoomToFeature
});
}
// style the properties style
function propertyStyle(feature) {
return {
fillColor: getPropertyColor(feature.properties.BusType),
weight: 2,
opacity: 1,
color: 'white',
dashArray: 3,
fillOpacity: 0.7
}
}
// set color per property according to the data table of the Esri Shape file.
function getPropertyColor(propStatus) {
if (propStatus == 'TypeA') {
return 'red';
} else if (propStatus == 'TypeB') {
return 'green';
} else {
return 'yellow';
}
}
// set the highlighted color for polygon
function highlightFeature(e) {
var layer = e.target;
layer.setStyle( {
weight: 2,
color: 'black',
fillColor: 'white',
fillOpacity: 0.2
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
}
// reset the highlighted color for polygon after mouse leave polygon
function resetHighlight(e) {
businessProperties.resetStyle(e.target);
}
//Extend the Default marker class to overwrite the leaflet.deflate marker icon???
var TestIcon = L.Icon.Default.extend({
options: {
iconUrl: 'assets/images/markers/business.png'
}
});
var testIcon = new TestIcon();
businessProperties.addTo(m);
// Init base maps for switch
var grayscale = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', { id: 'MapID', attribution: 'Map maintained by Demo LTD, — Map data © OpenStreetMap,' }).addTo(m);
var streets = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { id: 'MapID', attribution: 'Map maintained by Demo LTD, — Map data © OpenStreetMap,' });
var baseMaps = {
"Streets": streets,
"Grayscale": grayscale
};
// Init overlay map switch
var overlayMaps = {
"Bussines Properties": businessProperties
};
// Add switches to map control
L.control.layers(baseMaps, overlayMaps).addTo(m);
</script>
</body>
</html>
Is it possible to change the default marker icon to a custom marker icon while using the 'Leaflet.Deflate' plugin?
The answer is: No.
The current code for Leaflet.Deflate uses a default marker and a default marker only, see https://github.com/oliverroick/Leaflet.Deflate/blob/991f51ca82e7bb14a17c8d769b4c378c4ebaf700/src/L.Deflate.js#L42
You could hack your way around it, but I would rather recommend filing a feature request in the Leaflet.Deflate repo. It should be possible to modify the Leaflet.Deflate repo to allow line/polygon features to have some extra properties to be used as marker options.

how to draw a line (between pushpins) exactly over the railroad in bing map

Here is my map of between points based on latitude & longitude.
if you observe the line and rail road carefully you see, the railroad is not straight line but the line i draw between pushpins are straight. But i need my drawing lines should be over the rail road. i am not sure whether it's possible or not. if possible please advice.
And here is my html code.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<title>Crossing Map</title>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map = null;
var pinLayer = new Microsoft.Maps.EntityCollection();
var infoboxLayer = new Microsoft.Maps.EntityCollection();
function GetMap() {
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),{
credentials:"API Key"
});
// Create the info box for the pushpin
pinInfobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
infoboxLayer.push(pinInfobox);
//created variables(one variable per location)
var loc1 = new Microsoft.Maps.Location(29.775560, -95.348878);
// Add a pin to the map
var pin1 = new Microsoft.Maps.Pushpin(loc1);
pin1.Title = "Brooks St";
pin1.Description = "First PIn Descriptoin is here.";
pinLayer.push(pin1); //add pushpin to pinLayer
Microsoft.Maps.Events.addHandler(pin1, 'click', displayInfobox);
var loc2 = new Microsoft.Maps.Location(29.776584, -95.348878);
// Add a pin to the map
var pin2 = new Microsoft.Maps.Pushpin(loc2);
pin2.Title = "Harrington St";
pin2.Description = "Second pin description";
pinLayer.push(pin2); //add pushpin to pinLayer
Microsoft.Maps.Events.addHandler(pin2, 'click', displayInfobox);
var loc3 = new Microsoft.Maps.Location(29.778530, -95.348663);
// Add a pin to the map
var pin3 = new Microsoft.Maps.Pushpin(loc3);
pin3.Title = "Loraine St";
pin3.Description = "Third pin desc";
pinLayer.push(pin3); //add pushpin to pinLayer
Microsoft.Maps.Events.addHandler(pin3, 'click', displayInfobox);
var loc4 = new Microsoft.Maps.Location(29.783419, -95.348963);
// Add a pin to the map
var pin4 = new Microsoft.Maps.Pushpin(loc4);
pin4.Title = "Quitman St";
pin4.Description = "pin 4 desc";
pinLayer.push(pin4); //add pushpin to pinLayer
Microsoft.Maps.Events.addHandler(pin4, 'click', displayInfobox);
var loc5 = new Microsoft.Maps.Location(29.802104, -95.342655);
// Add a pin to the map
var pin5 = new Microsoft.Maps.Pushpin(loc5);
pin5.Title = "Calvalcade";
pin5.Description = "5th pin desc";
pinLayer.push(pin5); //add pushpin to pinLayer
Microsoft.Maps.Events.addHandler(pin5, 'click', displayInfobox);
// Create a polyline
var lineVertices = new Array(loc1,loc2,loc3,loc4,loc5); //var lineVertices = new Array(loc1, loc2, loc3);
var line = new Microsoft.Maps.Polyline(lineVertices);
//map.setView({center:loc2, zoom: 9} );
map.setView({center:loc2, zoom: 15} );
map.entities.push(line);
map.entities.push(pinLayer);
map.entities.push(infoboxLayer);
}
function displayInfobox(e) {
pinInfobox.setOptions({
title: e.target.Title,
description: e.target.Description,
visible:true,
offset: new Microsoft.Maps.Point(0,25)
});
pinInfobox.setLocation(e.target.getLocation());
}
function hideInfobox(e) {
pinInfobox.setOptions({ visible: false });
}
</script>
</head>
<body onload="GetMap();">
<div class="wapper">
<div class="contentareaNoM safetybg">
<div id="core">
<div id='mapDiv' style="positio:relative; margin-left:100px; width:800px; height:800px;"></div>
</div>
</div>
</div>
</body>
</html>
You need to have the polyline (with coordinates) that corresponds to your railroad then you will be able to draw onto those elements. In this way, you will be able to have every point of the railway.
You can take a look at OpenStreetMap that include those element with precise geometry information where the coverage is good.