Generate PDF from HTML with Map (exactly a screenshot) - javascript

Hi I have this html with some content and a map, using Leaflet api for map rendering (jsfiddle) This whole content is part of a modal panel which open on a button click after user input some data. I want to export all content into a pdf with some client side solution.
I have tried jspdf like but it does not works. tried combination of canvastohtml and jspdf like but could not able to make it work either. Point to mentione here is my content contains map which export jspdf doesn't support
Anyone knows a solution, please share. I have included the code below
PS: Using phamtomjs screenshot utilities is not an option
<script src="https://npmcdn.com/leaflet#1.0.0-rc.3/dist/leaflet.js"></script>
<link href="https://npmcdn.com/leaflet#1.0.0-rc.3/dist/leaflet.css" rel="stylesheet" />
<body>
<script>
function createMap(mapPlaceHolderId) {
var OSM_MAP_TILE_SERVER_URL = 'http://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png';
var DEFAULT_MAP_CENTER = L.latLng(25.296854389343867, 51.48811340332031);
var DEFAULT_MAP_ZOOM = 12;
var MAP_ZOOM_MAX = 19;
var MAP_ZOOM_SEARCH = 17;
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib = 'Map data © OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {
minZoom: 8,
maxZoom: 12,
attribution: osmAttrib
});
var map = L.map(mapPlaceHolderId).setView([51.505, -0.09], 13);
map.addLayer(osm);
return map;
}
</script>
<div id="vrSubReportContainer">
<div class="mapPopupTableContainer">
<div class="mapPopupTableData"><b>Plate Number:</b> 009-001GL-297286, <b>Driver Name:</b> Unknown driver
<br><b>Latitude,Longitude</b>: 25.215238,51.605439</div>
</div>
<div id="mapContainer" class="map-container">
<div class="map" id="fd_map_canvas"></div>
</div>
</div>
<script>
(function() {
createMap('fd_map_canvas');
})();
</script>
</body>

Related

How to make Leaflet Search actually search

Implementing the Leaflet Search example just produces a search box. Nothing happens when you open it and start typing. The leaflet search code isn't being executed. It just shows the red Location not found. The graph shows area's of interest and I need to do something with the area's that match search criteria, to identify them to the user.
var searchLayer = L.layerGroup().addTo(map);
//... adding data in searchLayer ...
map.addControl( new L.Control.Search({layer: searchLayer}) );
//searchLayer is a L.LayerGroup contains searched markers
There is code in the control to search to the data. It takes into account a geoJson data structure.
What am I missing in order to activate the search code?
Although not explicitly explained in Leaflet Control Search README, the plugin will use the data in marker.options.title or in feature.properties.title by default.
You can specify a different key than title using the propertyName option when instantiating the Search Control:
var map = L.map('map').setView([41.8990, 12.4977], 14);
var poiLayers = L.geoJSON(restaurant, {
onEachFeature: function(feature, layer) {
layer.bindPopup(feature.properties.amenity + '<br><b>' + feature.properties.name + '</b>');
}
});
L.control.search({
layer: poiLayers,
initial: false,
propertyName: 'name' // Specify which property is searched into.
})
.addTo(map);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet-src.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet-search#2.3.7/dist/leaflet-search.src.css" />
<script src="https://unpkg.com/leaflet-search#2.3.7/dist/leaflet-search.src.js"></script>
<script src="http://labs.easyblog.it/maps/leaflet-search/examples/data/restaurant.geojson.js"></script>
<div id="map" style="height: 200px"></div>

How to apply leaflet marker cluster using layers

