I'm following these docs, but the code below does not render a marker. Any ideas why?
mapboxgl.accessToken = "pk.eyJ1IjoiZGlsbHBpeGVsIiwiYSI6ImNqM3A1YWV4czAwa3cyd3BmeWR4OTJ4NGEifQ.atNs-3fdoNghDcrdKwtIkA";
var map = new mapboxgl.Map({
container: "map",
center: [-74.50, 40],
zoom: 6,
scrollZoom: false,
style: "mapbox://styles/mapbox/light-v9",
});
map.addControl(new mapboxgl.NavigationControl(), "top-left");
var marker = new mapboxgl.Marker().setLngLat([-74.50, 40]).addTo(map);
#map {
height: 320px;
}
<link href="//api.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.css" rel="stylesheet"/>
<script src="//api.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.js"></script>
<div id="map"></div>
Nevermind. Just found the answer: https://github.com/mapbox/mapbox-gl-js/issues/4384
Also answered here: Mapbox GL - my basic, default marker won´t show up on the map
Related
I want to show/hide Leaflet.heat(https://github.com/Leaflet/Leaflet.heat) layer, and new pane should somehow do this.
But is there any support for panes on Leaflet.heat?
This code does not work.
var heatPane = map.createPane("heat");
var heat = L.heatLayer([], {
radius: 10,
maxZoom: 6,
pane: "heat"
}).addTo(map);
heat.addLatLng([44,7])
heat.addLatLng([44,7])
UPD: I can use heat._heat._canvas.style.display = "none" to hide heat layer, but I don't think it is a good practice.
Thanks.
Is seems current release version of leaflet-heat.js does not support using pane option. You can use beta/development version if you want and you can achieve your requirements by just setting style on the pane.
Check out the code below:
document.onreadystatechange = function(e){
if(document.readyState != 'complete') return;
var map = L.map('map').setView([44, 7], 12);
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {}).addTo(map);
var heatPane = map.createPane("heat");
var heat = L.heatLayer([[44, 7], [44, 7], [44, 7], [44, 7]], {
radius: 10,
maxZoom: 6,
pane: "heat"
}).addTo(map);
document.getElementById("btnShow").onclick = function(){
heatPane.style.display = 'block';
};
document.getElementById("btnHide").onclick = function(){
heatPane.style.display = 'none';
};
};
#map {
width: 400px;
height: 400px;
}
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v1.3.4/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v1.3.4/leaflet.js"></script>
<!-- <script src="http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script> -->
<script src="http://leaflet.github.io/Leaflet.heat/src/HeatLayer.js"></script>
<script src="http://mourner.github.io/simpleheat/simpleheat.js"></script>
<div>
<button id="btnHide">Hide</button>
<button id="btnShow">Show</button>
</div>
<div id="map"></div>
P.S: You can uncomment the code and use release version of the script but it will not work because current release version of leaflet-heat draws canvas on default map layer.
I'm trying to add a layer from an api on ArcGis:
https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Facility_and_Structure/MapServer/1
In leaflet it is posible with:
L.esri.featureLayer({
url:"https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Facility_and_Structure/MapServer/1",
style: function () {
return { color: "#70ca49", weight: 2 };
}
}).addTo(map);
Is there a way to do this on mapboxgl?
Hi Jorge Monroy - Mapbox GL JS expects the data sources as such. In your case where you're wanting to load building footprints from an ArcGIS REST Service, your best bet is to load them as a geojson.
It looks like you're publishing the services from ArcServer 10.31. In that case, the way that I've loaded ArcGIS REST services is by exposing them through AGOL as explained there. If you have that option, that seems easiest. Otherwise, there are other (work-arounds)[https://gis.stackexchange.com/questions/13029/converting-arcgis-server-json-to-geojson] that I've no experience with.
Using Washington D.C. as an example, if you navigate to: http://opendata.dc.gov/datasets/building-footprints and then click on APIs, you can copy the link to the geojson service.
You can then load into MapboxGL JS through the data property of the geojson source shown there.
You can use leaflet-mapbox-gl.js to integrate leaflet and mapbox. Get token from mapbox and add it to below example to make it work.
References: https://github.com/mapbox/mapbox-gl-leaflet
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.css' rel='stylesheet' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.js'></script>
<script src="https://unpkg.com/mapbox-gl-leaflet/leaflet-mapbox-gl.js"></script>
<script src="https://unpkg.com/esri-leaflet/dist/esri-leaflet.js"></script>
<style>
html, body, #map {
margin:0; padding:0; width : 100%; height : 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var token = "";//add token before running this example
const INITIAL_VIEW_STATE = {
latitude: 45.528,
longitude: -122.680,
zoom: 13
};
var map = L.map('map').setView([45.528, -122.680], 13);
L.esri.basemapLayer("NationalGeographic").addTo(map);
var parks = L.esri.featureLayer({
url: "https://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Portland_Parks/FeatureServer/0",
style: function () {
return { color: "#70ca49", weight: 2 };
}
}).addTo(map);
var gl = L.mapboxGL({
accessToken: token,
style: 'mapbox://styles/mapbox/dark-v10'
}).addTo(map);
//To add anything on mapbox, first access the mapbox using getMapboxMap()
gl.getMapboxMap().on('load', () => {
//To load any layer on mapbox
//gl.getMapboxMap().addLayer();
});
var popupTemplate = "<h3>{NAME}</h3>{ACRES} Acres<br><small>Property ID: {PROPERTYID}<small>";
parks.bindPopup(function(e){
return L.Util.template(popupTemplate, e.feature.properties)
});
</script>
</body>
</html>
I'm using Mapbox GL JS version 0.32. Is there a way to export the map to a high-res PNG or PDF?
Obviously, I can just screenshot, but it would be nice if there was a more formal way.
I found this repo, but it looks old and isn't clear how it works.
I tried using the preserveDrawingBuffer option:
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
minZoom: 4,
maxZoom: 14,
center: [-2.0, 53.3],
preserveDrawingBuffer: true
});
console.log(map.getCanvas().toDataURL());
This outputs a long data URL in the console, but copying and pasting it into a base64 converter just seems to produce an empty image.
UPDATE: This is my new code, in full:
mapboxgl.accessToken = 'pk.eyXXX';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
minZoom: 4,
maxZoom: 14,
center: [-2.0, 53.3],
preserveDrawingBuffer: true
});
var dpi = 300;
Object.defineProperty(window, 'devicePixelRatio', {
get: function() {return dpi / 96}
});
map.on('load', function () {
var content = map.getCanvas().toDataURL();
console.log(content)
});
The output to the console is this: http://pastebin.com/raw/KhyJkJWJ
There are two main questions:
1. How do I get the map canvas as an image?
Actually, you are doing the right thing, but just too early. Give that map some time to load and fetch the image data when the load event is triggered:
map.on('load', () => console.log(map.getCanvas().toDataURL()));
2. How do I get that image in high-res?
By changing window.devicePixelRatio according to your destination dpi, you can trick your browser into generating high-res output. I found that solution in an implementation created by Matthew Petroff, see his code on https://github.com/mpetroff/print-maps.
This is the trick he's using for generating high-res output:
Object.defineProperty(window, 'devicePixelRatio', {
get: function() {return dpi / 96}
});
Source
I created a simple working example for anybody stumbling upon this thread:
(Thanks #Vic for pointing out the preserveDrawingBuffer-option in Mapbox GL JS)
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Display a map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' rel='stylesheet' />
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<style>
#map {
margin: auto;
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<div id='map'></div>
<a id="downloadLink" href="" download="map.png">Download ↓</a>
<div id="image"></div>
<script>
mapboxgl.accessToken = 'your-token-here';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-74.50, 40],
zoom: 9,
preserveDrawingBuffer: true
});
$('#downloadLink').click(function() {
var img = map.getCanvas().toDataURL('image/png')
this.href = img
})
</script>
</body>
</html>
I am trying to use draw plugin from here http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw
and tried using it locally as shown below
<html>
<head>
<title>A Leaflet map!</title>
<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>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.js"></script>
<style>
#map{ height: 100% }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var drawControl = new L.Control.Draw({
draw : {
position : 'topleft',
polygon : true,
polyline : false,
rectangle : true,
circle : false
},
edit : false
});
map.addControl(drawControl);
</script>
</body>
</html>
I am getting the drawing control and map but the polygon draw is not shown up after drawing is completed not sure how to do it
Please help in getting the polygon drawn on the map as shown in this demo
http://leaflet.github.io/Leaflet.draw/docs/examples/full.html
You must create a feature group and add the layers when they are created ...
var drawnItems = L.featureGroup().addTo(map);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
see the source of http://leaflet.github.io/Leaflet.draw/docs/examples/full.html
I am facing issue with leaflet library. When I try to load map, images are loaded more then once. I am using leaflet with angular, grunt and browserify. I suspect it can be because of order of loading libraries and async execution, but I am not sure. There is no js error messages, leaflet just breaks.
This is my grunt file:
var $ = require('jquery');
window.jQuery = $;
//require boostrap.js for bootstrap components
var angular = require('angular');
require('ui.bootstrap');
require('showErrors');
require('leaflet');
require('leaflet-directive');
angular.module('common', [
require('angular-resource')
]);
var requires = [
'ngRoute',
'leaflet-directive',
'common',
'ui.bootstrap',
'ui.bootstrap.showErrors'
];
require('./common');
angular.module('app', requires).config(function($routeProvider) {
customRouteProvider.when('/common', {templateUrl: 'js/common/1.html'});
customRouteProvider.otherwise({redirectTo: '/'});
});
Html code:
<div ng-controller="mapController">
<div id="map" style="height: 440px; border: 1px solid #AAA;"></div>
</div>
mapController:
module.exports = function ($scope, leafletData) {
var map = L.map( 'map', {
center: [20.0, 5.0],
minZoom: 2,
zoom: 2
});
L.tileLayer( 'http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors | Tiles Courtesy of MapQuest <img src="http://developer.mapquest.com/content/osm/mq_logo.png" width="16" height="16">',
subdomains: ['otile1','otile2','otile3','otile4']
}).addTo( map );
}
But when I execute the code leaflet breaks and my map looks like:
I tried also with angular-leaflet-directive with standard and it still breaks. Did anyone face this issue before? Any suggestions?
in your file Html code
test with change style div: height: 80vh;
<div ng-controller="mapController">
<div id="map" style="height: 80vh; border: 1px solid #AAA;"></div>
</div>
And check the initialization the component life cycle:
Angular 6 is ngOnInit.
Ionic is ionViewDidEnter.
The idea is that booklet loading is done after initialization of the component.
This problem often occurs due to resizing of any parent container while the map is already initialized.
This my solution in Angular 12 link
If you are having this issue on Vue3 you need to import the CSS:
<script>
import "leaflet/dist/leaflet.css";