I´m trying to apply the Leaflet.MarkerCluster.LayerSupport. But I don´t know how to use it :( I´ve already read the documentation about but and I tried many times but it doesen´t work.
This is my code
<!DOCTYPE html>
<html>
<head>
<title>Península</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src='https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v0.4.0/leaflet.markercluster.js'></script>
<script src="leaflet.markercluster.layersupport-src.js"></script>
<script>
var NemachIcons =L.Icon.extend({
options:{
shadowUrl:'',
iconSize: [50,55],
iconAnchor: [45,45],
popupAnchor:[-3,-76]
}
});
var tiloIcon = new NemachIcons({iconUrl:'http://www.iconshock.com/img_jpg/SIGMA/general/jpg/256/pyramid_icon.jpg'}),
puebloIcon = new NemachIcons({iconUrl:'http://icons.iconseeker.com/png/fullsize/gant/pointless-bw-circle-i-use-it-iex.png'}),
gasIcon =new NemachIcons({iconUrl:'https://cdn2.iconfinder.com/data/icons/function_icon_set/circle_green.png'});
L.icon =function (options) {
return new L.Icon(options);
};
var sitios = new L. LayerGroup();
L.marker([20.683, -88.568], {icon: tiloIcon}).bindPopup('1').addTo(sitios),
L.marker([21.204547, -89.269466], {icon: tiloIcon}).bindPopup('2').addTo(sitios),
L.marker([20.332362, -89.647899], {icon: tiloIcon}).bindPopup('3').addTo(sitios),
L.marker([20.486417, -88.660218], {icon: tiloIcon}).bindPopup('4').addTo(sitios),
L.marker([21.151196, -87.958143], {icon: tiloIcon}).bindPopup('5').addTo(sitios);
var pueblo = new L.LayerGroup();
L.marker([20.9330, -89.0178], {icon: puebloIcon}).bindPopup('6').addTo(pueblo),
L.marker([20.6909, -88.2015], {icon: puebloIcon}).bindPopup('7').addTo(pueblo);
var gas = new L.LayerGroup();
L.marker([20.973907, -89.578931], {icon: gasIcon}).bindPopup('8').addTo(gas);
var mbAttr = ' ' +
'' +
'',
mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw';
var grayscale = L.tileLayer(mbUrl, {id: 'mapbox.light', attribution: mbAttr}),
streets = L.tileLayer(mbUrl, {id: 'mapbox.streets', attribution: mbAttr});
var map = L.map('map', {
center: [20.794527, -88.760612],
zoom: 8,
layers: [grayscale, sitios]
});
var baseLayers = {
//"Grayscale": grayscale,
//"Streets": streets
};
var overlays = {
"Pirámide": sitios,
"Poblado": pueblo,
"Servicio": gas
};
L.control.layers(baseLayers, overlays).addTo(map);
</script>
</body>
</html>
I´ll appreciate all your answers
Like for Leaflet.markercluster, you have to create a Marker Cluster Group where your sub-groups will go into.
In the case of Layer Support, you create a Marker Cluster Group with Layer Support instead:
var mcg = L.markerClusterGroup.layerSupport().addTo(map);
Then you "check in" the sub-groups, so that they know they have to go into that clustering group rather than directly to the map, when they are selected through the Layers Control:
mcg.checkIn([
sitios,
pueblo,
gas
]);
Demo: http://plnkr.co/edit/CT3E63AKWze34FqUoiHn?p=preview
Note: you should download the JavaScript file leaflet.markercluster.layersupport-src.js, if not already done, and place it next to your HTML page, so that it can refer to it locally.
Note 2: if your usage requires only compatibility of clustering with L.Control.Layers, you might be interested in this more simple plugin: Leaflet.FeatureGroup.SubGroup.
Disclaimer: I am the author of these plugins.

Displaying PostGIS Data with Leafletjs

I'm learning GIS with PostGIS and I wanted to try something funny so I downloaded shape files from OSM, imported in PostGres with PostGIS extension and now I want to represent data from PostGIS visually. I have Pulled data with Query
SELECT ST_AsGeoJSON(geom) FROM "dar-es-salaam_tanzania.land_coast;
I got bunch of GeoJSON and wanted to show them to user. Unfortunately it does not show it. I use Yii2 to write codes that pulls the data. Here is the controller code:
public function actionIndex()
{
$cmd = Yii::$app->db->createCommand('SELECT ST_AsGeoJSON(geom) FROM "dar-es-salaam_tanzania.land_coast";');
$gjsons = [];
foreach($cmd->queryAll() as $row)
{
$gjsons[] = json_decode($row['st_asgeojson']);
}
return $this->render('index', ['geojson'=>json_encode($gjsons)]);
}
and in view
<?php
/* #var $this yii\web\View */
$this->title = 'Map Application';
$this->registerJs("
var map = L.map('map').setView([6.8000, 39.2833], 13);
L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'examples.map-20v6611k'
}).addTo(map);
var geojsonList = $geojson;
L.geoJson(geojsonList).addTo(map);
");
?>
<div id="map">
</div>
Is there something that am missing? I'm new to leaflet library and am following their tutorials on their site
UPDATE
Here is the HTML Output (stripped Geojson to fit SO) here is full source
Note that I set Height of the map and I can see a grey box with (+) and (-) signs on it but no map is shown.
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Map Application</title>
<link href="/tech/maps-app/web/assets/7edc4543/css/bootstrap.css" rel="stylesheet">
<link href="/tech/maps-app/web/css/site.css" rel="stylesheet">
<link href="/tech/maps-app/web/css/map.css" rel="stylesheet">
<link href="/tech/maps-app/web/leafletjs/leaflet.css" rel="stylesheet"></head>
<body>
<div class="wrap">
<div id="map">
</div>
</div>
</script><script src="/tech/maps-app/web/assets/c29e8e0a/jquery.js"></script>
<script src="/tech/maps-app/web/assets/f3e1524/yii.js"></script>
<script src="/tech/maps-app/web/leafletjs/leaflet.js"></script>
<script src="/tech/maps-app/web/assets/7edc4543/js/bootstrap.js"></script>
<script type="text/javascript">
jQuery(document).ready(function () {
var map = L.map('map').setView([6.8000, 39.2833], 13);
L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'examples.map-20v6611k'
}).addTo(map);
var geojsonList = [{"type":"MultiPolygon","coordinates":[[[[39.094989013528,-7.2022471828125],[38.638288027056,-7.2022471828125],[38.638288027056,-6.638130390625],[39.094989013528,-6.638130390625],[39.094989013528,-7.2022471828125]]]]}];
L.geoJson(geojsonList).addTo(map);
});
</script>
</body>
</html>
You didn't set height container. Set in your css file:
#map {
height: 400px;
}
And set zoom. Like that:
L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', {zoom: 10, ...

OpenWeatherMap - map is showing only moscow

I am trying to get the weather information for a certian cities(cities are coming dynamically) and i came across this map api which is very easy to integrate. but once i tried it, it is showing only moscow even if i gave the lat and lon of another city, say, munich.
this is the code:
<html>
<head>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script src="http://openweathermap.org/js/OWM.OpenLayers.1.3.4.js" ></script>
</head>
<body onload="init()">
<div id="basicMap"></div>
</body>
<script type="text/javascript">
function init() {
//Center of map
var lat = 48.24806; // <--- some dynamic location
var lon = 11.90166; //<--- some dynamic location
var lonlat = new OpenLayers.LonLat(lon, lat);
var map = new OpenLayers.Map("basicMap");
// Create overlays
// OSM
var mapnik = new OpenLayers.Layer.OSM();
// Stations
var stations = new OpenLayers.Layer.Vector.OWMStations("Stations");
// Current weather
var city = new OpenLayers.Layer.Vector.OWMWeather("Weather");
//Addind maps
map.addLayers([mapnik, stations, city]);
map.setCenter( lonlat, 10 );
}
</script>
</html>
i just want to save some loading energy for my server and do this weather issue in frontend with js. if this would work, it would be wonderful, please help if you can. why am i stuck to moscow here even if give different lat and lons. this is the link for api:
http://openweathermap.org/tutorial/openlayers
Apparently you need to set the Projection for it to work correctly.
Here is an example of the code centering at London:
<html>
<head>
<script src="http://openweathermap.org/js/OWM.OpenLayers.1.3.4.js" ></script>
</head>
<body onload="init()">
<div id="basicMap"></div>
</body>
<script type="text/javascript">
function init() {
//Center of map
var lat = 51.5112139; // <--- some dynamic location
var lon = -0.1198244; //<--- some dynamic location
var map = new OpenLayers.Map("basicMap");
var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(lon, lat).transform( fromProjection, toProjection);
// Create overlays
// OSM
var mapnik = new OpenLayers.Layer.OSM();
// Stations
var stations = new OpenLayers.Layer.Vector.OWMStations("Stations");
// Current weather
var city = new OpenLayers.Layer.Vector.OWMWeather("Weather");
//Addind maps
map.addLayers([mapnik, stations, city]);
map.setCenter( position, 5 );
}
</script>
</html>
To get the Longitude and Latitude of your place, you can use this URL:
http://www.mapcoordinates.net/en
Hope this helps

Unable to bind to click event on Leaflet popup

I'm using Leaflet to draw a map, within the popups I've added a link that should lead to a more detailed description, the description is separated from map and arranged into list using an accordion, so every description is hidden.
I can use an anchor to link to the accordion content, but I need to execute some JavaScript onclick so I am trying to add a click event handler - its not working.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Leaflet Quick Start Guide Example</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--<script src="http://leaflet.cloudmade.com/dist/leaflet.js"></script>-->
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="http://code.leafletjs.com/leaflet-0.3.1/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="http://code.leafletjs.com/leaflet-0.3.1/leaflet.ie.css" /><![endif]-->
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<div id="log"></div>
<div id="map_box_text" class="status_half">
<br>
<br>
<p>List made using JQuery UI accordion, every element is hidden, only on hover it opens, you can click on it to display on map, reverse cliking on map should aopen accordion list description (this), it's currently done using permalinks because I cannot catch click event on a or span tag.
<div class="accordion">
<h4> Ioff :: **** ***</h4>
<div>Detailed data</div>
<br>
<br>
<h4>Us sb :: **** *** </h4>
<div>Detailed data</div>
<br>
<br>
<h4>Ioff :: **** ***</h4>
<div>Detailed data</div>
<br>
<br>
<h4>Us sb :: **** *** </h4>
<div>Detailed data</div>
</div>
</div>
<script src="http://leaflet.cloudmade.com/dist/leaflet.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var map = new L.Map('map', {
center: new L.LatLng(51.641485,-0.15362),
zoom: 13
});
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/a0ead8ee56bd415896e0c7f7d22e8b6e/997/256/{z}/{x}/{y}.png',
cloudmadeAttrib = 'Map data © 2011 OpenStreetMap contributors',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttrib});
map.addLayer(cloudmade);
var point = {};
point["point_111_11"] = new L.Marker(new L.LatLng(51.4800166666667,-0.43673)).bindPopup("Ioff <br>**** ***");
point["point_222_22"] = new L.Marker(new L.LatLng(51.6616333333333,-0.0528583333333333)).bindPopup("Us sb <br>**** ***");
point["point_333_33"] = new L.Marker(new L.LatLng(52.3910783333333,-0.696951666666667)).bindPopup("Ioff <br>**** ***");
point["point_555_44"] = new L.Marker(new L.LatLng(51.641485,-0.15362)).bindPopup("Us sb <br>**** ***");
var points_layer = new L.LayerGroup();
points_layer.addLayer(point["point_111_11"]);
points_layer.addLayer(point["point_222_22"]);
points_layer.addLayer(point["point_333_33"]);
points_layer.addLayer(point["point_555_44"]);
map.addLayer(points_layer);
$('.pointpopup').click(function(){
var pointname = this.id;
map.setView(point[pointname].getLatLng(),15);
point[pointname].openPopup();
});
});
$(window).load(function(){
$("body").click(function(event) {
//console.log('event target is:' + event.target.nodeName);
$("#log").html("clicked: " + event.target.nodeName);
});
$('.map_popup').live('click',function () {
//$('.map_popup').click(function(){
alert('Try to open Accordion ' + $(this).attr('href'))
//console.log('Try to open Accordion');
})
})
</script>
</body>
</html>
you can check it on JS Fiddle
I've reported this as a bug on github to developer of Leaflet here and here but he close bug replying that it's not a issue and I can use another class - which doesn't work.
Edit:
I've found some on my own too: http://jsfiddle.net/M5Ntr/12/
But there is still a problem, potentially there can be a 500 points, so I would like to have as less code as possible, I've tried to create function but I cannot pass variables :(
this is working
point["point_111_11"] = new L.Marker(new L.LatLng(51.4800166666667,-0.43673)).bindPopup("<b>Ioff</b> <br>**** ***").on('click', function (e) { console.log("clicked (Try to open Accordion): " + e.target) });
but this is preferable (not working):
point["point_111_11"] = new L.Marker(new L.LatLng(51.4800166666667,-0.43673)).bindPopup("<b>Ioff</b> <br>**** ***").on('click', myfunction('point_111_11'));
function myfunction(seclectedId){
//do something with seclectedId
console.log(seclectedId)
}
or even
point["point_111_11"] = new L.Marker(new L.LatLng(51.4800166666667,-0.43673)).bindPopup("<b>Ioff</b> <br>**** ***").myBindFunction('point_111_11')
which will do .on('click') or something similar inside ...
As specified in the ticket you raised you can create DOM elements and pass them to the bindPopup method ... so you can do this :
var domelem = document.createElement('a');
domelem.href = "#point_555_444";
domelem.innerHTML = "Click me";
domelem.onclick = function() {
alert(this.href);
// do whatever else you want to do - open accordion etc
};
point["point_555_44"] = new L.Marker(new L.LatLng(51.641485, -0.15362)).bindPopup(domelem);
You just need to update the onclick function to do what you need it to do ....
Here is the above section of code within your example

Categories

Resources